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"
9 #include <linux/rockchip/grf.h>
11 #define HDMI_SEL_LCDC(x, bit) ((((x) & 1) << bit) | (1 << (16 + bit)))
12 #define grf_writel(v, offset) writel_relaxed(v, RK_GRF_VIRT + offset)
13 #define RK3399_GRF_SOC_CON20 0x6250
15 static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = {
16 /* tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl
17 * opmode: 0:HDMI1.4 1:HDMI2.0
19 * |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode|
20 * fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl|
22 {27000000, 27000000, 0, 8, 0, 0, 0,
24 {27000000, 27000000, 1, 8, 0, 0, 0,
26 {27000000, 33750000, 0, 10, 1, 0, 0,
28 {27000000, 33750000, 1, 10, 1, 0, 0,
30 {27000000, 40500000, 0, 12, 2, 0, 0,
32 {27000000, 54000000, 0, 16, 3, 0, 0,
34 {59400000, 59400000, 0, 8, 0, 0, 0,
36 {59400000, 74250000, 0, 10, 1, 0, 0,
38 {59400000, 89100000, 0, 12, 2, 0, 0,
40 {59400000, 118800000, 0, 16, 3, 0, 0,
42 {65000000, 65000000, 0, 8, 0, 0, 0,
44 {74250000, 74250000, 0, 8, 0, 0, 0,
46 {74250000, 92812500, 0, 10, 1, 0, 0,
48 {74250000, 111375000, 0, 12, 2, 0, 0,
50 {74250000, 148500000, 0, 16, 3, 0, 0,
52 {83500000, 83500000, 0, 8, 0, 0, 0,
54 {85500000, 85500000, 0, 8, 0, 0, 0,
56 {106500000, 106500000, 0, 8, 0, 0, 0,
58 {108000000, 108000000, 0, 8, 0, 0, 0,
60 {146250000, 146250000, 0, 8, 0, 0, 0,
62 {148500000, 74250000, 0, 8, 0, 0, 0,
64 {148500000, 148500000, 0, 8, 0, 0, 0,
66 {148500000, 185625000, 0, 10, 1, 0, 0,
68 {148500000, 222750000, 0, 12, 2, 0, 0,
70 {148500000, 297000000, 0, 16, 3, 0, 0,
72 {148500000, 297000000, 0, 8, 0, 0, 0,
74 {148500000, 594000000, 0, 8, 0, 3, 1,
76 {269390000, 269390000, 0, 8, 0, 0, 0,
78 {285000000, 285000000, 0, 8, 0, 0, 0,
80 {297000000, 148500000, 0, 8, 0, 0, 0,
82 {297000000, 297000000, 0, 8, 0, 0, 0,
84 {297000000, 371250000, 0, 10, 1, 3, 1,
86 {297000000, 445500000, 0, 12, 2, 3, 1,
88 {297000000, 594000000, 0, 16, 3, 3, 1,
90 {340000000, 340000000, 0, 8, 0, 0, 0,
92 {403000000, 403000000, 0, 8, 0, 3, 1,
94 {594000000, 297000000, 0, 8, 0, 0, 0,
96 {594000000, 371250000, 0, 10, 1, 3, 1,
98 {594000000, 445500000, 0, 12, 2, 3, 1,
100 {594000000, 594000000, 0, 16, 3, 3, 1,
101 1, 3, 3, 0, 0, 0, 3},
102 {594000000, 594000000, 0, 8, 0, 3, 1,
103 1, 3, 3, 0, 0, 0, 3},
106 static const struct ext_pll_config_tab EXT_PLL_TABLE[] = {
107 {27000000, 27000000, 8, 1, 90, 3, 2,
108 2, 10, 3, 3, 4, 0, 1, 40,
110 {27000000, 33750000, 10, 1, 90, 1, 3,
111 3, 10, 3, 3, 4, 0, 1, 40,
113 {59400000, 59400000, 8, 1, 99, 3, 2,
114 2, 1, 3, 3, 4, 0, 1, 40,
116 {59400000, 74250000, 10, 1, 99, 1, 2,
117 2, 1, 3, 3, 4, 0, 1, 40,
119 {74250000, 74250000, 8, 1, 99, 1, 2,
120 2, 1, 2, 3, 4, 0, 1, 40,
122 {74250000, 92812500, 10, 4, 495, 1, 2,
123 2, 1, 3, 3, 4, 0, 2, 40,
125 {148500000, 148500000, 8, 1, 99, 1, 1,
126 1, 1, 2, 2, 2, 0, 2, 40,
128 {148500000, 185625000, 10, 4, 495, 0, 2,
129 2, 1, 3, 2, 2, 0, 4, 40,
131 {297000000, 297000000, 8, 1, 99, 0, 1,
132 1, 1, 0, 2, 2, 0, 4, 40,
134 {297000000, 371250000, 10, 4, 495, 1, 2,
135 0, 1, 3, 1, 1, 0, 8, 40,
137 {594000000, 297000000, 8, 1, 99, 0, 1,
138 1, 1, 0, 2, 1, 0, 4, 40,
140 {594000000, 371250000, 10, 4, 495, 1, 2,
141 0, 1, 3, 1, 1, 1, 8, 40,
143 {594000000, 594000000, 8, 1, 99, 0, 2,
144 0, 1, 0, 1, 1, 0, 8, 40,
148 /* ddc i2c master reset */
149 static void rockchip_hdmiv2_i2cm_reset(struct hdmi_dev *hdmi_dev)
151 hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ,
152 m_I2CM_SOFTRST, v_I2CM_SOFTRST(0));
153 usleep_range(90, 100);
156 /*set read/write offset,set read/write mode*/
157 static void rockchip_hdmiv2_i2cm_write_request(struct hdmi_dev *hdmi_dev,
160 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
161 hdmi_writel(hdmi_dev, I2CM_DATAO, data);
162 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_WR, v_I2CM_WR(1));
165 static void rockchip_hdmiv2_i2cm_read_request(struct hdmi_dev *hdmi_dev,
168 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
169 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD, v_I2CM_RD(1));
172 static void rockchip_hdmiv2_i2cm_write_data(struct hdmi_dev *hdmi_dev,
179 while (trytime-- > 0) {
180 rockchip_hdmiv2_i2cm_write_request(hdmi_dev, offset, data);
182 usleep_range(900, 1000);
183 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
185 hdmi_writel(hdmi_dev,
186 IH_I2CM_STAT0, interrupt);
188 if (interrupt & (m_SCDC_READREQ |
189 m_I2CM_DONE | m_I2CM_ERROR))
193 if (interrupt & m_I2CM_DONE) {
194 dev_dbg(hdmi_dev->hdmi->dev,
195 "[%s] write offset %02x data %02x success\n",
196 __func__, offset, data);
198 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
199 dev_err(hdmi_dev->hdmi->dev,
200 "[%s] write data error\n", __func__);
201 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
206 static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset)
208 u8 interrupt = 0, val;
212 while (trytime-- > 0) {
213 rockchip_hdmiv2_i2cm_read_request(hdmi_dev, offset);
215 usleep_range(900, 1000);
216 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
218 hdmi_writel(hdmi_dev, IH_I2CM_STAT0, interrupt);
220 if (interrupt & (m_SCDC_READREQ |
221 m_I2CM_DONE | m_I2CM_ERROR))
225 if (interrupt & m_I2CM_DONE) {
226 val = hdmi_readl(hdmi_dev, I2CM_DATAI);
228 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
229 pr_err("[%s] read data error\n", __func__);
230 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
236 static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask)
239 hdmi_msk_reg(hdmi_dev, I2CM_INT,
240 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
241 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
242 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
243 v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));
245 hdmi_msk_reg(hdmi_dev, I2CM_INT,
246 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
247 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
248 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
249 v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
253 #define I2C_DIV_FACTOR 1000000
254 static u16 i2c_count(u16 sfrclock, u16 sclmintime)
256 unsigned long tmp_scl_period = 0;
258 if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0)
259 tmp_scl_period = (unsigned long)((sfrclock * sclmintime) +
260 (I2C_DIV_FACTOR - ((sfrclock * sclmintime) %
261 I2C_DIV_FACTOR))) / I2C_DIV_FACTOR;
263 tmp_scl_period = (unsigned long)(sfrclock * sclmintime) /
266 return (u16)(tmp_scl_period);
269 #define EDID_I2C_MIN_SS_SCL_HIGH_TIME 9625
270 #define EDID_I2C_MIN_SS_SCL_LOW_TIME 10000
272 static void rockchip_hdmiv2_i2cm_clk_init(struct hdmi_dev *hdmi_dev)
276 /* Set DDC I2C CLK which divided from DDC_CLK. */
277 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME);
278 hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR,
280 hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_1_ADDR,
281 (value >> 8) & 0xff);
282 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME);
283 hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR,
285 hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_1_ADDR,
286 (value >> 8) & 0xff);
287 hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE,
288 v_I2CM_FAST_STD_MODE(STANDARD_MODE));
291 static int rockchip_hdmiv2_scdc_get_sink_version(struct hdmi_dev *hdmi_dev)
293 return rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SINK_VER);
296 static void rockchip_hdmiv2_scdc_set_source_version(struct hdmi_dev *hdmi_dev,
299 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, version, SCDC_SOURCE_VER);
302 static void rockchip_hdmiv2_scdc_read_request(struct hdmi_dev *hdmi_dev,
305 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
306 m_I2CM_READ_REQ_EN, v_I2CM_READ_REQ_EN(enable));
307 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, enable, SCDC_CONFIG_0);
311 static void rockchip_hdmiv2_scdc_update_read(struct hdmi_dev *hdmi_dev)
313 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
314 m_I2CM_READ_UPDATE, v_I2CM_READ_UPDATE(1));
317 static int rockchip_hdmiv2_scdc_get_scambling_status(struct hdmi_dev *hdmi_dev)
321 val = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SCRAMBLER_STAT);
325 static void rockchip_hdmiv2_scdc_enable_polling(struct hdmi_dev *hdmi_dev,
328 rockchip_hdmiv2_scdc_read_request(hdmi_dev, enable);
329 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
330 m_I2CM_UPRD_VSYNC_EN, v_I2CM_UPRD_VSYNC_EN(enable));
333 static int rockchip_hdmiv2_scdc_get_status_reg0(struct hdmi_dev *hdmi_dev)
335 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
336 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
337 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE0);
340 static int rockchip_hdmiv2_scdc_get_status_reg1(struct hdmi_dev *hdmi_dev)
342 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
343 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
344 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE1);
348 static void rockchip_hdmiv2_scdc_init(struct hdmi_dev *hdmi_dev)
350 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
351 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
352 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
353 /* set scdc i2c addr */
354 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_SCDC_ADDR);
355 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);/*enable interrupt*/
358 static void rockchip_hdmiv2_scdc_set_tmds_rate(struct hdmi_dev *hdmi_dev)
362 mutex_lock(&hdmi_dev->ddc_lock);
363 rockchip_hdmiv2_scdc_init(hdmi_dev);
364 stat = rockchip_hdmiv2_i2cm_read_data(hdmi_dev,
366 if (hdmi_dev->tmdsclk > 340000000)
370 rockchip_hdmiv2_i2cm_write_data(hdmi_dev,
371 stat, SCDC_TMDS_CONFIG);
372 mutex_unlock(&hdmi_dev->ddc_lock);
375 static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev,
378 HDMIDBG(2, "%s enable %d\n", __func__, enable);
380 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
381 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG);
382 /* TMDS software reset request */
383 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
384 m_TMDS_SWRST, v_TMDS_SWRST(0));
385 /* Enable/Disable Scrambling */
386 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
387 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
389 /* Enable/Disable Scrambling */
390 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
391 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
392 /* TMDS software reset request */
393 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
394 m_TMDS_SWRST, v_TMDS_SWRST(0));
395 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
396 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 0, SCDC_TMDS_CONFIG);
401 static const struct ext_pll_config_tab *get_phy_ext_tab(
402 unsigned int pixclock, unsigned int tmdsclk,
409 HDMIDBG(2, "%s pixClock %u tmdsclk %u colorDepth %d\n",
410 __func__, pixclock, tmdsclk, colordepth);
411 for (i = 0; i < ARRAY_SIZE(EXT_PLL_TABLE); i++) {
412 if ((EXT_PLL_TABLE[i].pix_clock == pixclock) &&
413 (EXT_PLL_TABLE[i].tmdsclock == tmdsclk) &&
414 (EXT_PLL_TABLE[i].color_depth == colordepth))
415 return &EXT_PLL_TABLE[i];
420 static const struct phy_mpll_config_tab *get_phy_mpll_tab(
421 unsigned int pixclock, unsigned int tmdsclk,
422 char pixrepet, char colordepth)
428 HDMIDBG(2, "%s pixClock %u tmdsclk %u pixRepet %d colorDepth %d\n",
429 __func__, pixclock, tmdsclk, pixrepet, colordepth);
430 for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
431 if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) &&
432 (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) &&
433 (PHY_MPLL_TABLE[i].pix_repet == pixrepet) &&
434 (PHY_MPLL_TABLE[i].color_depth == colordepth))
435 return &PHY_MPLL_TABLE[i];
440 static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev)
442 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
443 if (hdmi_dev->soctype != HDMI_SOC_RK322X) {
444 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
445 m_PDDQ_SIG | m_TXPWRON_SIG |
446 m_ENHPD_RXSENSE_SIG | m_SVSRET_SIG,
447 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) |
448 v_ENHPD_RXSENSE_SIG(1)) | v_SVSRET_SIG(0);
450 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
451 m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
452 v_TXPWRON_SIG(0) | v_ENHPD_RXSENSE_SIG(0));
453 regmap_write(hdmi_dev->grf_base,
455 RK322X_PLL_PDATA_DEN);
457 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
460 int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev,
461 int reg_addr, int val)
463 int trytime = 2, i = 0, op_status = 0;
465 if (hdmi_dev->phybase) {
466 writel_relaxed(val, hdmi_dev->phybase + (reg_addr) * 0x04);
470 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
471 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff);
472 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff);
473 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE);
477 usleep_range(900, 1000);
478 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
480 hdmi_writel(hdmi_dev,
484 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
488 if (!(op_status & m_I2CMPHY_DONE))
489 dev_err(hdmi_dev->hdmi->dev,
490 "[%s] operation error,trytime=%d\n",
500 int rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev,
503 int trytime = 2, i = 0, op_status = 0;
506 if (hdmi_dev->phybase)
507 return readl_relaxed(hdmi_dev->phybase + (reg_addr) * 0x04);
510 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
511 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00);
512 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00);
513 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ);
517 usleep_range(900, 1000);
518 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
520 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
523 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
527 if (!(op_status & m_I2CMPHY_DONE)) {
528 pr_err("[%s] operation error,trytime=%d\n",
531 val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1);
532 val = (val & 0xff) << 8;
533 val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff);
534 pr_debug("phy_reg0x%02x: 0x%04x",
544 #define PHY_TIMEOUT 10000
546 static int ext_phy_config(struct hdmi_dev *hdmi_dev)
548 int stat = 0, i = 0, temp;
549 const struct ext_pll_config_tab *phy_ext = NULL;
551 if (hdmi_dev->grf_base)
552 regmap_write(hdmi_dev->grf_base,
554 RK322X_PLL_POWER_DOWN |
555 RK322X_PLL_PDATA_DEN);
556 if (hdmi_dev->tmdsclk_ratio_change &&
557 hdmi_dev->hdmi->edid.scdc_present == 1)
558 rockchip_hdmiv2_scdc_set_tmds_rate(hdmi_dev);
560 /* config the required PHY I2C register */
561 phy_ext = get_phy_ext_tab(hdmi_dev->pixelclk,
563 hdmi_dev->colordepth);
565 stat = ((phy_ext->pll_nf >> 1) & EXT_PHY_PLL_FB_BIT8_MASK) |
566 ((phy_ext->vco_div_5 & 1) << 5) |
567 (phy_ext->pll_nd & EXT_PHY_PLL_PRE_DIVIDER_MASK);
568 rockchip_hdmiv2_write_phy(hdmi_dev,
569 EXT_PHY_PLL_PRE_DIVIDER, stat);
570 stat = phy_ext->pll_nf & 0xff;
571 rockchip_hdmiv2_write_phy(hdmi_dev,
572 EXT_PHY_PLL_FB_DIVIDER, stat);
573 stat = (phy_ext->pclk_divider_a & EXT_PHY_PCLK_DIVIDERA_MASK) |
574 ((phy_ext->pclk_divider_b & 3) << 5);
575 rockchip_hdmiv2_write_phy(hdmi_dev,
576 EXT_PHY_PCLK_DIVIDER1, stat);
577 stat = (phy_ext->pclk_divider_d & EXT_PHY_PCLK_DIVIDERD_MASK) |
578 ((phy_ext->pclk_divider_c & 3) << 5);
579 rockchip_hdmiv2_write_phy(hdmi_dev,
580 EXT_PHY_PCLK_DIVIDER2, stat);
581 stat = ((phy_ext->tmsd_divider_c & 3) << 4) |
582 ((phy_ext->tmsd_divider_a & 3) << 2) |
583 (phy_ext->tmsd_divider_b & 3);
584 rockchip_hdmiv2_write_phy(hdmi_dev,
585 EXT_PHY_TMDSCLK_DIVIDER, stat);
586 rockchip_hdmiv2_write_phy(hdmi_dev,
587 EXT_PHY_PPLL_FB_DIVIDER,
590 if (phy_ext->ppll_no == 1) {
591 rockchip_hdmiv2_write_phy(hdmi_dev,
592 EXT_PHY_PPLL_POST_DIVIDER,
594 stat = 0x20 | phy_ext->ppll_nd;
595 rockchip_hdmiv2_write_phy(hdmi_dev,
596 EXT_PHY_PPLL_PRE_DIVIDER,
599 stat = ((phy_ext->ppll_no / 2) - 1) << 4;
600 rockchip_hdmiv2_write_phy(hdmi_dev,
601 EXT_PHY_PPLL_POST_DIVIDER,
603 stat = 0xe0 | phy_ext->ppll_nd;
604 rockchip_hdmiv2_write_phy(hdmi_dev,
605 EXT_PHY_PPLL_PRE_DIVIDER,
609 pr_err("%s no supported phy configuration.\n", __func__);
613 if (hdmi_dev->phy_table) {
614 for (i = 0; i < hdmi_dev->phy_table_size; i++) {
615 temp = hdmi_dev->phy_table[i].maxfreq;
616 if (hdmi_dev->tmdsclk <= temp)
621 if (i != hdmi_dev->phy_table_size) {
622 if (hdmi_dev->phy_table[i].slopeboost) {
623 rockchip_hdmiv2_write_phy(hdmi_dev,
624 EXT_PHY_SIGNAL_CTRL, 0xff);
625 temp = hdmi_dev->phy_table[i].slopeboost - 1;
626 stat = ((temp & 3) << 6) | ((temp & 3) << 4) |
627 ((temp & 3) << 2) | (temp & 3);
628 rockchip_hdmiv2_write_phy(hdmi_dev,
629 EXT_PHY_SLOPEBOOST, stat);
631 rockchip_hdmiv2_write_phy(hdmi_dev,
632 EXT_PHY_SIGNAL_CTRL, 0x0f);
634 stat = ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 4) |
635 ((hdmi_dev->phy_table[i].pre_emphasis & 3) << 2) |
636 (hdmi_dev->phy_table[i].pre_emphasis & 3);
637 rockchip_hdmiv2_write_phy(hdmi_dev,
638 EXT_PHY_PREEMPHASIS, stat);
639 stat = ((hdmi_dev->phy_table[i].clk_level & 0xf) << 4) |
640 (hdmi_dev->phy_table[i].data2_level & 0xf);
641 rockchip_hdmiv2_write_phy(hdmi_dev,
642 EXT_PHY_LEVEL1, stat);
643 stat = ((hdmi_dev->phy_table[i].data1_level & 0xf) << 4) |
644 (hdmi_dev->phy_table[i].data0_level & 0xf);
645 rockchip_hdmiv2_write_phy(hdmi_dev,
646 EXT_PHY_LEVEL2, stat);
648 rockchip_hdmiv2_write_phy(hdmi_dev,
649 EXT_PHY_SIGNAL_CTRL, 0x0f);
651 rockchip_hdmiv2_write_phy(hdmi_dev, 0xf3, 0x22);
653 stat = clk_get_rate(hdmi_dev->pclk_phy) / 100000;
654 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL,
655 ((stat >> 8) & 0xff) | 0x80);
656 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL_DIV_L,
658 if (hdmi_dev->tmdsclk > 340000000)
659 stat = EXT_PHY_AUTO_R100_OHMS;
660 else if (hdmi_dev->tmdsclk > 200000000)
661 stat = EXT_PHY_AUTO_R50_OHMS;
663 stat = EXT_PHY_AUTO_ROPEN_CIRCUIT;
664 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_RESIS_AUTO,
666 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_TERM_CAL,
668 if (hdmi_dev->tmdsclk > 200000000)
672 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PLL_BW, stat);
673 rockchip_hdmiv2_write_phy(hdmi_dev, EXT_PHY_PPLL_BW, 0x27);
674 if (hdmi_dev->grf_base)
675 regmap_write(hdmi_dev->grf_base,
677 RK322X_PLL_POWER_UP);
678 if (hdmi_dev->tmdsclk_ratio_change)
681 usleep_range(900, 1000);
682 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
683 m_TXPWRON_SIG, v_TXPWRON_SIG(1));
685 while (i++ < PHY_TIMEOUT) {
687 temp = EXT_PHY_PPLL_POST_DIVIDER;
688 stat = rockchip_hdmiv2_read_phy(hdmi_dev, temp);
689 if (stat & EXT_PHY_PPLL_LOCK_STATUS_MASK)
691 usleep_range(1000, 2000);
694 if ((stat & EXT_PHY_PPLL_LOCK_STATUS_MASK) == 0) {
695 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
696 dev_err(hdmi_dev->hdmi->dev,
697 "PHY PLL not locked: PCLK_ON=%ld,TMDSCLK_ON=%ld\n",
698 (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
702 if (hdmi_dev->grf_base)
703 regmap_write(hdmi_dev->grf_base,
705 RK322X_PLL_PDATA_EN);
710 static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev)
713 const struct phy_mpll_config_tab *phy_mpll = NULL;
715 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
716 return ext_phy_config(hdmi_dev);
717 } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
718 if (hdmi_dev->pixelclk > 148500000)
719 clk_set_rate(hdmi_dev->pclk_phy, 148500000);
721 clk_set_rate(hdmi_dev->pclk_phy, hdmi_dev->pixelclk);
722 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
723 clk_set_rate(hdmi_dev->pclk_phy, hdmi_dev->pixelclk);
726 hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV,
727 m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0));
728 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
730 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
731 m_PDDQ_SIG | m_TXPWRON_SIG | m_SVSRET_SIG,
732 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | v_SVSRET_SIG(1));
734 if (hdmi_dev->tmdsclk_ratio_change &&
735 hdmi_dev->hdmi->edid.scdc_present == 1)
736 rockchip_hdmiv2_scdc_set_tmds_rate(hdmi_dev);
739 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
740 usleep_range(1000, 2000);
741 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
743 /* Set slave address as PHY GEN2 address */
744 hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
746 /* config the required PHY I2C register */
747 if (hdmi_dev->soctype == HDMI_SOC_RK3366 &&
748 hdmi_dev->pixelclk > 148500000)
749 phy_mpll = get_phy_mpll_tab(148500000,
751 hdmi_dev->pixelrepeat - 1,
752 hdmi_dev->colordepth);
754 phy_mpll = get_phy_mpll_tab(hdmi_dev->pixelclk,
756 hdmi_dev->pixelrepeat - 1,
757 hdmi_dev->colordepth);
759 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG,
760 v_PREP_DIV(phy_mpll->prep_div) |
762 phy_mpll->tmdsmhl_cntrl) |
763 v_OPMODE(phy_mpll->opmode) |
765 phy_mpll->fbdiv2_cntrl) |
767 phy_mpll->fbdiv1_cntrl) |
768 v_REF_CNTRL(phy_mpll->ref_cntrl) |
769 v_MPLL_N_CNTRL(phy_mpll->n_cntrl));
770 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL,
772 phy_mpll->prop_cntrl) |
774 phy_mpll->int_cntrl));
775 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL,
777 phy_mpll->gmp_cntrl));
780 if (hdmi_dev->phy_table) {
781 for (i = 0; i < hdmi_dev->phy_table_size; i++)
782 if (hdmi_dev->tmdsclk <= hdmi_dev->phy_table[i].maxfreq)
785 if (i == hdmi_dev->phy_table_size) {
786 pr_info("%s use default phy settings\n", __func__);
787 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
788 v_OVERRIDE(1) | v_SLOPEBOOST(0) |
789 v_TX_SYMON(1) | v_CLK_SYMON(1) |
791 if (hdmi_dev->tmdsclk > 340000000)
792 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
795 else if (hdmi_dev->tmdsclk > 165000000)
796 rockchip_hdmiv2_write_phy(hdmi_dev,
801 rockchip_hdmiv2_write_phy(hdmi_dev,
806 stat = v_OVERRIDE(1) | v_TX_SYMON(1) | v_CLK_SYMON(1) |
807 v_PREEMPHASIS(hdmi_dev->phy_table[i].pre_emphasis) |
808 v_SLOPEBOOST(hdmi_dev->phy_table[i].slopeboost);
809 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL, stat);
811 stat = v_SUP_CLKLVL(hdmi_dev->phy_table[i].clk_level) |
812 v_SUP_TXLVL(hdmi_dev->phy_table[i].data0_level);
813 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL, stat);
816 if (hdmi_dev->tmdsclk > 340000000)
817 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
818 v_TX_TERM(R50_OHMS));
820 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
821 v_TX_TERM(R100_OHMS));
822 /* rockchip_hdmiv2_write_phy(hdmi_dev, 0x05, 0x8000); */
823 if (hdmi_dev->tmdsclk_ratio_change)
826 hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e);
828 /* check if the PHY PLL is locked */
831 while (i++ < PHY_TIMEOUT) {
833 stat = hdmi_readl(hdmi_dev, PHY_STAT0);
834 if (stat & m_PHY_LOCK)
836 usleep_range(1000, 2000);
839 if ((stat & m_PHY_LOCK) == 0) {
840 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
841 dev_err(hdmi_dev->hdmi->dev,
842 "PHY PLL not locked: PCLK_ON=%ld,TMDSCLK_ON=%ld\n",
843 (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
846 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
850 static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
851 struct hdmi_video *vpara)
853 struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
854 int value, vsync_pol, hsync_pol, de_pol;
855 struct hdmi_video_timing *timing = NULL;
856 struct fb_videomode *mode = NULL;
857 u32 sink_version, tmdsclk;
859 vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
860 hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
861 de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
863 hdmi_msk_reg(hdmi_dev, A_VIDPOLCFG,
864 m_DATAEN_POL | m_VSYNC_POL | m_HSYNC_POL,
865 v_DATAEN_POL(de_pol) |
866 v_VSYNC_POL(vsync_pol) |
867 v_HSYNC_POL(hsync_pol));
869 timing = (struct hdmi_video_timing *)hdmi_vic2timing(vpara->vic);
871 dev_err(hdmi_drv->dev,
872 "[%s] not found vic %d\n", __func__, vpara->vic);
875 mode = &timing->mode;
876 if (vpara->color_input == HDMI_COLOR_YCBCR420)
877 tmdsclk = mode->pixclock / 2;
878 else if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
879 tmdsclk = 2 * mode->pixclock;
881 tmdsclk = mode->pixclock;
882 if (vpara->color_output != HDMI_COLOR_YCBCR422) {
883 switch (vpara->color_output_depth) {
885 tmdsclk += tmdsclk / 4;
888 tmdsclk += tmdsclk / 2;
897 } else if (vpara->color_output_depth > 12) {
898 /* YCbCr422 mode only support up to 12bit */
899 vpara->color_output_depth = 12;
901 if ((tmdsclk > 594000000) ||
902 (tmdsclk > 340000000 &&
903 tmdsclk > hdmi_drv->edid.maxtmdsclock)) {
904 pr_warn("out of max tmds clock, limit to 8bit\n");
905 vpara->color_output_depth = 8;
906 if (vpara->color_input == HDMI_COLOR_YCBCR420)
907 tmdsclk = mode->pixclock / 2;
908 else if (vpara->format_3d != HDMI_3D_FRAME_PACKING)
909 tmdsclk = mode->pixclock;
914 if ((tmdsclk > 340000000) ||
915 (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000))
916 hdmi_dev->tmdsclk_ratio_change = true;
918 hdmi_dev->tmdsclk_ratio_change = false;
920 hdmi_dev->tmdsclk = tmdsclk;
921 if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
922 hdmi_dev->pixelclk = 2 * mode->pixclock;
924 hdmi_dev->pixelclk = mode->pixclock;
925 hdmi_dev->pixelrepeat = timing->pixelrepeat;
926 /* hdmi_dev->colordepth is used for find pll config.
927 * For YCbCr422, tmdsclk is same on all color depth.
929 if (vpara->color_output == HDMI_COLOR_YCBCR422)
930 hdmi_dev->colordepth = 8;
932 hdmi_dev->colordepth = vpara->color_output_depth;
933 pr_info("pixel clk is %lu tmds clk is %u\n",
934 hdmi_dev->pixelclk, hdmi_dev->tmdsclk);
935 /* Start/stop HDCP keepout window generation */
936 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
937 m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
938 if (hdmi_drv->edid.scdc_present == 1 && !hdmi_drv->uboot) {
939 if (tmdsclk > 340000000 ||
940 hdmi_drv->edid.lte_340mcsc_scramble) {
941 /* used for HDMI 2.0 TX */
942 mutex_lock(&hdmi_dev->ddc_lock);
943 rockchip_hdmiv2_scdc_init(hdmi_dev);
945 rockchip_hdmiv2_scdc_get_sink_version(hdmi_dev);
946 pr_info("sink scdc version is %d\n", sink_version);
947 sink_version = hdmi_drv->edid.hf_vsdb_version;
948 rockchip_hdmiv2_scdc_set_source_version(hdmi_dev,
950 if (hdmi_drv->edid.rr_capable == 1)
951 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
952 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 1);
953 mutex_unlock(&hdmi_dev->ddc_lock);
955 mutex_lock(&hdmi_dev->ddc_lock);
956 rockchip_hdmiv2_scdc_init(hdmi_dev);
957 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 0);
958 mutex_unlock(&hdmi_dev->ddc_lock);
961 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
962 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
965 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
966 m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL |
967 m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
968 v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
969 v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) |
970 v_FC_INTERLACE_MODE(mode->vmode));
971 if ((mode->vmode & FB_VMODE_INTERLACED) &&
972 vpara->format_3d != HDMI_3D_FRAME_PACKING)
973 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
974 m_FC_VBLANK, v_FC_VBLANK(1));
976 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
977 m_FC_VBLANK, v_FC_VBLANK(0));
980 if (vpara->color_input == HDMI_COLOR_YCBCR420)
982 hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8));
983 hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff));
985 if (vpara->format_3d == HDMI_3D_FRAME_PACKING) {
986 if (mode->vmode == 0)
987 value = 2 * mode->yres +
992 value = 2 * mode->yres +
993 3 * (mode->upper_margin +
995 mode->vsync_len) + 2;
999 hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8));
1000 hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff));
1002 value = mode->hsync_len + mode->left_margin + mode->right_margin;
1003 if (vpara->color_input == HDMI_COLOR_YCBCR420)
1005 hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(value >> 8));
1006 hdmi_writel(hdmi_dev, FC_INHBLANK0, (value & 0xff));
1008 value = mode->vsync_len + mode->upper_margin + mode->lower_margin;
1009 hdmi_writel(hdmi_dev, FC_INVBLANK, (value & 0xff));
1011 value = mode->right_margin;
1012 if (vpara->color_input == HDMI_COLOR_YCBCR420)
1014 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(value >> 8));
1015 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (value & 0xff));
1017 value = mode->lower_margin;
1018 hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (value & 0xff));
1020 value = mode->hsync_len;
1021 if (vpara->color_input == HDMI_COLOR_YCBCR420)
1023 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(value >> 8));
1024 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (value & 0xff));
1026 value = mode->vsync_len;
1027 hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff));
1029 /* Set the control period minimum duration (min. of 12 pixel
1030 * clock cycles, refer to HDMI 1.4b specification)
1032 hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
1033 hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
1035 /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
1036 * worst case: tmdsClock == 25MHz => config <= 19
1038 hdmi_writel(hdmi_dev, FC_EXCTRLSPAC,
1039 (hdmi_dev->tmdsclk / 1000) * 50 / (256 * 512));
1041 hdmi_writel(hdmi_dev, FC_PRCONF,
1042 v_FC_PR_FACTOR(timing->pixelrepeat) |
1043 v_FC_PR_FACTOR_OUT(timing->pixelrepeat - 1));
1048 static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev,
1049 struct hdmi_video *vpara)
1051 unsigned char color_depth = COLOR_DEPTH_24BIT_DEFAULT;
1052 unsigned char output_select = 0;
1053 unsigned char remap_size = 0;
1055 if (vpara->color_output == HDMI_COLOR_YCBCR422) {
1056 switch (vpara->color_output_depth) {
1058 remap_size = YCC422_16BIT;
1061 remap_size = YCC422_20BIT;
1064 remap_size = YCC422_24BIT;
1067 remap_size = YCC422_16BIT;
1071 output_select = OUT_FROM_YCC422_REMAP;
1072 /*Config remap size for the different color Depth*/
1073 hdmi_msk_reg(hdmi_dev, VP_REMAP,
1074 m_YCC422_SIZE, v_YCC422_SIZE(remap_size));
1076 switch (vpara->color_output_depth) {
1078 color_depth = COLOR_DEPTH_30BIT;
1079 output_select = OUT_FROM_PIXEL_PACKING;
1082 color_depth = COLOR_DEPTH_36BIT;
1083 output_select = OUT_FROM_PIXEL_PACKING;
1086 color_depth = COLOR_DEPTH_48BIT;
1087 output_select = OUT_FROM_PIXEL_PACKING;
1091 color_depth = COLOR_DEPTH_24BIT_DEFAULT;
1092 output_select = OUT_FROM_8BIT_BYPASS;
1096 /*Config Color Depth*/
1097 hdmi_msk_reg(hdmi_dev, VP_PR_CD,
1098 m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth));
1099 /*Config pixel repettion*/
1100 hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR,
1101 v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1));
1102 if (hdmi_dev->pixelrepeat > 1)
1103 hdmi_msk_reg(hdmi_dev, VP_CONF,
1104 m_PIXEL_REPET_EN | m_BYPASS_SEL,
1105 v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
1107 hdmi_msk_reg(hdmi_dev, VP_CONF,
1108 m_PIXEL_REPET_EN | m_BYPASS_SEL,
1109 v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));
1111 /*config output select*/
1112 if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */
1113 hdmi_msk_reg(hdmi_dev, VP_CONF,
1114 m_BYPASS_EN | m_PIXEL_PACK_EN |
1115 m_YCC422_EN | m_OUTPUT_SEL,
1116 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) |
1117 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
1118 } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */
1119 hdmi_msk_reg(hdmi_dev, VP_CONF,
1120 m_BYPASS_EN | m_PIXEL_PACK_EN |
1121 m_YCC422_EN | m_OUTPUT_SEL,
1122 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) |
1123 v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
1124 } else if (output_select == OUT_FROM_8BIT_BYPASS ||
1125 output_select == 3) { /* bypass */
1126 hdmi_msk_reg(hdmi_dev, VP_CONF,
1127 m_BYPASS_EN | m_PIXEL_PACK_EN |
1128 m_YCC422_EN | m_OUTPUT_SEL,
1129 v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
1130 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
1133 #if defined(HDMI_VIDEO_STUFFING)
1134 /* YCC422 and pixel packing stuffing*/
1135 hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
1136 hdmi_msk_reg(hdmi_dev, VP_STUFF,
1137 m_YCC422_STUFFING | m_PP_STUFFING,
1138 v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
1143 static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev,
1144 struct hdmi_video *vpara)
1148 if (vpara->color_input == HDMI_COLOR_YCBCR422) {
1149 /* YCC422 mapping is discontinued - only map 1 is supported */
1150 switch (vpara->color_output_depth) {
1152 map_code = VIDEO_YCBCR422_8BIT;
1155 map_code = VIDEO_YCBCR422_10BIT;
1158 map_code = VIDEO_YCBCR422_12BIT;
1161 map_code = VIDEO_YCBCR422_8BIT;
1164 } else if (vpara->color_input == HDMI_COLOR_YCBCR420 ||
1165 vpara->color_input == HDMI_COLOR_YCBCR444) {
1166 switch (vpara->color_output_depth) {
1168 map_code = VIDEO_YCBCR444_10BIT;
1171 map_code = VIDEO_YCBCR444_12BIT;
1174 map_code = VIDEO_YCBCR444_16BIT;
1178 map_code = VIDEO_YCBCR444_8BIT;
1182 switch (vpara->color_output_depth) {
1184 map_code = VIDEO_RGB444_10BIT;
1187 map_code = VIDEO_RGB444_12BIT;
1190 map_code = VIDEO_RGB444_16BIT;
1194 map_code = VIDEO_RGB444_8BIT;
1197 map_code += (vpara->color_input == HDMI_COLOR_YCBCR444) ?
1201 /* Set Data enable signal from external
1202 * and set video sample input mapping
1204 hdmi_msk_reg(hdmi_dev, TX_INVID0,
1205 m_INTERNAL_DE_GEN | m_VIDEO_MAPPING,
1206 v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));
1208 #if defined(HDMI_VIDEO_STUFFING)
1209 hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
1210 hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
1211 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1212 m_GYDATA_STUFF, v_GYDATA_STUFF(1));
1213 hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
1214 hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
1215 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1216 m_RCRDATA_STUFF, v_RCRDATA_STUFF(1));
1217 hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
1218 hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
1219 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
1220 m_BCBDATA_STUFF, v_BCBDATA_STUFF(1));
1225 static const char coeff_csc[][24] = {
1227 * A1 | A2 | A3 | A4 |
1228 * B1 | B2 | B3 | B4 |
1229 * C1 | C2 | C3 | C4 |
1232 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
1233 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
1234 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
1236 { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */
1237 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /*G*/
1238 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40, /*R*/
1239 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x00, 0x40, /*B*/
1241 { /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */
1242 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /*G*/
1243 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x01, 0x00, /*R*/
1244 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x01, 0x00, /*B*/
1246 { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
1247 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40, /*Y*/
1248 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00, /*Cr*/
1249 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
1251 { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
1252 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00, /*Y*/
1253 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00, /*Cr*/
1254 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
1256 { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
1257 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40, /*Y*/
1258 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00, /*Cr*/
1259 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
1261 { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
1262 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00, /*Y*/
1263 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00, /*Cr*/
1264 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
1267 { /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */
1268 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, /*G*/
1269 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, /*R*/
1270 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b, /*B*/
1272 { /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */
1273 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, /*G*/
1274 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, /*R*/
1275 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25, /*B*/
1279 static int rockchip_hdmiv2_video_csc(struct hdmi_dev *hdmi_dev,
1280 struct hdmi_video *vpara)
1282 int i, mode, interpolation, decimation, csc_scale = 0;
1283 const char *coeff = NULL;
1284 unsigned char color_depth = 0;
1286 if (vpara->color_input == vpara->color_output) {
1287 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1288 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0));
1292 if (vpara->color_input == HDMI_COLOR_YCBCR422 &&
1293 vpara->color_output != HDMI_COLOR_YCBCR422 &&
1294 vpara->color_output != HDMI_COLOR_YCBCR420) {
1296 hdmi_msk_reg(hdmi_dev, CSC_CFG,
1297 m_CSC_INTPMODE, v_CSC_INTPMODE(interpolation));
1300 if ((vpara->color_input == HDMI_COLOR_RGB_0_255 ||
1301 vpara->color_input == HDMI_COLOR_YCBCR444) &&
1302 vpara->color_output == HDMI_COLOR_YCBCR422) {
1304 hdmi_msk_reg(hdmi_dev, CSC_CFG,
1305 m_CSC_DECIMODE, v_CSC_DECIMODE(decimation));
1311 switch (vpara->vic) {
1312 case HDMI_720X480I_60HZ_4_3:
1313 case HDMI_720X576I_50HZ_4_3:
1314 case HDMI_720X480P_60HZ_4_3:
1315 case HDMI_720X576P_50HZ_4_3:
1316 case HDMI_720X480I_60HZ_16_9:
1317 case HDMI_720X576I_50HZ_16_9:
1318 case HDMI_720X480P_60HZ_16_9:
1319 case HDMI_720X576P_50HZ_16_9:
1320 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
1321 vpara->color_output >= HDMI_COLOR_YCBCR444) {
1322 mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
1324 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
1325 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1326 mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
1331 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
1332 vpara->color_output >= HDMI_COLOR_YCBCR444) {
1333 mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
1335 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
1336 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1337 mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
1343 if ((vpara->color_input == HDMI_COLOR_RGB_0_255) &&
1344 (vpara->color_output == HDMI_COLOR_RGB_16_235)) {
1345 mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
1349 switch (vpara->color_output_depth) {
1351 color_depth = COLOR_DEPTH_30BIT;
1355 color_depth = COLOR_DEPTH_36BIT;
1359 color_depth = COLOR_DEPTH_48BIT;
1364 color_depth = COLOR_DEPTH_24BIT;
1368 coeff = coeff_csc[mode];
1369 for (i = 0; i < 24; i++)
1370 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
1372 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1373 m_CSC_SCALE, v_CSC_SCALE(csc_scale));
1374 /*config CSC_COLOR_DEPTH*/
1375 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1376 m_CSC_COLOR_DEPTH, v_CSC_COLOR_DEPTH(color_depth));
1379 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1380 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1));
1385 static int hdmi_dev_detect_hotplug(struct hdmi *hdmi)
1387 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1390 value = hdmi_readl(hdmi_dev, PHY_STAT0);
1391 HDMIDBG(2, "[%s] reg%x value %02x\n", __func__, PHY_STAT0, value);
1392 if (value & m_PHY_HPD)
1393 return HDMI_HPD_ACTIVED;
1395 return HDMI_HPD_REMOVED;
1398 static int hdmi_dev_read_edid(struct hdmi *hdmi, int block, unsigned char *buff)
1400 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1401 int i = 0, n = 0, index = 0, ret = -1, trytime = 5;
1402 int offset = (block % 2) * 0x80;
1405 HDMIDBG(2, "[%s] block %d\n", __func__, block);
1407 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
1409 /* Set DDC I2C CLK which divided from DDC_CLK to 100KHz. */
1410 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
1412 /* Enable I2C interrupt for reading edid */
1413 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);
1415 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
1416 hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
1417 hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
1418 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
1419 for (trytime = 0; trytime < 5; trytime++) {
1420 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
1421 /* enable extend sequential read operation */
1423 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1424 m_I2CM_RD8, v_I2CM_RD8(1));
1426 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1432 usleep_range(900, 1000);
1433 interrupt = hdmi_readl(hdmi_dev,
1436 hdmi_writel(hdmi_dev,
1437 IH_I2CM_STAT0, interrupt);
1440 (m_SCDC_READREQ | m_I2CM_DONE |
1445 if (interrupt & m_I2CM_DONE) {
1446 for (index = 0; index < 8; index++)
1447 buff[8 * n + index] =
1448 hdmi_readl(hdmi_dev,
1452 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
1457 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
1459 "[%s] edid read %d error\n",
1460 __func__, offset + 8 * n);
1465 "[%s] edid read error\n", __func__);
1471 /* Disable I2C interrupt */
1472 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
1476 static void hdmi_dev_config_avi(struct hdmi_dev *hdmi_dev,
1477 struct hdmi_video *vpara)
1479 unsigned char colorimetry, ext_colorimetry = 0, aspect_ratio, y1y0;
1480 unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT;
1482 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(0));
1483 hdmi_msk_reg(hdmi_dev, IH_FC_STAT1,
1484 m_AVI_INFOFRAME, v_AVI_INFOFRAME(1));
1485 /* Set AVI infoFrame Data byte1 */
1486 if (vpara->color_output == HDMI_COLOR_YCBCR444)
1487 y1y0 = AVI_COLOR_MODE_YCBCR444;
1488 else if (vpara->color_output == HDMI_COLOR_YCBCR422)
1489 y1y0 = AVI_COLOR_MODE_YCBCR422;
1490 else if (vpara->color_output == HDMI_COLOR_YCBCR420)
1491 y1y0 = AVI_COLOR_MODE_YCBCR420;
1493 y1y0 = AVI_COLOR_MODE_RGB;
1495 hdmi_msk_reg(hdmi_dev, FC_AVICONF0,
1496 m_FC_ACTIV_FORMAT | m_FC_RGC_YCC,
1497 v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1));
1499 /* Set AVI infoFrame Data byte2 */
1500 switch (vpara->vic) {
1501 case HDMI_720X480I_60HZ_4_3:
1502 case HDMI_720X576I_50HZ_4_3:
1503 case HDMI_720X480P_60HZ_4_3:
1504 case HDMI_720X576P_50HZ_4_3:
1505 aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
1506 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1507 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1509 case HDMI_720X480I_60HZ_16_9:
1510 case HDMI_720X576I_50HZ_16_9:
1511 case HDMI_720X480P_60HZ_16_9:
1512 case HDMI_720X576P_50HZ_16_9:
1513 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1514 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1515 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1518 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1519 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1520 colorimetry = AVI_COLORIMETRY_ITU709;
1523 if (vpara->colorimetry > HDMI_COLORIMETRY_ITU709) {
1524 colorimetry = AVI_COLORIMETRY_EXTENDED;
1525 ext_colorimetry = vpara->colorimetry -
1526 HDMI_COLORIMETRY_EXTEND_XVYCC_601;
1527 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235 ||
1528 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1529 colorimetry = AVI_COLORIMETRY_NO_DATA;
1530 } else if (vpara->colorimetry != HDMI_COLORIMETRY_NO_DATA) {
1531 colorimetry = vpara->colorimetry;
1534 hdmi_writel(hdmi_dev, FC_AVICONF1,
1535 v_FC_COLORIMETRY(colorimetry) |
1536 v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
1537 v_FC_ACT_ASPEC_RATIO(ACTIVE_ASPECT_RATE_DEFAULT));
1539 /* Set AVI infoFrame Data byte3 */
1540 hdmi_msk_reg(hdmi_dev, FC_AVICONF2,
1541 m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE,
1542 v_FC_EXT_COLORIMETRY(ext_colorimetry) |
1543 v_FC_QUAN_RANGE(rgb_quan_range));
1545 /* Set AVI infoFrame Data byte4 */
1546 if ((vpara->vic > 92 && vpara->vic < 96) ||
1547 (vpara->vic == 98) ||
1548 (vpara->vic & HDMI_VIDEO_DMT) ||
1549 (vpara->vic & HDMI_VIDEO_DISCRETE_VR))
1550 hdmi_writel(hdmi_dev, FC_AVIVID, 0);
1552 hdmi_writel(hdmi_dev, FC_AVIVID, vpara->vic & 0xff);
1553 /* Set AVI infoFrame Data byte5 */
1554 hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN,
1555 v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS));
1556 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(1));
1559 static int hdmi_dev_config_vsi(struct hdmi *hdmi,
1560 unsigned char vic_3d, unsigned char format)
1562 int i = 0, id = 0x000c03;
1563 unsigned char data[3] = {0};
1565 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1567 HDMIDBG(2, "[%s] vic %d format %d.\n", __func__, vic_3d, format);
1569 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0));
1570 hdmi_writel(hdmi_dev, FC_VSDIEEEID2, id & 0xff);
1571 hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff);
1572 hdmi_writel(hdmi_dev, FC_VSDIEEEID0, (id >> 16) & 0xff);
1574 data[0] = format << 5; /* PB4 --HDMI_Video_Format */
1576 case HDMI_VIDEO_FORMAT_4KX2K:
1577 data[1] = vic_3d; /* PB5--HDMI_VIC */
1580 case HDMI_VIDEO_FORMAT_3D:
1581 data[1] = vic_3d << 4; /* PB5--3D_Structure field */
1582 data[2] = 0; /* PB6--3D_Ext_Data field */
1590 for (i = 0; i < 3; i++)
1591 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
1592 hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6);
1594 hdmi_writel(hdmi_dev, FC_DATAUTO1, 0);
1595 hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11);
1596 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1));
1600 #define HDR_LSB(n) ((n) & 0xff)
1601 #define HDR_MSB(n) (((n) & 0xff) >> 8)
1603 static void hdmi_dev_config_hdr(struct hdmi_dev *hdmi_dev,
1605 struct hdmi_hdr_metadata *hdr)
1607 /* hdr is supportted after disignid = 0x21 */
1608 if (!hdmi_dev || hdmi_readl(hdmi_dev, DESIGN_ID) < 0x21)
1611 hdmi_writel(hdmi_dev, FC_DRM_HB, 1);/*verion = 0x1*/
1612 hdmi_writel(hdmi_dev, (FC_DRM_HB + 1), 27);/*length of following data*/
1613 hdmi_writel(hdmi_dev, FC_DRM_PB, eotf / 2);
1614 hdmi_writel(hdmi_dev, FC_DRM_PB + 1, 0);
1617 hdmi_writel(hdmi_dev, FC_DRM_PB + 2, HDR_LSB(hdr->prim_x0));
1618 hdmi_writel(hdmi_dev, FC_DRM_PB + 3, HDR_MSB(hdr->prim_x0));
1619 hdmi_writel(hdmi_dev, FC_DRM_PB + 4, HDR_LSB(hdr->prim_y0));
1620 hdmi_writel(hdmi_dev, FC_DRM_PB + 5, HDR_MSB(hdr->prim_y0));
1621 hdmi_writel(hdmi_dev, FC_DRM_PB + 6, HDR_LSB(hdr->prim_x1));
1622 hdmi_writel(hdmi_dev, FC_DRM_PB + 7, HDR_MSB(hdr->prim_x1));
1623 hdmi_writel(hdmi_dev, FC_DRM_PB + 8, HDR_LSB(hdr->prim_y1));
1624 hdmi_writel(hdmi_dev, FC_DRM_PB + 9, HDR_MSB(hdr->prim_y1));
1625 hdmi_writel(hdmi_dev, FC_DRM_PB + 10, HDR_LSB(hdr->prim_x2));
1626 hdmi_writel(hdmi_dev, FC_DRM_PB + 11, HDR_MSB(hdr->prim_x2));
1627 hdmi_writel(hdmi_dev, FC_DRM_PB + 12, HDR_LSB(hdr->prim_y2));
1628 hdmi_writel(hdmi_dev, FC_DRM_PB + 13, HDR_MSB(hdr->prim_y2));
1629 hdmi_writel(hdmi_dev, FC_DRM_PB + 14, HDR_LSB(hdr->white_px));
1630 hdmi_writel(hdmi_dev, FC_DRM_PB + 15, HDR_MSB(hdr->white_px));
1631 hdmi_writel(hdmi_dev, FC_DRM_PB + 16, HDR_LSB(hdr->white_py));
1632 hdmi_writel(hdmi_dev, FC_DRM_PB + 17, HDR_MSB(hdr->white_py));
1633 hdmi_writel(hdmi_dev, FC_DRM_PB + 18, HDR_LSB(hdr->max_dml));
1634 hdmi_writel(hdmi_dev, FC_DRM_PB + 19, HDR_MSB(hdr->max_dml));
1635 hdmi_writel(hdmi_dev, FC_DRM_PB + 20, HDR_LSB(hdr->min_dml));
1636 hdmi_writel(hdmi_dev, FC_DRM_PB + 21, HDR_MSB(hdr->min_dml));
1637 hdmi_writel(hdmi_dev, FC_DRM_PB + 22, HDR_LSB(hdr->max_cll));
1638 hdmi_writel(hdmi_dev, FC_DRM_PB + 23, HDR_MSB(hdr->max_cll));
1639 hdmi_writel(hdmi_dev, FC_DRM_PB + 24, HDR_LSB(hdr->max_fall));
1640 hdmi_writel(hdmi_dev, FC_DRM_PB + 25, HDR_MSB(hdr->max_fall));
1642 hdmi_writel(hdmi_dev, FC_DRM_PB + 1, 0);
1643 hdmi_writel(hdmi_dev, FC_DRM_PB + 2, 0);
1644 hdmi_writel(hdmi_dev, FC_DRM_PB + 3, 0);
1645 hdmi_writel(hdmi_dev, FC_DRM_PB + 4, 0);
1646 hdmi_writel(hdmi_dev, FC_DRM_PB + 5, 0);
1647 hdmi_writel(hdmi_dev, FC_DRM_PB + 6, 0);
1648 hdmi_writel(hdmi_dev, FC_DRM_PB + 7, 0);
1649 hdmi_writel(hdmi_dev, FC_DRM_PB + 8, 0);
1650 hdmi_writel(hdmi_dev, FC_DRM_PB + 9, 0);
1651 hdmi_writel(hdmi_dev, FC_DRM_PB + 10, 0);
1652 hdmi_writel(hdmi_dev, FC_DRM_PB + 11, 0);
1653 hdmi_writel(hdmi_dev, FC_DRM_PB + 12, 0);
1654 hdmi_writel(hdmi_dev, FC_DRM_PB + 13, 0);
1655 hdmi_writel(hdmi_dev, FC_DRM_PB + 14, 0);
1656 hdmi_writel(hdmi_dev, FC_DRM_PB + 15, 0);
1657 hdmi_writel(hdmi_dev, FC_DRM_PB + 16, 0);
1658 hdmi_writel(hdmi_dev, FC_DRM_PB + 17, 0);
1659 hdmi_writel(hdmi_dev, FC_DRM_PB + 18, 0);
1660 hdmi_writel(hdmi_dev, FC_DRM_PB + 19, 0);
1661 hdmi_writel(hdmi_dev, FC_DRM_PB + 20, 0);
1662 hdmi_writel(hdmi_dev, FC_DRM_PB + 21, 0);
1663 hdmi_writel(hdmi_dev, FC_DRM_PB + 22, 0);
1664 hdmi_writel(hdmi_dev, FC_DRM_PB + 23, 0);
1665 hdmi_writel(hdmi_dev, FC_DRM_PB + 24, 0);
1666 hdmi_writel(hdmi_dev, FC_DRM_PB + 25, 0);
1669 hdmi_msk_reg(hdmi_dev, FC_PACK_TXE, m_DRM_TXEN, v_DRM_TXEN(1));
1670 hdmi_msk_reg(hdmi_dev, FC_MASK2, m_DRM_MASK, v_DRM_MASK(0));
1671 hdmi_msk_reg(hdmi_dev, FC_DRM_UP, m_DRM_PUPD, v_DRM_PUPD(1));
1673 hdmi_msk_reg(hdmi_dev, FC_PACK_TXE, m_DRM_TXEN, v_DRM_TXEN(0));
1674 hdmi_msk_reg(hdmi_dev, FC_MASK2, m_DRM_MASK, v_DRM_MASK(1));
1675 hdmi_msk_reg(hdmi_dev, FC_DRM_UP, m_DRM_PUPD, v_DRM_PUPD(1));
1679 static int hdmi_dev_config_spd(struct hdmi *hdmi, const char *vendor,
1680 const char *product, char deviceinfo)
1682 struct hdmi_dev *hdmi_dev;
1685 if (!hdmi || !vendor || !product)
1687 hdmi_dev = hdmi->property->priv;
1689 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(0));
1690 len = strlen(vendor);
1691 for (i = 0; i < 8; i++) {
1693 hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i,
1696 hdmi_writel(hdmi_dev, FC_SPDVENDORNAME0 + i,
1699 len = strlen(product);
1700 for (i = 0; i < 16; i++) {
1702 hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i,
1705 hdmi_writel(hdmi_dev, FC_SPDPRODUCTNAME0 + i,
1708 hdmi_writel(hdmi_dev, FC_SPDDEVICEINF, deviceinfo);
1709 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_SPD_AUTO, v_SPD_AUTO(1));
1713 static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara)
1715 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1717 HDMIDBG(2, "%s vic %d 3dformat %d color mode %d color depth %d\n",
1718 __func__, vpara->vic, vpara->format_3d,
1719 vpara->color_output, vpara->color_output_depth);
1721 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
1722 vpara->color_input = HDMI_COLOR_RGB_0_255;
1725 /* before configure video, we power off phy */
1726 if (hdmi_dev->soctype != HDMI_SOC_RK322X) {
1727 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1728 m_PDDQ_SIG | m_TXPWRON_SIG,
1729 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1731 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1732 m_ENHPD_RXSENSE_SIG,
1733 v_ENHPD_RXSENSE_SIG(1));
1734 regmap_write(hdmi_dev->grf_base,
1735 RK322X_GRF_SOC_CON2,
1736 RK322X_PLL_POWER_DOWN);
1738 /* force output blue */
1739 if (vpara->color_output == HDMI_COLOR_RGB_0_255) {
1740 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/
1741 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/
1742 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/
1743 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235) {
1744 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x10); /*R*/
1745 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/
1746 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10); /*B*/
1748 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*Cr*/
1749 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*Y*/
1750 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*Cb*/
1752 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1753 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1754 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1757 if (rockchip_hdmiv2_video_framecomposer(hdmi, vpara) < 0)
1760 if (rockchip_hdmiv2_video_packetizer(hdmi_dev, vpara) < 0)
1762 /* Color space convert */
1763 if (rockchip_hdmiv2_video_csc(hdmi_dev, vpara) < 0)
1765 if (rockchip_hdmiv2_video_sampler(hdmi_dev, vpara) < 0)
1768 if (vpara->sink_hdmi == OUTPUT_HDMI) {
1769 hdmi_dev_config_avi(hdmi_dev, vpara);
1770 hdmi_dev_config_spd(hdmi, hdmi_dev->vendor_name,
1771 hdmi_dev->product_name,
1772 hdmi_dev->deviceinfo);
1773 if (vpara->format_3d != HDMI_3D_NONE) {
1774 hdmi_dev_config_vsi(hdmi,
1776 HDMI_VIDEO_FORMAT_3D);
1777 } else if ((vpara->vic > 92 && vpara->vic < 96) ||
1778 (vpara->vic == 98)) {
1779 vpara->vic = (vpara->vic == 98) ?
1780 4 : (96 - vpara->vic);
1781 hdmi_dev_config_vsi(hdmi,
1783 HDMI_VIDEO_FORMAT_4KX2K);
1785 hdmi_dev_config_vsi(hdmi,
1787 HDMI_VIDEO_FORMAT_NORMAL);
1789 hdmi_dev_config_hdr(hdmi_dev, vpara->eotf, NULL);
1790 dev_info(hdmi->dev, "[%s] sucess output HDMI.\n", __func__);
1792 dev_info(hdmi->dev, "[%s] success output DVI.\n", __func__);
1796 rockchip_hdmiv2_config_phy(hdmi_dev);
1798 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
1802 static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev,
1803 struct hdmi_audio *audio)
1805 /* Refer to CEA861-E Audio infoFrame
1806 * Set both Audio Channel Count and Audio Coding
1807 * Type Refer to Stream Head for HDMI
1809 hdmi_msk_reg(hdmi_dev, FC_AUDICONF0,
1810 m_FC_CHN_CNT | m_FC_CODING_TYPE,
1811 v_FC_CHN_CNT(audio->channel - 1) | v_FC_CODING_TYPE(0));
1813 /* Set both Audio Sample Size and Sample Frequency
1814 * Refer to Stream Head for HDMI
1816 hdmi_msk_reg(hdmi_dev, FC_AUDICONF1,
1817 m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ,
1818 v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
1820 /* Set Channel Allocation */
1821 hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1823 /* Set LFEPBLDOWN-MIX INH and LSV */
1824 hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1827 static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio)
1829 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1830 int word_length = 0, channel = 0, mclk_fs;
1831 unsigned int N = 0, CTS = 0;
1835 HDMIDBG(2, "%s\n", __func__);
1837 if (audio->channel < 3)
1838 channel = I2S_CHANNEL_1_2;
1839 else if (audio->channel < 5)
1840 channel = I2S_CHANNEL_3_4;
1841 else if (audio->channel < 7)
1842 channel = I2S_CHANNEL_5_6;
1844 channel = I2S_CHANNEL_7_8;
1846 switch (audio->rate) {
1847 case HDMI_AUDIO_FS_32000:
1850 if (hdmi_dev->tmdsclk >= 594000000)
1852 else if (hdmi_dev->tmdsclk >= 297000000)
1856 /*div a num to avoid the value is exceed 2^32(int)*/
1857 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 32);
1859 case HDMI_AUDIO_FS_44100:
1862 if (hdmi_dev->tmdsclk >= 594000000)
1864 else if (hdmi_dev->tmdsclk >= 297000000)
1869 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 441);
1871 case HDMI_AUDIO_FS_48000:
1874 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1876 else if (hdmi_dev->tmdsclk >= 297000000)
1881 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 48);
1883 case HDMI_AUDIO_FS_88200:
1886 if (hdmi_dev->tmdsclk >= 594000000)
1888 else if (hdmi_dev->tmdsclk >= 297000000)
1893 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 882);
1895 case HDMI_AUDIO_FS_96000:
1898 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1900 else if (hdmi_dev->tmdsclk >= 297000000)
1905 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 96);
1907 case HDMI_AUDIO_FS_176400:
1910 if (hdmi_dev->tmdsclk >= 594000000)
1911 N = N_1764K_HIGHCLK;
1912 else if (hdmi_dev->tmdsclk >= 297000000)
1917 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 100, 1764);
1919 case HDMI_AUDIO_FS_192000:
1922 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1924 else if (hdmi_dev->tmdsclk >= 297000000)
1929 CTS = CALC_CTS(N, hdmi_dev->tmdsclk / 1000, 192);
1932 dev_err(hdmi_dev->hdmi->dev,
1933 "[%s] not support such sample rate %d\n",
1934 __func__, audio->rate);
1938 switch (audio->word_length) {
1939 case HDMI_AUDIO_WORD_LENGTH_16bit:
1940 word_length = I2S_16BIT_SAMPLE;
1942 case HDMI_AUDIO_WORD_LENGTH_20bit:
1943 word_length = I2S_20BIT_SAMPLE;
1945 case HDMI_AUDIO_WORD_LENGTH_24bit:
1946 word_length = I2S_24BIT_SAMPLE;
1949 word_length = I2S_16BIT_SAMPLE;
1952 HDMIDBG(2, "rate = %d, tmdsclk = %u, N = %d, CTS = %d\n",
1953 audio->rate, hdmi_dev->tmdsclk, N, CTS);
1954 /* more than 2 channels => layout 1 else layout 0 */
1955 hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1957 v_AUD_PACK_LAYOUT((audio->channel > 2) ? 1 : 0));
1959 if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_SPDIF) {
1961 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1962 m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA));
1963 hdmi_msk_reg(hdmi_dev, AUD_SPDIF1,
1964 m_SET_NLPCM | m_SPDIF_WIDTH,
1965 v_SET_NLPCM(PCM_LINEAR) |
1966 v_SPDIF_WIDTH(word_length));
1967 /*Mask fifo empty and full int and reset fifo*/
1968 hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT,
1969 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1970 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1971 hdmi_msk_reg(hdmi_dev, AUD_SPDIF0,
1972 m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1));
1974 /*Mask fifo empty and full int and reset fifo*/
1975 hdmi_msk_reg(hdmi_dev, AUD_INT,
1976 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1977 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1978 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1979 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1980 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1981 design_id = hdmi_readl(hdmi_dev, DESIGN_ID);
1982 if (design_id >= 0x21)
1983 hdmi_writel(hdmi_dev, AUD_CONF2, 0x4);
1985 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
1986 usleep_range(90, 100);
1988 * when we try to use hdmi nlpcm mode
1989 * we should use set AUD_CONF2 to open this route and set
1990 * word_length to 24bit for b.p.c.u.v with 16bit raw data
1991 * when the bitstream data up to 8 channel, we should use
1993 * HBR Mode : Dolby TrueHD
1997 * FS_32000 FS_44100 FS_48000 : Dolby Digital & DTS
1998 * FS_176400 FS_192000 : Dolby Digital Plus
2000 if (audio->type == HDMI_AUDIO_NLPCM) {
2001 if (channel == I2S_CHANNEL_7_8) {
2002 HDMIDBG(2, "hbr mode.\n");
2003 hdmi_writel(hdmi_dev, AUD_CONF2, 0x1);
2004 word_length = I2S_24BIT_SAMPLE;
2005 } else if ((audio->rate == HDMI_AUDIO_FS_32000) ||
2006 (audio->rate == HDMI_AUDIO_FS_44100) ||
2007 (audio->rate == HDMI_AUDIO_FS_48000) ||
2008 (audio->rate == HDMI_AUDIO_FS_176400) ||
2009 (audio->rate == HDMI_AUDIO_FS_192000)) {
2010 HDMIDBG(2, "nlpcm mode.\n");
2011 hdmi_writel(hdmi_dev, AUD_CONF2, 0x2);
2012 word_length = I2S_24BIT_SAMPLE;
2014 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
2017 if (design_id >= 0x21)
2018 hdmi_writel(hdmi_dev, AUD_CONF2, 0x4);
2020 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
2022 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
2023 m_I2S_SEL | m_I2S_IN_EN,
2024 v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
2025 hdmi_writel(hdmi_dev, AUD_CONF1,
2026 v_I2S_MODE(I2S_STANDARD_MODE) |
2027 v_I2S_WIDTH(word_length));
2030 hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS,
2031 m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs));
2034 hdmi_msk_reg(hdmi_dev, AUD_N3, m_NCTS_ATOMIC_WR, v_NCTS_ATOMIC_WR(1));
2035 /*Set CTS by manual*/
2036 hdmi_msk_reg(hdmi_dev, AUD_CTS3,
2037 m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
2038 v_N_SHIFT(N_SHIFT_1) |
2040 v_AUD_CTS3(CTS >> 16));
2041 hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
2042 hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
2044 hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
2045 hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
2046 hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
2048 /* set channel status register */
2049 hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7,
2050 m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate));
2051 hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2);
2053 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
2054 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
2056 hdmi_dev_config_aai(hdmi_dev, audio);
2061 static int hdmi_dev_control_output(struct hdmi *hdmi, int enable)
2063 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2064 struct hdmi_video vpara;
2066 HDMIDBG(2, "[%s] %d\n", __func__, enable);
2067 if (enable == HDMI_AV_UNMUTE) {
2068 hdmi_writel(hdmi_dev, FC_DBGFORCE, 0x00);
2069 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI)
2070 hdmi_msk_reg(hdmi_dev, FC_GCP,
2071 m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE,
2072 v_FC_SET_AVMUTE(0) | v_FC_CLR_AVMUTE(1));
2074 if (enable & HDMI_VIDEO_MUTE) {
2075 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
2076 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
2077 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI) {
2078 hdmi_msk_reg(hdmi_dev, FC_GCP,
2081 v_FC_SET_AVMUTE(1) |
2082 v_FC_CLR_AVMUTE(0));
2083 vpara.vic = hdmi->vic;
2084 vpara.color_output = HDMI_COLOR_RGB_0_255;
2085 hdmi_dev_config_avi(hdmi_dev, &vpara);
2086 while ((!hdmi_readl(hdmi_dev, IH_FC_STAT1)) &
2088 usleep_range(900, 1000);
2092 /* if (enable & HDMI_AUDIO_MUTE) {
2093 * hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
2094 * m_AUD_PACK_SAMPFIT,
2095 * v_AUD_PACK_SAMPFIT(0x0F));
2098 if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) {
2099 if (hdmi->ops->hdcp_power_off_cb)
2100 hdmi->ops->hdcp_power_off_cb(hdmi);
2101 rockchip_hdmiv2_powerdown(hdmi_dev);
2107 static int hdmi_dev_insert(struct hdmi *hdmi)
2109 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2111 HDMIDBG(2, "%s\n", __func__);
2113 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
2114 return HDMI_ERROR_SUCCESS;
2117 static int hdmi_dev_remove(struct hdmi *hdmi)
2119 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2121 HDMIDBG(2, "%s\n", __func__);
2122 if (hdmi->ops->hdcp_power_off_cb)
2123 hdmi->ops->hdcp_power_off_cb(hdmi);
2124 rockchip_hdmiv2_powerdown(hdmi_dev);
2125 hdmi_dev->tmdsclk = 0;
2126 return HDMI_ERROR_SUCCESS;
2129 static int hdmi_dev_enable(struct hdmi *hdmi)
2131 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2133 HDMIDBG(2, "%s\n", __func__);
2134 if (!hdmi_dev->enable) {
2135 hdmi_writel(hdmi_dev, IH_MUTE, 0x00);
2136 hdmi_dev->enable = 1;
2138 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 10, 0);
2142 static int hdmi_dev_disable(struct hdmi *hdmi)
2144 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
2146 HDMIDBG(2, "%s\n", __func__);
2147 if (hdmi_dev->enable) {
2148 hdmi_dev->enable = 0;
2149 hdmi_writel(hdmi_dev, IH_MUTE, 0x1);
2154 void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops)
2157 ops->enable = hdmi_dev_enable;
2158 ops->disable = hdmi_dev_disable;
2159 ops->getstatus = hdmi_dev_detect_hotplug;
2160 ops->insert = hdmi_dev_insert;
2161 ops->remove = hdmi_dev_remove;
2162 ops->getedid = hdmi_dev_read_edid;
2163 ops->setvideo = hdmi_dev_config_video;
2164 ops->setaudio = hdmi_dev_config_audio;
2165 ops->setmute = hdmi_dev_control_output;
2166 ops->setvsi = hdmi_dev_config_vsi;
2170 void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev)
2172 struct hdmi *hdmi = hdmi_dev->hdmi;
2174 /*lcdc source select*/
2175 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
2176 grf_writel(HDMI_SEL_LCDC(hdmi->property->videosrc, 4),
2177 RK3288_GRF_SOC_CON6);
2178 /* select GPIO7_C0 as cec pin */
2179 grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
2180 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
2181 regmap_write(hdmi_dev->grf_base,
2182 RK3399_GRF_SOC_CON20,
2183 HDMI_SEL_LCDC(hdmi->property->videosrc, 6));
2187 pr_info("reset hdmi\n");
2188 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
2189 rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, true);
2190 usleep_range(10, 20);
2191 rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HDMI, false);
2193 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
2194 regmap_write(hdmi_dev->grf_base,
2195 RK322X_GRF_SOC_CON2,
2196 RK322X_DDC_MASK_EN);
2197 regmap_write(hdmi_dev->grf_base,
2198 RK322X_GRF_SOC_CON6,
2199 RK322X_IO_3V_DOMAIN);
2201 reset_control_assert(hdmi_dev->reset);
2202 usleep_range(10, 20);
2203 reset_control_deassert(hdmi_dev->reset);
2205 rockchip_hdmiv2_powerdown(hdmi_dev);
2207 hdmi->hotplug = hdmi_dev_detect_hotplug(hdmi);
2208 if (hdmi->hotplug != HDMI_HPD_ACTIVED)
2211 /*mute unnecessary interrupt, only enable hpd*/
2212 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff);
2213 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT1, 0xff);
2214 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT2, 0xff);
2215 hdmi_writel(hdmi_dev, IH_MUTE_AS_STAT0, 0xff);
2216 hdmi_writel(hdmi_dev, IH_MUTE_PHY_STAT0, 0xfc);
2217 hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, 0xff);
2218 hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, 0xff);
2219 hdmi_writel(hdmi_dev, IH_MUTE_VP_STAT0, 0xff);
2220 hdmi_writel(hdmi_dev, IH_MUTE_I2CMPHY_STAT0, 0xff);
2221 hdmi_writel(hdmi_dev, IH_MUTE_AHBDMAAUD_STAT0, 0xff);
2223 /* disable hdcp interrupt */
2224 hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff);
2225 hdmi_writel(hdmi_dev, PHY_MASK, 0xf1);
2227 if (hdmi->property->feature & SUPPORT_CEC)
2228 rockchip_hdmiv2_cec_init(hdmi);
2229 if (hdmi->property->feature & SUPPORT_HDCP)
2230 rockchip_hdmiv2_hdcp_init(hdmi);
2233 irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv)
2235 struct hdmi_dev *hdmi_dev = priv;
2236 struct hdmi *hdmi = hdmi_dev->hdmi;
2237 char phy_pol = hdmi_readl(hdmi_dev, PHY_POL0);
2238 char phy_status = hdmi_readl(hdmi_dev, PHY_STAT0);
2239 char phy_int0 = hdmi_readl(hdmi_dev, PHY_INI0);
2241 char fc_stat0 = hdmi_readl(hdmi_dev, IH_FC_STAT0);
2242 char fc_stat1 = hdmi_readl(hdmi_dev, IH_FC_STAT1);
2243 char fc_stat2 = hdmi_readl(hdmi_dev, IH_FC_STAT2);
2244 char aud_int = hdmi_readl(hdmi_dev, IH_AS_SATA0);
2245 char phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0);
2246 char vp_stat0 = hdmi_readl(hdmi_dev, IH_VP_STAT0);
2247 char cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0);
2248 char hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
2249 char hdcp2_int = hdmi_readl(hdmi_dev, HDCP2REG_STAT);
2252 hdmi_writel(hdmi_dev, IH_FC_STAT0, fc_stat0);
2253 hdmi_writel(hdmi_dev, IH_FC_STAT1, fc_stat1);
2254 hdmi_writel(hdmi_dev, IH_FC_STAT2, fc_stat2);
2255 hdmi_writel(hdmi_dev, IH_VP_STAT0, vp_stat0);
2257 if (phy_int0 || phy_int) {
2258 if ((phy_int0 & m_PHY_LOCK) &&
2259 (phy_pol & m_PHY_LOCK) == 0) {
2260 pr_info("hdmi phy pll unlock\n");
2261 hdmi_submit_work(hdmi, HDMI_SET_VIDEO, 0, 0);
2263 phy_pol = (phy_int0 & (~phy_status)) | ((~phy_int0) & phy_pol);
2264 hdmi_writel(hdmi_dev, PHY_POL0, phy_pol);
2265 hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int);
2266 if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c))
2267 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, 0);
2272 hdmi_writel(hdmi_dev, IH_AS_SATA0, aud_int);
2273 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
2274 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
2275 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
2279 hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int);
2280 if (hdmi_dev->hdmi->property->feature & SUPPORT_CEC)
2281 rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int);
2285 hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
2286 rockchip_hdmiv2_hdcp_isr(hdmi_dev, hdcp_int);
2291 hdmi_writel(hdmi_dev, HDCP2REG_STAT, hdcp2_int);
2292 pr_info("hdcp2_int is 0x%02x\n", hdcp2_int);
2293 if ((hdcp2_int & m_HDCP2_AUTH_FAIL ||
2294 hdcp2_int & m_HDCP2_AUTH_LOST) &&
2295 hdmi_dev->hdcp2_start) {
2296 pr_info("hdcp2 failed or lost\n");
2297 hdmi_dev->hdcp2_start();