2 #include <linux/delay.h>
3 #include <linux/interrupt.h>
4 #include <linux/rockchip/cru.h>
5 #include <linux/rockchip/grf.h>
6 #include <linux/rockchip/iomap.h>
7 #include "rockchip_hdmiv2.h"
8 #include "rockchip_hdmiv2_hw.h"
10 static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = {
11 /* tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl
12 * opmode: 0:HDMI1.4 1:HDMI2.0
14 * |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode|
15 * fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl|
17 {27000000, 27000000, 0, 8, 0, 0, 0,
19 {27000000, 33750000, 0, 10, 1, 0, 0,
21 {27000000, 40500000, 0, 12, 2, 0, 0,
23 {27000000, 54000000, 0, 16, 3, 0, 0,
25 {59400000, 59400000, 0, 8, 0, 0, 0,
27 {59400000, 74250000, 0, 10, 1, 0, 0,
29 {59400000, 89100000, 0, 12, 2, 0, 0,
31 {59400000, 118800000, 0, 16, 3, 0, 0,
33 {65000000, 65000000, 0, 8, 0, 0, 0,
35 {74250000, 74250000, 0, 8, 0, 0, 0,
37 {74250000, 92812500, 0, 10, 1, 0, 0,
39 {74250000, 111375000, 0, 12, 2, 0, 0,
41 {74250000, 148500000, 0, 16, 3, 0, 0,
43 {83500000, 83500000, 0, 8, 0, 0, 0,
45 {85500000, 85500000, 0, 8, 0, 0, 0,
47 {106500000, 106500000, 0, 8, 0, 0, 0,
49 {108000000, 108000000, 0, 8, 0, 0, 0,
51 {146250000, 146250000, 0, 8, 0, 0, 0,
53 {148500000, 74250000, 0, 8, 0, 0, 0,
55 {148500000, 148500000, 0, 8, 0, 0, 0,
57 {148500000, 185625000, 0, 10, 1, 0, 0,
59 {148500000, 222750000, 0, 12, 2, 0, 0,
61 {148500000, 297000000, 0, 16, 3, 0, 0,
63 {148500000, 297000000, 0, 8, 0, 0, 0,
65 {148500000, 594000000, 0, 8, 0, 3, 1,
67 {297000000, 148500000, 0, 8, 0, 0, 0,
69 {297000000, 297000000, 0, 8, 0, 0, 0,
71 {297000000, 371250000, 0, 10, 1, 3, 1,
73 {297000000, 445500000, 0, 12, 2, 3, 1,
75 {297000000, 594000000, 0, 16, 3, 3, 1,
77 {594000000, 297000000, 0, 8, 0, 0, 0,
79 {594000000, 371250000, 0, 10, 1, 3, 1,
81 {594000000, 445500000, 0, 12, 2, 3, 1,
83 {594000000, 594000000, 0, 16, 3, 3, 1,
85 {594000000, 594000000, 0, 8, 0, 3, 1,
89 static const struct ext_pll_config_tab EXT_PLL_TABLE[] = {
90 {27000000, 27000000, 8, 1, 90, 3, 2,
91 2, 10, 3, 3, 4, 0, 1, 40,
93 {27000000, 33750000, 10, 1, 90, 1, 3,
94 3, 10, 3, 3, 4, 0, 1, 40,
96 {59400000, 59400000, 8, 1, 99, 3, 2,
97 2, 1, 3, 3, 4, 0, 1, 40,
99 {59400000, 74250000, 10, 1, 99, 1, 2,
100 2, 1, 3, 3, 4, 0, 1, 40,
102 {74250000, 74250000, 8, 1, 99, 1, 2,
103 2, 1, 2, 3, 4, 0, 1, 40,
105 {74250000, 92812500, 10, 4, 495, 1, 2,
106 2, 1, 3, 3, 4, 0, 2, 40,
108 {148500000, 148500000, 8, 1, 99, 1, 1,
109 1, 1, 2, 2, 2, 0, 2, 40,
111 {148500000, 185625000, 10, 4, 495, 0, 2,
112 2, 1, 3, 2, 2, 0, 4, 40,
114 {297000000, 297000000, 8, 1, 99, 0, 1,
115 1, 1, 0, 2, 2, 0, 4, 40,
117 {297000000, 371250000, 10, 4, 495, 1, 2,
118 0, 1, 3, 1, 1, 0, 8, 40,
120 {594000000, 297000000, 8, 1, 99, 0, 1,
121 1, 1, 0, 2, 1, 0, 4, 40,
123 {594000000, 371250000, 10, 4, 495, 1, 2,
124 0, 1, 3, 1, 1, 1, 8, 40,
126 {594000000, 594000000, 8, 1, 99, 0, 2,
127 0, 1, 0, 1, 1, 0, 8, 40,
131 /* ddc i2c master reset */
132 static void rockchip_hdmiv2_i2cm_reset(struct hdmi_dev *hdmi_dev)
134 hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ,
135 m_I2CM_SOFTRST, v_I2CM_SOFTRST(0));
136 usleep_range(90, 100);
139 /*set read/write offset,set read/write mode*/
140 static void rockchip_hdmiv2_i2cm_write_request(struct hdmi_dev *hdmi_dev,
143 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
144 hdmi_writel(hdmi_dev, I2CM_DATAO, data);
145 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_WR, v_I2CM_WR(1));
148 static void rockchip_hdmiv2_i2cm_read_request(struct hdmi_dev *hdmi_dev,
151 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
152 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD, v_I2CM_RD(1));
155 static void rockchip_hdmiv2_i2cm_write_data(struct hdmi_dev *hdmi_dev,
162 while (trytime-- > 0) {
163 rockchip_hdmiv2_i2cm_write_request(hdmi_dev, offset, data);
165 usleep_range(900, 1000);
166 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
168 hdmi_writel(hdmi_dev,
169 IH_I2CM_STAT0, interrupt);
171 if (interrupt & (m_SCDC_READREQ |
172 m_I2CM_DONE | m_I2CM_ERROR))
176 if (interrupt & m_I2CM_DONE) {
177 dev_dbg(hdmi_dev->hdmi->dev,
178 "[%s] write offset %02x data %02x success\n",
179 __func__, offset, data);
181 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
182 dev_err(hdmi_dev->hdmi->dev,
183 "[%s] write data error\n", __func__);
184 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
189 static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset)
195 while (trytime-- > 0) {
196 rockchip_hdmiv2_i2cm_read_request(hdmi_dev, offset);
198 usleep_range(900, 1000);
199 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
201 hdmi_writel(hdmi_dev, IH_I2CM_STAT0, interrupt);
203 if (interrupt & (m_SCDC_READREQ |
204 m_I2CM_DONE | m_I2CM_ERROR))
208 if (interrupt & m_I2CM_DONE) {
209 val = hdmi_readl(hdmi_dev, I2CM_DATAI);
211 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
212 pr_err("[%s] read data error\n", __func__);
213 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
219 static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask)
222 hdmi_msk_reg(hdmi_dev, I2CM_INT,
223 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
224 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
225 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
226 v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));
228 hdmi_msk_reg(hdmi_dev, I2CM_INT,
229 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
230 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
231 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
232 v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
236 #define I2C_DIV_FACTOR 1000000
237 static u16 i2c_count(u16 sfrclock, u16 sclmintime)
239 unsigned long tmp_scl_period = 0;
241 if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0)
242 tmp_scl_period = (unsigned long)((sfrclock * sclmintime) +
243 (I2C_DIV_FACTOR - ((sfrclock * sclmintime) %
244 I2C_DIV_FACTOR))) / I2C_DIV_FACTOR;
246 tmp_scl_period = (unsigned long)(sfrclock * sclmintime) /
249 return (u16)(tmp_scl_period);
252 #define EDID_I2C_MIN_SS_SCL_HIGH_TIME 9625
253 #define EDID_I2C_MIN_SS_SCL_LOW_TIME 10000
255 static void rockchip_hdmiv2_i2cm_clk_init(struct hdmi_dev *hdmi_dev)
259 /* Set DDC I2C CLK which divided from DDC_CLK. */
260 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME);
261 hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR,
263 hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_1_ADDR,
264 (value >> 8) & 0xff);
265 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME);
266 hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR,
268 hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_1_ADDR,
269 (value >> 8) & 0xff);
270 hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE,
271 v_I2CM_FAST_STD_MODE(STANDARD_MODE));
274 static int rockchip_hdmiv2_scdc_get_sink_version(struct hdmi_dev *hdmi_dev)
276 return rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SINK_VER);
279 static void rockchip_hdmiv2_scdc_set_source_version(struct hdmi_dev *hdmi_dev,
282 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, version, SCDC_SOURCE_VER);
285 static void rockchip_hdmiv2_scdc_read_request(struct hdmi_dev *hdmi_dev,
288 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
289 m_I2CM_READ_REQ_EN, v_I2CM_READ_REQ_EN(enable));
290 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, enable, SCDC_CONFIG_0);
294 static void rockchip_hdmiv2_scdc_update_read(struct hdmi_dev *hdmi_dev)
296 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
297 m_I2CM_READ_UPDATE, v_I2CM_READ_UPDATE(1));
300 static int rockchip_hdmiv2_scdc_get_scambling_status(struct hdmi_dev *hdmi_dev)
304 val = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SCRAMBLER_STAT);
308 static void rockchip_hdmiv2_scdc_enable_polling(struct hdmi_dev *hdmi_dev,
311 rockchip_hdmiv2_scdc_read_request(hdmi_dev, enable);
312 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
313 m_I2CM_UPRD_VSYNC_EN, v_I2CM_UPRD_VSYNC_EN(enable));
316 static int rockchip_hdmiv2_scdc_get_status_reg0(struct hdmi_dev *hdmi_dev)
318 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
319 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
320 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE0);
323 static int rockchip_hdmiv2_scdc_get_status_reg1(struct hdmi_dev *hdmi_dev)
325 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
326 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
327 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE1);
331 static void rockchip_hdmiv2_scdc_init(struct hdmi_dev *hdmi_dev)
333 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
334 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
335 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
336 /* set scdc i2c addr */
337 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_SCDC_ADDR);
338 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);/*enable interrupt*/
341 static void rockchip_hdmiv2_scdc_set_tmds_rate(struct hdmi_dev *hdmi_dev)
345 mutex_lock(&hdmi_dev->ddc_lock);
346 rockchip_hdmiv2_scdc_init(hdmi_dev);
347 stat = rockchip_hdmiv2_i2cm_read_data(hdmi_dev,
349 if (hdmi_dev->tmdsclk > 340000000)
353 rockchip_hdmiv2_i2cm_write_data(hdmi_dev,
354 stat, SCDC_TMDS_CONFIG);
355 mutex_unlock(&hdmi_dev->ddc_lock);
358 static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev,
361 HDMIDBG("%s enable %d\n", __func__, enable);
363 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
364 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG);
365 /* TMDS software reset request */
366 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
367 m_TMDS_SWRST, v_TMDS_SWRST(0));
368 /* Enable/Disable Scrambling */
369 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
370 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
372 /* Enable/Disable Scrambling */
373 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
374 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
375 /* TMDS software reset request */
376 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
377 m_TMDS_SWRST, v_TMDS_SWRST(0));
378 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
379 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 0, SCDC_TMDS_CONFIG);
384 static const struct ext_pll_config_tab *get_phy_ext_tab(
385 unsigned int pixclock, unsigned int tmdsclk,
392 HDMIDBG("%s pixClock %u tmdsclk %u colorDepth %d\n",
393 __func__, pixclock, tmdsclk, colordepth);
394 for (i = 0; i < ARRAY_SIZE(EXT_PLL_TABLE); i++) {
395 if ((EXT_PLL_TABLE[i].pix_clock == pixclock) &&
396 (EXT_PLL_TABLE[i].tmdsclock == tmdsclk) &&
397 (EXT_PLL_TABLE[i].color_depth == colordepth))
398 return &EXT_PLL_TABLE[i];
403 static const struct phy_mpll_config_tab *get_phy_mpll_tab(
404 unsigned int pixclock, unsigned int tmdsclk,
405 char pixrepet, char colordepth)
411 HDMIDBG("%s pixClock %u tmdsclk %u pixRepet %d colorDepth %d\n",
412 __func__, pixclock, tmdsclk, pixrepet, colordepth);
413 for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
414 if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) &&
415 (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) &&
416 (PHY_MPLL_TABLE[i].pix_repet == pixrepet) &&
417 (PHY_MPLL_TABLE[i].color_depth == colordepth))
418 return &PHY_MPLL_TABLE[i];
423 static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev)
425 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
426 if (hdmi_dev->soctype != HDMI_SOC_RK322X) {
427 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
428 m_PDDQ_SIG | m_TXPWRON_SIG |
429 m_ENHPD_RXSENSE_SIG | m_SVSRET_SIG,
430 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) |
431 v_ENHPD_RXSENSE_SIG(1)) | v_SVSRET_SIG(0);
433 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
434 m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
435 v_TXPWRON_SIG(0) | v_ENHPD_RXSENSE_SIG(0));
436 regmap_write(hdmi_dev->grf_base,
438 RK322X_PLL_PDATA_DEN);
440 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
443 int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev,
444 int reg_addr, int val)
446 int trytime = 2, i = 0, op_status = 0;
448 if (hdmi_dev->phybase) {
449 writel_relaxed(val, hdmi_dev->phybase + (reg_addr) * 0x04);
453 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
454 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff);
455 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff);
456 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE);
460 usleep_range(900, 1000);
461 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
463 hdmi_writel(hdmi_dev,
467 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
471 if (!(op_status & m_I2CMPHY_DONE))
472 dev_err(hdmi_dev->hdmi->dev,
473 "[%s] operation error,trytime=%d\n",
483 int rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev,
486 int trytime = 2, i = 0, op_status = 0;
489 if (hdmi_dev->phybase)
490 return readl_relaxed(hdmi_dev->phybase + (reg_addr) * 0x04);
493 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
494 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00);
495 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00);
496 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ);
500 usleep_range(900, 1000);
501 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
503 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
506 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
510 if (!(op_status & m_I2CMPHY_DONE)) {
511 pr_err("[%s] operation error,trytime=%d\n",
514 val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1);
515 val = (val & 0xff) << 8;
516 val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff);
517 pr_debug("phy_reg0x%02x: 0x%04x",
527 #define PHY_TIMEOUT 10000
529 static int ext_phy_config(struct hdmi_dev *hdmi_dev)
531 int stat = 0, i = 0, temp;
532 const struct ext_pll_config_tab *phy_ext = NULL;
534 if (hdmi_dev->grf_base)
535 regmap_write(hdmi_dev->grf_base,
537 RK322X_PLL_POWER_DOWN |
538 RK322X_PLL_PDATA_DEN);
539 if (hdmi_dev->tmdsclk_ratio_change &&
540 hdmi_dev->hdmi->edid.scdc_present == 1)
541 rockchip_hdmiv2_scdc_set_tmds_rate(hdmi_dev);
543 /* config the required PHY I2C register */
544 phy_ext = get_phy_ext_tab(hdmi_dev->pixelclk,
546 hdmi_dev->colordepth);
548 stat = ((phy_ext->pll_nf >> 1) & EXT_PHY_PLL_FB_BIT8_MASK) |
549 ((phy_ext->vco_div_5 & 1) << 5) |
550 (phy_ext->pll_nd & EXT_PHY_PLL_PRE_DIVIDER_MASK);
551 rockchip_hdmiv2_write_phy(hdmi_dev,
552 EXT_PHY_PLL_PRE_DIVIDER, stat);
553 stat = phy_ext->pll_nf & 0xff;
554 rockchip_hdmiv2_write_phy(hdmi_dev,
555 EXT_PHY_PLL_FB_DIVIDER, stat);
556 stat = (phy_ext->pclk_divider_a & EXT_PHY_PCLK_DIVIDERA_MASK) |
557 ((phy_ext->pclk_divider_b & 3) << 5);
558 rockchip_hdmiv2_write_phy(hdmi_dev,
559 EXT_PHY_PCLK_DIVIDER1, stat);
560 stat = (phy_ext->pclk_divider_d & EXT_PHY_PCLK_DIVIDERD_MASK) |
561 ((phy_ext->pclk_divider_c & 3) << 5);
562 rockchip_hdmiv2_write_phy(hdmi_dev,
563 EXT_PHY_PCLK_DIVIDER2, stat);
564 stat = ((phy_ext->tmsd_divider_c & 3) << 4) |
565 ((phy_ext->tmsd_divider_a & 3) << 2) |
566 (phy_ext->tmsd_divider_b & 3);
567 rockchip_hdmiv2_write_phy(hdmi_dev,
568 EXT_PHY_TMDSCLK_DIVIDER, stat);
569 rockchip_hdmiv2_write_phy(hdmi_dev,
570 EXT_PHY_PPLL_FB_DIVIDER,
573 if (phy_ext->ppll_no == 1) {
574 rockchip_hdmiv2_write_phy(hdmi_dev,
575 EXT_PHY_PPLL_POST_DIVIDER,
577 stat = 0x20 | phy_ext->ppll_nd;
578 rockchip_hdmiv2_write_phy(hdmi_dev,
579 EXT_PHY_PPLL_PRE_DIVIDER,
582 stat = ((phy_ext->ppll_no / 2) - 1) << 4;
583 rockchip_hdmiv2_write_phy(hdmi_dev,
584 EXT_PHY_PPLL_POST_DIVIDER,
586 stat = 0xe0 | phy_ext->ppll_nd;
587 rockchip_hdmiv2_write_phy(hdmi_dev,
588 EXT_PHY_PPLL_PRE_DIVIDER,
592 pr_err("%s no supported phy configuration.\n", __func__);
596 if (hdmi_dev->phy_table) {
597 for (i = 0; i < hdmi_dev->phy_table_size; i++) {
598 temp = hdmi_dev->phy_table[i].maxfreq;
599 if (hdmi_dev->tmdsclk <= temp)
604 if (i != hdmi_dev->phy_table_size) {
605 if (hdmi_dev->phy_table[i].slopeboost) {
606 rockchip_hdmiv2_write_phy(hdmi_dev,
607 EXT_PHY_SIGNAL_CTRL, 0xff);
608 temp = hdmi_dev->phy_table[i].slopeboost - 1;
609 stat = ((temp & 3) << 6) | ((temp & 3) << 4) |
610 ((temp & 3) << 2) | (temp & 3);
611 rockchip_hdmiv2_write_phy(hdmi_dev,
612 EXT_PHY_SLOPEBOOST, stat);
614 rockchip_hdmiv2_write_phy(hdmi_dev,
615 EXT_PHY_SIGNAL_CTRL, 0x0f);
617 stat = ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 4) |
618 ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 2) |
619 (hdmi_dev->phy_table[i].pre_emphasis & 3);
620 rockchip_hdmiv2_write_phy(hdmi_dev,
621 EXT_PHY_PREEMPHASIS, stat);
622 stat = ((hdmi_dev->phy_table[i].clk_level & 0xf) << 4) |
623 (hdmi_dev->phy_table[i].data2_level & 0xf);
624 rockchip_hdmiv2_write_phy(hdmi_dev,
625 EXT_PHY_LEVEL1, stat);
626 stat = ((hdmi_dev->phy_table[i].data1_level & 0xf) << 4) |
627 (hdmi_dev->phy_table[i].data0_level & 0xf);
628 rockchip_hdmiv2_write_phy(hdmi_dev,
629 EXT_PHY_LEVEL2, stat);
631 rockchip_hdmiv2_write_phy(hdmi_dev,
632 EXT_PHY_SIGNAL_CTRL, 0x0f);
634 rockchip_hdmiv2_write_phy(hdmi_dev, 0xf3, 0x22);
636 stat = clk_get_rate(hdmi_dev->pclk_phy) / 100000;
637 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL,
638 ((stat >> 8) & 0xff) | 0x80);
639 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL_DIV_L,
641 if (hdmi_dev->tmdsclk > 340000000)
642 stat = EXT_PHY_AUTO_R100_OHMS;
643 else if (hdmi_dev->tmdsclk > 200000000)
644 stat = EXT_PHY_AUTO_R50_OHMS;
646 stat = EXT_PHY_AUTO_ROPEN_CIRCUIT;
647 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_RESIS_AUTO,
649 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL,
651 if (hdmi_dev->tmdsclk > 200000000)
655 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PLL_BW, stat);
656 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PPLL_BW, 0x27);
657 if (hdmi_dev->grf_base)
658 regmap_write(hdmi_dev->grf_base,
660 RK322X_PLL_POWER_UP);
661 if (hdmi_dev->tmdsclk_ratio_change)
664 usleep_range(900, 1000);
665 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
666 m_TXPWRON_SIG, v_TXPWRON_SIG(1));
668 while (i++ < PHY_TIMEOUT) {
670 temp = EXT_PHY_PPLL_POST_DIVIDER;
671 stat = rockchip_hdmiv2_read_phy(hdmi_dev, temp);
672 if (stat & EXT_PHY_PPLL_LOCK_STATUS_MASK)
674 usleep_range(1000, 2000);
677 if ((stat & EXT_PHY_PPLL_LOCK_STATUS_MASK) == 0) {
678 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
679 dev_err(hdmi_dev->hdmi->dev,
680 "PHY PLL not locked: PCLK_ON=%ld,TMDSCLK_ON=%ld\n",
681 (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
685 if (hdmi_dev->grf_base)
686 regmap_write(hdmi_dev->grf_base,
688 RK322X_PLL_PDATA_EN);
693 static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev)
696 const struct phy_mpll_config_tab *phy_mpll = NULL;
698 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
699 return ext_phy_config(hdmi_dev);
700 } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
701 if (hdmi_dev->pixelclk > 148500000)
702 clk_set_rate(hdmi_dev->pclk_phy, 148500000);
704 clk_set_rate(hdmi_dev->pclk_phy, hdmi_dev->pixelclk);
705 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
706 clk_set_rate(hdmi_dev->pclk_phy, hdmi_dev->pixelclk);
709 hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV,
710 m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0));
711 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
713 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
714 m_PDDQ_SIG | m_TXPWRON_SIG | m_SVSRET_SIG,
715 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | v_SVSRET_SIG(1));
717 if (hdmi_dev->tmdsclk_ratio_change &&
718 hdmi_dev->hdmi->edid.scdc_present == 1)
719 rockchip_hdmiv2_scdc_set_tmds_rate(hdmi_dev);
722 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
723 usleep_range(1000, 2000);
724 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
726 /* Set slave address as PHY GEN2 address */
727 hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
729 /* config the required PHY I2C register */
730 if (hdmi_dev->soctype == HDMI_SOC_RK3366 &&
731 hdmi_dev->pixelclk > 148500000)
732 phy_mpll = get_phy_mpll_tab(148500000,
734 hdmi_dev->pixelrepeat - 1,
735 hdmi_dev->colordepth);
737 phy_mpll = get_phy_mpll_tab(hdmi_dev->pixelclk,
739 hdmi_dev->pixelrepeat - 1,
740 hdmi_dev->colordepth);
742 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG,
743 v_PREP_DIV(phy_mpll->prep_div) |
745 phy_mpll->tmdsmhl_cntrl) |
746 v_OPMODE(phy_mpll->opmode) |
748 phy_mpll->fbdiv2_cntrl) |
750 phy_mpll->fbdiv1_cntrl) |
751 v_REF_CNTRL(phy_mpll->ref_cntrl) |
752 v_MPLL_N_CNTRL(phy_mpll->n_cntrl));
753 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL,
755 phy_mpll->prop_cntrl) |
757 phy_mpll->int_cntrl));
758 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL,
760 phy_mpll->gmp_cntrl));
763 if (hdmi_dev->phy_table) {
764 for (i = 0; i < hdmi_dev->phy_table_size; i++)
765 if (hdmi_dev->tmdsclk <= hdmi_dev->phy_table[i].maxfreq)
768 if (i == hdmi_dev->phy_table_size) {
769 pr_info("%s use default phy settings\n", __func__);
770 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
771 v_OVERRIDE(1) | v_SLOPEBOOST(0) |
772 v_TX_SYMON(1) | v_CLK_SYMON(1) |
774 if (hdmi_dev->tmdsclk > 340000000)
775 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
778 else if (hdmi_dev->tmdsclk > 165000000)
779 rockchip_hdmiv2_write_phy(hdmi_dev,
784 rockchip_hdmiv2_write_phy(hdmi_dev,
789 stat = v_OVERRIDE(1) | v_TX_SYMON(1) | v_CLK_SYMON(1) |
790 v_PREEMPHASIS(hdmi_dev->phy_table[i].pre_emphasis) |
791 v_SLOPEBOOST(hdmi_dev->phy_table[i].slopeboost);
792 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, stat);
794 stat = v_SUP_CLKLVL(hdmi_dev->phy_table[i].clk_level) |
795 v_SUP_TXLVL(hdmi_dev->phy_table[i].data0_level);
796 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL, stat);
799 if (hdmi_dev->tmdsclk > 340000000)
800 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
801 v_TX_TERM(R50_OHMS));
803 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
804 v_TX_TERM(R100_OHMS));
805 /* rockchip_hdmiv2_write_phy(hdmi_dev, 0x05, 0x8000); */
806 if (hdmi_dev->tmdsclk_ratio_change)
809 hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e);
811 /* check if the PHY PLL is locked */
814 while (i++ < PHY_TIMEOUT) {
816 stat = hdmi_readl(hdmi_dev, PHY_STAT0);
817 if (stat & m_PHY_LOCK)
819 usleep_range(1000, 2000);
822 if ((stat & m_PHY_LOCK) == 0) {
823 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
824 dev_err(hdmi_dev->hdmi->dev,
825 "PHY PLL not locked: PCLK_ON=%ld,TMDSCLK_ON=%ld\n",
826 (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
829 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
833 static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
834 struct hdmi_video *vpara)
836 struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
837 int value, vsync_pol, hsync_pol, de_pol;
838 struct hdmi_video_timing *timing = NULL;
839 struct fb_videomode *mode = NULL;
840 u32 sink_version, tmdsclk;
842 vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
843 hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
844 de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
846 hdmi_msk_reg(hdmi_dev, A_VIDPOLCFG,
847 m_DATAEN_POL | m_VSYNC_POL | m_HSYNC_POL,
848 v_DATAEN_POL(de_pol) |
849 v_VSYNC_POL(vsync_pol) |
850 v_HSYNC_POL(hsync_pol));
852 timing = (struct hdmi_video_timing *)hdmi_vic2timing(vpara->vic);
854 dev_err(hdmi_drv->dev,
855 "[%s] not found vic %d\n", __func__, vpara->vic);
858 mode = &timing->mode;
859 if (vpara->color_input == HDMI_COLOR_YCBCR420)
860 tmdsclk = mode->pixclock / 2;
861 else if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
862 tmdsclk = 2 * mode->pixclock;
864 tmdsclk = mode->pixclock;
865 if (vpara->color_output != HDMI_COLOR_YCBCR422) {
866 switch (vpara->color_output_depth) {
868 tmdsclk += tmdsclk / 4;
871 tmdsclk += tmdsclk / 2;
880 } else if (vpara->color_output_depth > 12) {
881 /* YCbCr422 mode only support up to 12bit */
882 vpara->color_output_depth = 12;
884 if ((tmdsclk > 594000000) ||
885 (tmdsclk > 340000000 &&
886 tmdsclk > hdmi_drv->edid.maxtmdsclock)) {
887 pr_warn("out of max tmds clock, limit to 8bit\n");
888 vpara->color_output_depth = 8;
889 if (vpara->color_input == HDMI_COLOR_YCBCR420)
890 tmdsclk = mode->pixclock / 2;
891 else if (vpara->format_3d != HDMI_3D_FRAME_PACKING)
892 tmdsclk = mode->pixclock;
897 if ((tmdsclk > 340000000) ||
898 (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000))
899 hdmi_dev->tmdsclk_ratio_change = true;
901 hdmi_dev->tmdsclk_ratio_change = false;
903 hdmi_dev->tmdsclk = tmdsclk;
904 if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
905 hdmi_dev->pixelclk = 2 * mode->pixclock;
907 hdmi_dev->pixelclk = mode->pixclock;
908 hdmi_dev->pixelrepeat = timing->pixelrepeat;
909 /* hdmi_dev->colordepth is used for find pll config.
910 * For YCbCr422, tmdsclk is same on all color depth.
912 if (vpara->color_output == HDMI_COLOR_YCBCR422)
913 hdmi_dev->colordepth = 8;
915 hdmi_dev->colordepth = vpara->color_output_depth;
916 pr_info("pixel clk is %lu tmds clk is %u\n",
917 hdmi_dev->pixelclk, hdmi_dev->tmdsclk);
918 /* Start/stop HDCP keepout window generation */
919 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
920 m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
921 if (hdmi_drv->edid.scdc_present == 1 && !hdmi_drv->uboot) {
922 if (tmdsclk > 340000000 ||
923 hdmi_drv->edid.lte_340mcsc_scramble) {
924 /* used for HDMI 2.0 TX */
925 mutex_lock(&hdmi_dev->ddc_lock);
926 rockchip_hdmiv2_scdc_init(hdmi_dev);
928 rockchip_hdmiv2_scdc_get_sink_version(hdmi_dev);
929 pr_info("sink scdc version is %d\n", sink_version);
930 sink_version = hdmi_drv->edid.hf_vsdb_version;
931 rockchip_hdmiv2_scdc_set_source_version(hdmi_dev,
933 if (hdmi_drv->edid.rr_capable == 1)
934 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
935 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 1);
936 mutex_unlock(&hdmi_dev->ddc_lock);
938 mutex_lock(&hdmi_dev->ddc_lock);
939 rockchip_hdmiv2_scdc_init(hdmi_dev);
940 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 0);
941 mutex_unlock(&hdmi_dev->ddc_lock);
944 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
945 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
948 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
949 m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL |
950 m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
951 v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
952 v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) |
953 v_FC_INTERLACE_MODE(mode->vmode));
954 if ((mode->vmode & FB_VMODE_INTERLACED) &&
955 vpara->format_3d != HDMI_3D_FRAME_PACKING)
956 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
957 m_FC_VBLANK, v_FC_VBLANK(1));
959 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
960 m_FC_VBLANK, v_FC_VBLANK(0));
963 if (vpara->color_input == HDMI_COLOR_YCBCR420)
965 hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8));
966 hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff));
968 if (vpara->format_3d == HDMI_3D_FRAME_PACKING) {
969 if (mode->vmode == 0)
970 value = 2 * mode->yres +
975 value = 2 * mode->yres +
976 3 * (mode->upper_margin +
978 mode->vsync_len) + 2;
982 hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8));
983 hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff));
985 value = mode->hsync_len + mode->left_margin + mode->right_margin;
986 if (vpara->color_input == HDMI_COLOR_YCBCR420)
988 hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(value >> 8));
989 hdmi_writel(hdmi_dev, FC_INHBLANK0, (value & 0xff));
991 value = mode->vsync_len + mode->upper_margin + mode->lower_margin;
992 hdmi_writel(hdmi_dev, FC_INVBLANK, (value & 0xff));
994 value = mode->right_margin;
995 if (vpara->color_input == HDMI_COLOR_YCBCR420)
997 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(value >> 8));
998 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (value & 0xff));
1000 value = mode->lower_margin;
1001 hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (value & 0xff));
1003 value = mode->hsync_len;
1004 if (vpara->color_input == HDMI_COLOR_YCBCR420)
1006 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(value >> 8));
1007 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (value & 0xff));
1009 value = mode->vsync_len;
1010 hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff));
1012 /* Set the control period minimum duration (min. of 12 pixel
1013 * clock cycles, refer to HDMI 1.4b specification)
1015 hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
1016 hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
1018 /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
1019 * worst case: tmdsClock == 25MHz => config <= 19
1021 hdmi_writel(hdmi_dev, FC_EXCTRLSPAC,
1022 (hdmi_dev->tmdsclk / 1000) * 50 / (256 * 512));
1024 hdmi_writel(hdmi_dev, FC_PRCONF,
1025 v_FC_PR_FACTOR(timing->pixelrepeat) |
1026 v_FC_PR_FACTOR_OUT(timing->pixelrepeat - 1));
1031 static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev,
1032 struct hdmi_video *vpara)
1034 unsigned char color_depth = COLOR_DEPTH_24BIT_DEFAULT;
1035 unsigned char output_select = 0;
1036 unsigned char remap_size = 0;
1038 if (vpara->color_output == HDMI_COLOR_YCBCR422) {
1039 switch (vpara->color_output_depth) {
1041 remap_size = YCC422_16BIT;
1044 remap_size = YCC422_20BIT;
1047 remap_size = YCC422_24BIT;
1050 remap_size = YCC422_16BIT;
1054 output_select = OUT_FROM_YCC422_REMAP;
1055 /*Config remap size for the different color Depth*/
1056 hdmi_msk_reg(hdmi_dev, VP_REMAP,
1057 m_YCC422_SIZE, v_YCC422_SIZE(remap_size));
1059 switch (vpara->color_output_depth) {
1061 color_depth = COLOR_DEPTH_30BIT;
1062 output_select = OUT_FROM_PIXEL_PACKING;
1065 color_depth = COLOR_DEPTH_36BIT;
1066 output_select = OUT_FROM_PIXEL_PACKING;
1069 color_depth = COLOR_DEPTH_48BIT;
1070 output_select = OUT_FROM_PIXEL_PACKING;
1074 color_depth = COLOR_DEPTH_24BIT_DEFAULT;
1075 output_select = OUT_FROM_8BIT_BYPASS;
1079 /*Config Color Depth*/
1080 hdmi_msk_reg(hdmi_dev, VP_PR_CD,
1081 m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth));
1082 /*Config pixel repettion*/
1083 hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR,
1084 v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1));
1085 if (hdmi_dev->pixelrepeat > 1)
1086 hdmi_msk_reg(hdmi_dev, VP_CONF,
1087 m_PIXEL_REPET_EN | m_BYPASS_SEL,
1088 v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
1090 hdmi_msk_reg(hdmi_dev, VP_CONF,
1091 m_PIXEL_REPET_EN | m_BYPASS_SEL,
1092 v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));
1094 /*config output select*/
1095 if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */
1096 hdmi_msk_reg(hdmi_dev, VP_CONF,
1097 m_BYPASS_EN | m_PIXEL_PACK_EN |
1098 m_YCC422_EN | m_OUTPUT_SEL,
1099 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) |
1100 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
1101 } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */
1102 hdmi_msk_reg(hdmi_dev, VP_CONF,
1103 m_BYPASS_EN | m_PIXEL_PACK_EN |
1104 m_YCC422_EN | m_OUTPUT_SEL,
1105 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) |
1106 v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
1107 } else if (output_select == OUT_FROM_8BIT_BYPASS ||
1108 output_select == 3) { /* bypass */
1109 hdmi_msk_reg(hdmi_dev, VP_CONF,
1110 m_BYPASS_EN | m_PIXEL_PACK_EN |
1111 m_YCC422_EN | m_OUTPUT_SEL,
1112 v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
1113 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
1116 #if defined(HDMI_VIDEO_STUFFING)
1117 /* YCC422 and pixel packing stuffing*/
1118 hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
1119 hdmi_msk_reg(hdmi_dev, VP_STUFF,
1120 m_YCC422_STUFFING | m_PP_STUFFING,
1121 v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
1126 static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev,
1127 struct hdmi_video *vpara)
1131 if (vpara->color_input == HDMI_COLOR_YCBCR422) {
1132 /* YCC422 mapping is discontinued - only map 1 is supported */
1133 switch (vpara->color_output_depth) {
1135 map_code = VIDEO_YCBCR422_8BIT;
1138 map_code = VIDEO_YCBCR422_10BIT;
1141 map_code = VIDEO_YCBCR422_12BIT;
1144 map_code = VIDEO_YCBCR422_8BIT;
1147 } else if (vpara->color_input == HDMI_COLOR_YCBCR420 ||
1148 vpara->color_input == HDMI_COLOR_YCBCR444) {
1149 switch (vpara->color_output_depth) {
1151 map_code = VIDEO_YCBCR444_10BIT;
1154 map_code = VIDEO_YCBCR444_12BIT;
1157 map_code = VIDEO_YCBCR444_16BIT;
1161 map_code = VIDEO_YCBCR444_8BIT;
1165 switch (vpara->color_output_depth) {
1167 map_code = VIDEO_RGB444_10BIT;
1170 map_code = VIDEO_RGB444_12BIT;
1173 map_code = VIDEO_RGB444_16BIT;
1177 map_code = VIDEO_RGB444_8BIT;
1180 map_code += (vpara->color_input == HDMI_COLOR_YCBCR444) ?
1184 /* Set Data enable signal from external
1185 * and set video sample input mapping
1187 hdmi_msk_reg(hdmi_dev, TX_INVID0,
1188 m_INTERNAL_DE_GEN | m_VIDEO_MAPPING,
1189 v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));
1191 #if defined(HDMI_VIDEO_STUFFING)
1192 hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
1193 hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
1194 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1195 m_GYDATA_STUFF, v_GYDATA_STUFF(1));
1196 hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
1197 hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
1198 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1199 m_RCRDATA_STUFF, v_RCRDATA_STUFF(1));
1200 hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
1201 hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
1202 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1203 m_BCBDATA_STUFF, v_BCBDATA_STUFF(1));
1208 static const char coeff_csc[][24] = {
1210 * A1 | A2 | A3 | A4 |
1211 * B1 | B2 | B3 | B4 |
1212 * C1 | C2 | C3 | C4 |
1214 { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */
1215 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /*G*/
1216 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40, /*R*/
1217 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x00, 0x40, /*B*/
1219 { /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */
1220 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /*G*/
1221 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x01, 0x00, /*R*/
1222 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x01, 0x00, /*B*/
1224 { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
1225 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40, /*Y*/
1226 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00, /*Cr*/
1227 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
1229 { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
1230 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00, /*Y*/
1231 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00, /*Cr*/
1232 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
1234 { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
1235 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40, /*Y*/
1236 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00, /*Cr*/
1237 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
1239 { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
1240 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00, /*Y*/
1241 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00, /*Cr*/
1242 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
1245 { /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */
1246 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, /*G*/
1247 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, /*R*/
1248 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b, /*B*/
1250 { /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */
1251 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, /*G*/
1252 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, /*R*/
1253 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25, /*B*/
1257 static int rockchip_hdmiv2_video_csc(struct hdmi_dev *hdmi_dev,
1258 struct hdmi_video *vpara)
1260 int i, mode, interpolation, decimation, csc_scale;
1261 const char *coeff = NULL;
1262 unsigned char color_depth = 0;
1264 if (vpara->color_input == vpara->color_output) {
1265 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1266 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0));
1270 if (vpara->color_input == HDMI_COLOR_YCBCR422 &&
1271 vpara->color_output != HDMI_COLOR_YCBCR422 &&
1272 vpara->color_output != HDMI_COLOR_YCBCR420) {
1274 hdmi_msk_reg(hdmi_dev, CSC_CFG,
1275 m_CSC_INTPMODE, v_CSC_INTPMODE(interpolation));
1278 if ((vpara->color_input == HDMI_COLOR_RGB_0_255 ||
1279 vpara->color_input == HDMI_COLOR_YCBCR444) &&
1280 vpara->color_output == HDMI_COLOR_YCBCR422) {
1282 hdmi_msk_reg(hdmi_dev, CSC_CFG,
1283 m_CSC_DECIMODE, v_CSC_DECIMODE(decimation));
1286 switch (vpara->vic) {
1287 case HDMI_720X480I_60HZ_4_3:
1288 case HDMI_720X576I_50HZ_4_3:
1289 case HDMI_720X480P_60HZ_4_3:
1290 case HDMI_720X576P_50HZ_4_3:
1291 case HDMI_720X480I_60HZ_16_9:
1292 case HDMI_720X576I_50HZ_16_9:
1293 case HDMI_720X480P_60HZ_16_9:
1294 case HDMI_720X576P_50HZ_16_9:
1295 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
1296 vpara->color_output >= HDMI_COLOR_YCBCR444) {
1297 mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
1299 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
1300 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1301 mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
1306 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
1307 vpara->color_output >= HDMI_COLOR_YCBCR444) {
1308 mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
1310 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
1311 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1312 mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
1318 if ((vpara->color_input == HDMI_COLOR_RGB_0_255) &&
1319 (vpara->color_output == HDMI_COLOR_RGB_16_235)) {
1320 mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
1324 switch (vpara->color_output_depth) {
1326 color_depth = COLOR_DEPTH_30BIT;
1330 color_depth = COLOR_DEPTH_36BIT;
1334 color_depth = COLOR_DEPTH_48BIT;
1339 color_depth = COLOR_DEPTH_24BIT;
1343 coeff = coeff_csc[mode];
1344 for (i = 0; i < 24; i++)
1345 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
1347 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1348 m_CSC_SCALE, v_CSC_SCALE(csc_scale));
1349 /*config CSC_COLOR_DEPTH*/
1350 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1351 m_CSC_COLOR_DEPTH, v_CSC_COLOR_DEPTH(color_depth));
1354 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1355 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1));
1360 static int hdmi_dev_detect_hotplug(struct hdmi *hdmi)
1362 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1365 value = hdmi_readl(hdmi_dev, PHY_STAT0);
1366 HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value);
1367 if (value & m_PHY_HPD)
1368 return HDMI_HPD_ACTIVED;
1370 return HDMI_HPD_REMOVED;
1373 static int hdmi_dev_read_edid(struct hdmi *hdmi, int block, unsigned char *buff)
1375 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1376 int i = 0, n = 0, index = 0, ret = -1, trytime = 5;
1377 int offset = (block % 2) * 0x80;
1380 HDMIDBG("[%s] block %d\n", __func__, block);
1382 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
1384 /* Set DDC I2C CLK which divided from DDC_CLK to 100KHz. */
1385 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
1387 /* Enable I2C interrupt for reading edid */
1388 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);
1390 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
1391 hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
1392 hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
1393 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
1394 for (trytime = 0; trytime < 5; trytime++) {
1395 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
1396 /* enable extend sequential read operation */
1398 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1399 m_I2CM_RD8, v_I2CM_RD8(1));
1401 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1407 usleep_range(900, 1000);
1408 interrupt = hdmi_readl(hdmi_dev,
1411 hdmi_writel(hdmi_dev,
1412 IH_I2CM_STAT0, interrupt);
1415 (m_SCDC_READREQ | m_I2CM_DONE |
1420 if (interrupt & m_I2CM_DONE) {
1421 for (index = 0; index < 8; index++)
1422 buff[8 * n + index] =
1423 hdmi_readl(hdmi_dev,
1427 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
1432 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
1434 "[%s] edid read %d error\n",
1435 __func__, offset + 8 * n);
1440 "[%s] edid read error\n", __func__);
1446 /* Disable I2C interrupt */
1447 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
1451 static void hdmi_dev_config_avi(struct hdmi_dev *hdmi_dev,
1452 struct hdmi_video *vpara)
1454 unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0;
1455 unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT;
1457 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(0));
1458 hdmi_msk_reg(hdmi_dev, IH_FC_STAT1,
1459 m_AVI_INFOFRAME, v_AVI_INFOFRAME(1));
1460 /* Set AVI infoFrame Data byte1 */
1461 if (vpara->color_output == HDMI_COLOR_YCBCR444)
1462 y1y0 = AVI_COLOR_MODE_YCBCR444;
1463 else if (vpara->color_output == HDMI_COLOR_YCBCR422)
1464 y1y0 = AVI_COLOR_MODE_YCBCR422;
1465 else if (vpara->color_output == HDMI_COLOR_YCBCR420)
1466 y1y0 = AVI_COLOR_MODE_YCBCR420;
1468 y1y0 = AVI_COLOR_MODE_RGB;
1470 hdmi_msk_reg(hdmi_dev, FC_AVICONF0,
1471 m_FC_ACTIV_FORMAT | m_FC_RGC_YCC,
1472 v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1));
1474 /* Set AVI infoFrame Data byte2 */
1475 switch (vpara->vic) {
1476 case HDMI_720X480I_60HZ_4_3:
1477 case HDMI_720X576I_50HZ_4_3:
1478 case HDMI_720X480P_60HZ_4_3:
1479 case HDMI_720X576P_50HZ_4_3:
1480 aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
1481 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1482 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1484 case HDMI_720X480I_60HZ_16_9:
1485 case HDMI_720X576I_50HZ_16_9:
1486 case HDMI_720X480P_60HZ_16_9:
1487 case HDMI_720X576P_50HZ_16_9:
1488 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1489 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1490 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1493 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1494 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1495 colorimetry = AVI_COLORIMETRY_ITU709;
1498 if (vpara->colorimetry > HDMI_COLORIMETRY_ITU709) {
1499 colorimetry = AVI_COLORIMETRY_EXTENDED;
1500 ext_colorimetry = vpara->colorimetry;
1501 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235 ||
1502 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1503 colorimetry = AVI_COLORIMETRY_NO_DATA;
1504 ext_colorimetry = 0;
1505 } else if (vpara->colorimetry != HDMI_COLORIMETRY_NO_DATA) {
1506 colorimetry = vpara->colorimetry;
1509 hdmi_writel(hdmi_dev, FC_AVICONF1,
1510 v_FC_COLORIMETRY(colorimetry) |
1511 v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
1512 v_FC_ACT_ASPEC_RATIO(ACTIVE_ASPECT_RATE_DEFAULT));
1514 /* Set AVI infoFrame Data byte3 */
1515 hdmi_msk_reg(hdmi_dev, FC_AVICONF2,
1516 m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE,
1517 v_FC_EXT_COLORIMETRY(ext_colorimetry) |
1518 v_FC_QUAN_RANGE(rgb_quan_range));
1520 /* Set AVI infoFrame Data byte4 */
1521 if ((vpara->vic > 92 && vpara->vic < 96) ||
1522 (vpara->vic == 98) ||
1523 (vpara->vic & HDMI_VIDEO_DMT))
1524 hdmi_writel(hdmi_dev, FC_AVIVID, 0);
1526 hdmi_writel(hdmi_dev, FC_AVIVID, vpara->vic & 0xff);
1527 /* Set AVI infoFrame Data byte5 */
1528 hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN,
1529 v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS));
1530 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(1));
1533 static int hdmi_dev_config_vsi(struct hdmi *hdmi,
1534 unsigned char vic_3d, unsigned char format)
1536 int i = 0, id = 0x000c03;
1537 unsigned char data[3] = {0};
1539 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1541 HDMIDBG("[%s] vic %d format %d.\n", __func__, vic_3d, format);
1543 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0));
1544 hdmi_writel(hdmi_dev, FC_VSDIEEEID2, id & 0xff);
1545 hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff);
1546 hdmi_writel(hdmi_dev, FC_VSDIEEEID0, (id >> 16) & 0xff);
1548 data[0] = format << 5; /* PB4 --HDMI_Video_Format */
1550 case HDMI_VIDEO_FORMAT_4KX2K:
1551 data[1] = vic_3d; /* PB5--HDMI_VIC */
1554 case HDMI_VIDEO_FORMAT_3D:
1555 data[1] = vic_3d << 4; /* PB5--3D_Structure field */
1556 data[2] = 0; /* PB6--3D_Ext_Data field */
1564 for (i = 0; i < 3; i++)
1565 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
1566 hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6);
1568 hdmi_writel(hdmi_dev, FC_DATAUTO1, 0);
1569 hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11);
1570 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1));
1574 static int hdmi_dev_config_spd(struct hdmi *hdmi, const char *vendor,
1575 const char *product, char deviceinfo)
1577 struct hdmi_dev *hdmi_dev;
1580 if (!hdmi || !vendor || !product)
1582 hdmi_dev = hdmi->property->priv;
1584 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(0));
1585 len = strlen(vendor);
1586 for (i = 0; i < 8; i++) {
1588 hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i,
1591 hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i,
1594 len = strlen(product);
1595 for (i = 0; i < 16; i++) {
1597 hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i,
1600 hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i,
1603 hdmi_writel(hdmi_dev, FC_SPDDEVICEINF, deviceinfo);
1604 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(1));
1608 static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara)
1610 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1612 HDMIDBG("%s vic %d 3dformat %d color mode %d color depth %d\n",
1613 __func__, vpara->vic, vpara->format_3d,
1614 vpara->color_output, vpara->color_output_depth);
1616 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
1617 vpara->color_input = HDMI_COLOR_RGB_0_255;
1620 /* before configure video, we power off phy */
1621 if (hdmi_dev->soctype != HDMI_SOC_RK322X) {
1622 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1623 m_PDDQ_SIG | m_TXPWRON_SIG,
1624 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1626 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1627 m_ENHPD_RXSENSE_SIG,
1628 v_ENHPD_RXSENSE_SIG(1));
1629 regmap_write(hdmi_dev->grf_base,
1630 RK322X_GRF_SOC_CON2,
1631 RK322X_PLL_POWER_DOWN);
1633 /* force output blue */
1634 if (vpara->color_output == HDMI_COLOR_RGB_0_255) {
1635 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/
1636 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/
1637 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/
1638 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235) {
1639 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x10); /*R*/
1640 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/
1641 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10); /*B*/
1643 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*Cr*/
1644 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*Y*/
1645 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*Cb*/
1647 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1648 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1649 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1652 if (rockchip_hdmiv2_video_framecomposer(hdmi, vpara) < 0)
1655 if (rockchip_hdmiv2_video_packetizer(hdmi_dev, vpara) < 0)
1657 /* Color space convert */
1658 if (rockchip_hdmiv2_video_csc(hdmi_dev, vpara) < 0)
1660 if (rockchip_hdmiv2_video_sampler(hdmi_dev, vpara) < 0)
1663 if (vpara->sink_hdmi == OUTPUT_HDMI) {
1664 hdmi_dev_config_avi(hdmi_dev, vpara);
1665 hdmi_dev_config_spd(hdmi, hdmi_dev->vendor_name,
1666 hdmi_dev->product_name,
1667 hdmi_dev->deviceinfo);
1668 if (vpara->format_3d != HDMI_3D_NONE) {
1669 hdmi_dev_config_vsi(hdmi,
1671 HDMI_VIDEO_FORMAT_3D);
1672 } else if ((vpara->vic > 92 && vpara->vic < 96) ||
1673 (vpara->vic == 98)) {
1674 vpara->vic = (vpara->vic == 98) ?
1675 4 : (96 - vpara->vic);
1676 hdmi_dev_config_vsi(hdmi,
1678 HDMI_VIDEO_FORMAT_4KX2K);
1680 hdmi_dev_config_vsi(hdmi,
1682 HDMI_VIDEO_FORMAT_NORMAL);
1684 dev_info(hdmi->dev, "[%s] success output HDMI.\n", __func__);
1686 dev_info(hdmi->dev, "[%s] success output DVI.\n", __func__);
1690 rockchip_hdmiv2_config_phy(hdmi_dev);
1692 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
1696 static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev,
1697 struct hdmi_audio *audio)
1699 /* Refer to CEA861-E Audio infoFrame
1700 * Set both Audio Channel Count and Audio Coding
1701 * Type Refer to Stream Head for HDMI
1703 hdmi_msk_reg(hdmi_dev, FC_AUDICONF0,
1704 m_FC_CHN_CNT | m_FC_CODING_TYPE,
1705 v_FC_CHN_CNT(audio->channel - 1) | v_FC_CODING_TYPE(0));
1707 /* Set both Audio Sample Size and Sample Frequency
1708 * Refer to Stream Head for HDMI
1710 hdmi_msk_reg(hdmi_dev, FC_AUDICONF1,
1711 m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ,
1712 v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
1714 /* Set Channel Allocation */
1715 hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1717 /* Set LFEPBLDOWN-MIX INH and LSV */
1718 hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1721 static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio)
1723 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1724 int word_length = 0, channel = 0, mclk_fs;
1725 unsigned int N = 0, CTS = 0;
1729 HDMIDBG("%s\n", __func__);
1731 if (audio->channel < 3)
1732 channel = I2S_CHANNEL_1_2;
1733 else if (audio->channel < 5)
1734 channel = I2S_CHANNEL_3_4;
1735 else if (audio->channel < 7)
1736 channel = I2S_CHANNEL_5_6;
1738 channel = I2S_CHANNEL_7_8;
1740 switch (audio->rate) {
1741 case HDMI_AUDIO_FS_32000:
1744 if (hdmi_dev->tmdsclk >= 594000000)
1746 else if (hdmi_dev->tmdsclk >= 297000000)
1750 /*div a num to avoid the value is exceed 2^32(int)*/
1751 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 32);
1753 case HDMI_AUDIO_FS_44100:
1756 if (hdmi_dev->tmdsclk >= 594000000)
1758 else if (hdmi_dev->tmdsclk >= 297000000)
1763 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 441);
1765 case HDMI_AUDIO_FS_48000:
1768 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1770 else if (hdmi_dev->tmdsclk >= 297000000)
1775 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 48);
1777 case HDMI_AUDIO_FS_88200:
1780 if (hdmi_dev->tmdsclk >= 594000000)
1782 else if (hdmi_dev->tmdsclk >= 297000000)
1787 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 882);
1789 case HDMI_AUDIO_FS_96000:
1792 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1794 else if (hdmi_dev->tmdsclk >= 297000000)
1799 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 96);
1801 case HDMI_AUDIO_FS_176400:
1804 if (hdmi_dev->tmdsclk >= 594000000)
1805 N = N_1764K_HIGHCLK;
1806 else if (hdmi_dev->tmdsclk >= 297000000)
1811 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 1764);
1813 case HDMI_AUDIO_FS_192000:
1816 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1818 else if (hdmi_dev->tmdsclk >= 297000000)
1823 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 192);
1826 dev_err(hdmi_dev->hdmi->dev,
1827 "[%s] not support such sample rate %d\n",
1828 __func__, audio->rate);
1832 switch (audio->word_length) {
1833 case HDMI_AUDIO_WORD_LENGTH_16bit:
1834 word_length = I2S_16BIT_SAMPLE;
1836 case HDMI_AUDIO_WORD_LENGTH_20bit:
1837 word_length = I2S_20BIT_SAMPLE;
1839 case HDMI_AUDIO_WORD_LENGTH_24bit:
1840 word_length = I2S_24BIT_SAMPLE;
1843 word_length = I2S_16BIT_SAMPLE;
1846 HDMIDBG("rate = %d, tmdsclk = %u, N = %d, CTS = %d\n",
1847 audio->rate, hdmi_dev->tmdsclk, N, CTS);
1848 /* more than 2 channels => layout 1 else layout 0 */
1849 hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1851 v_AUD_PACK_LAYOUT((audio->channel > 2) ? 1 : 0));
1853 if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_SPDIF) {
1855 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1856 m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA));
1857 hdmi_msk_reg(hdmi_dev, AUD_SPDIF1,
1858 m_SET_NLPCM | m_SPDIF_WIDTH,
1859 v_SET_NLPCM(PCM_LINEAR) |
1860 v_SPDIF_WIDTH(word_length));
1861 /*Mask fifo empty and full int and reset fifo*/
1862 hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT,
1863 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1864 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1865 hdmi_msk_reg(hdmi_dev, AUD_SPDIF0,
1866 m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1));
1868 /*Mask fifo empty and full int and reset fifo*/
1869 hdmi_msk_reg(hdmi_dev, AUD_INT,
1870 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1871 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1872 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1873 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1874 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1875 design_id = hdmi_readl(hdmi_dev, DESIGN_ID);
1876 if (design_id >= 0x21)
1877 hdmi_writel(hdmi_dev, AUD_CONF2, 0x4);
1879 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
1880 usleep_range(90, 100);
1881 if (channel == I2S_CHANNEL_7_8) {
1882 HDMIDBG("hbr mode.\n");
1883 hdmi_writel(hdmi_dev, AUD_CONF2, 0x1);
1884 word_length = I2S_24BIT_SAMPLE;
1885 } else if ((audio->rate == HDMI_AUDIO_FS_48000) ||
1886 (audio->rate == HDMI_AUDIO_FS_192000)) {
1887 HDMIDBG("nlpcm mode.\n");
1888 hdmi_writel(hdmi_dev, AUD_CONF2, 0x2);
1889 word_length = I2S_24BIT_SAMPLE;
1891 if (design_id >= 0x21)
1892 hdmi_writel(hdmi_dev, AUD_CONF2, 0x4);
1894 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
1896 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1897 m_I2S_SEL | m_I2S_IN_EN,
1898 v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
1899 hdmi_writel(hdmi_dev, AUD_CONF1,
1900 v_I2S_MODE(I2S_STANDARD_MODE) |
1901 v_I2S_WIDTH(word_length));
1904 hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS,
1905 m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs));
1908 hdmi_msk_reg(hdmi_dev, AUD_N3, m_NCTS_ATOMIC_WR, v_NCTS_ATOMIC_WR(1));
1909 /*Set CTS by manual*/
1910 hdmi_msk_reg(hdmi_dev, AUD_CTS3,
1911 m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
1912 v_N_SHIFT(N_SHIFT_1) |
1914 v_AUD_CTS3(CTS >> 16));
1915 hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
1916 hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
1918 hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
1919 hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
1920 hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
1922 /* set channel status register */
1923 hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7,
1924 m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate));
1925 hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2);
1927 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1928 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1930 hdmi_dev_config_aai(hdmi_dev, audio);
1935 static int hdmi_dev_control_output(struct hdmi *hdmi, int enable)
1937 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1938 struct hdmi_video vpara;
1940 HDMIDBG("[%s] %d\n", __func__, enable);
1941 if (enable == HDMI_AV_UNMUTE) {
1942 hdmi_writel(hdmi_dev, FC_DBGFORCE, 0x00);
1943 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI)
1944 hdmi_msk_reg(hdmi_dev, FC_GCP,
1945 m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE,
1946 v_FC_SET_AVMUTE(0) | v_FC_CLR_AVMUTE(1));
1948 if (enable & HDMI_VIDEO_MUTE) {
1949 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1950 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1951 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI) {
1952 hdmi_msk_reg(hdmi_dev, FC_GCP,
1955 v_FC_SET_AVMUTE(1) |
1956 v_FC_CLR_AVMUTE(0));
1957 vpara.vic = hdmi->vic;
1958 vpara.color_output = HDMI_COLOR_RGB_0_255;
1959 hdmi_dev_config_avi(hdmi_dev, &vpara);
1960 while ((!hdmi_readl(hdmi_dev, IH_FC_STAT1)) &
1962 usleep_range(900, 1000);
1966 /* if (enable & HDMI_AUDIO_MUTE) {
1967 * hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1968 * m_AUD_PACK_SAMPFIT,
1969 * v_AUD_PACK_SAMPFIT(0x0F));
1972 if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) {
1973 if (hdmi->ops->hdcp_power_off_cb)
1974 hdmi->ops->hdcp_power_off_cb(hdmi);
1975 rockchip_hdmiv2_powerdown(hdmi_dev);
1981 static int hdmi_dev_insert(struct hdmi *hdmi)
1983 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1985 HDMIDBG("%s\n", __func__);
1987 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1988 return HDMI_ERROR_SUCCESS;
1991 static int hdmi_dev_remove(struct hdmi *hdmi)
1993 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1995 HDMIDBG("%s\n", __func__);
1996 if (hdmi->ops->hdcp_power_off_cb)
1997 hdmi->ops->hdcp_power_off_cb(hdmi);
1998 rockchip_hdmiv2_powerdown(hdmi_dev);
1999 hdmi_dev->tmdsclk = 0;
2000 return HDMI_ERROR_SUCCESS;
2003 static int hdmi_dev_enable(struct hdmi *hdmi)
2005 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2007 HDMIDBG("%s\n", __func__);
2008 if (!hdmi_dev->enable) {
2009 hdmi_writel(hdmi_dev, IH_MUTE, 0x00);
2010 hdmi_dev->enable = 1;
2012 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 10, 0);
2016 static int hdmi_dev_disable(struct hdmi *hdmi)
2018 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2020 HDMIDBG("%s\n", __func__);
2021 if (hdmi_dev->enable) {
2022 hdmi_dev->enable = 0;
2023 hdmi_writel(hdmi_dev, IH_MUTE, 0x1);
2028 void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops)
2031 ops->enable = hdmi_dev_enable;
2032 ops->disable = hdmi_dev_disable;
2033 ops->getstatus = hdmi_dev_detect_hotplug;
2034 ops->insert = hdmi_dev_insert;
2035 ops->remove = hdmi_dev_remove;
2036 ops->getedid = hdmi_dev_read_edid;
2037 ops->setvideo = hdmi_dev_config_video;
2038 ops->setaudio = hdmi_dev_config_audio;
2039 ops->setmute = hdmi_dev_control_output;
2040 ops->setvsi = hdmi_dev_config_vsi;
2044 void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev)
2046 struct hdmi *hdmi = hdmi_dev->hdmi;
2049 pr_info("reset hdmi\n");
2050 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
2051 rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, true);
2052 usleep_range(10, 20);
2053 rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, false);
2055 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
2056 regmap_write(hdmi_dev->grf_base,
2057 RK322X_GRF_SOC_CON2,
2058 RK322X_DDC_MASK_EN);
2059 regmap_write(hdmi_dev->grf_base,
2060 RK322X_GRF_SOC_CON6,
2061 RK322X_IO_3V_DOMAIN);
2063 reset_control_assert(hdmi_dev->reset);
2064 usleep_range(10, 20);
2065 reset_control_deassert(hdmi_dev->reset);
2067 rockchip_hdmiv2_powerdown(hdmi_dev);
2069 hdmi->hotplug = hdmi_dev_detect_hotplug(hdmi);
2070 if (hdmi->hotplug != HDMI_HPD_ACTIVED)
2073 /*mute unnecessary interrupt, only enable hpd*/
2074 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff);
2075 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT1, 0xff);
2076 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT2, 0xff);
2077 hdmi_writel(hdmi_dev, IH_MUTE_AS_STAT0, 0xff);
2078 hdmi_writel(hdmi_dev, IH_MUTE_PHY_STAT0, 0xfc);
2079 hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, 0xff);
2080 hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, 0xff);
2081 hdmi_writel(hdmi_dev, IH_MUTE_VP_STAT0, 0xff);
2082 hdmi_writel(hdmi_dev, IH_MUTE_I2CMPHY_STAT0, 0xff);
2083 hdmi_writel(hdmi_dev, IH_MUTE_AHBDMAAUD_STAT0, 0xff);
2085 /* disable hdcp interrupt */
2086 hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff);
2087 hdmi_writel(hdmi_dev, PHY_MASK, 0xf1);
2089 if (hdmi->property->feature & SUPPORT_CEC)
2090 rockchip_hdmiv2_cec_init(hdmi);
2091 if (hdmi->property->feature & SUPPORT_HDCP)
2092 rockchip_hdmiv2_hdcp_init(hdmi);
2095 irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv)
2097 struct hdmi_dev *hdmi_dev = priv;
2098 struct hdmi *hdmi = hdmi_dev->hdmi;
2099 char phy_pol = hdmi_readl(hdmi_dev, PHY_POL0);
2100 char phy_status = hdmi_readl(hdmi_dev, PHY_STAT0);
2101 char phy_int0 = hdmi_readl(hdmi_dev, PHY_INI0);
2103 char fc_stat0 = hdmi_readl(hdmi_dev, IH_FC_STAT0);
2104 char fc_stat1 = hdmi_readl(hdmi_dev, IH_FC_STAT1);
2105 char fc_stat2 = hdmi_readl(hdmi_dev, IH_FC_STAT2);
2106 char aud_int = hdmi_readl(hdmi_dev, IH_AS_SATA0);
2107 char phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0);
2108 char vp_stat0 = hdmi_readl(hdmi_dev, IH_VP_STAT0);
2109 char cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0);
2110 char hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
2111 char hdcp2_int = hdmi_readl(hdmi_dev, HDCP2REG_STAT);
2114 hdmi_writel(hdmi_dev, IH_FC_STAT0, fc_stat0);
2115 hdmi_writel(hdmi_dev, IH_FC_STAT1, fc_stat1);
2116 hdmi_writel(hdmi_dev, IH_FC_STAT2, fc_stat2);
2117 hdmi_writel(hdmi_dev, IH_VP_STAT0, vp_stat0);
2119 if (phy_int0 || phy_int) {
2120 if ((phy_int0 & m_PHY_LOCK) &&
2121 (phy_pol & m_PHY_LOCK) == 0) {
2122 pr_info("hdmi phy pll unlock\n");
2123 hdmi_submit_work(hdmi, HDMI_SET_VIDEO, 0, 0);
2125 phy_pol = (phy_int0 & (~phy_status)) | ((~phy_int0) & phy_pol);
2126 hdmi_writel(hdmi_dev, PHY_POL0, phy_pol);
2127 hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int);
2128 if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c))
2129 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, 0);
2134 hdmi_writel(hdmi_dev, IH_AS_SATA0, aud_int);
2135 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
2136 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
2137 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
2141 hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int);
2142 if (hdmi_dev->hdmi->property->feature & SUPPORT_CEC)
2143 rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int);
2147 hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
2148 rockchip_hdmiv2_hdcp_isr(hdmi_dev, hdcp_int);
2153 hdmi_writel(hdmi_dev, HDCP2REG_STAT, hdcp2_int);
2154 pr_info("hdcp2_int is 0x%02x\n", hdcp2_int);
2155 if ((hdcp2_int & m_HDCP2_AUTH_FAIL ||
2156 hdcp2_int & m_HDCP2_AUTH_LOST) &&
2157 hdmi_dev->hdcp2_start) {
2158 pr_info("hdcp2 failed or lost\n");
2159 hdmi_dev->hdcp2_start();