1 #include <linux/delay.h>
2 #include <linux/interrupt.h>
3 #include <linux/rockchip/grf.h>
4 #include <linux/rockchip/iomap.h>
5 #include "rockchip_hdmiv2.h"
6 #include "rockchip_hdmiv2_hw.h"
8 static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = {
9 /*tmdsclk = (pixclk / ref_cntrl ) * (fbdiv2 * fbdiv1) / nctrl / tmdsmhl
10 opmode: 0:HDMI1.4 1:HDMI2.0
12 /* |pixclock| tmdsclock|pixrepet|colordepth|prepdiv|tmdsmhl|opmode|
13 fbdiv2|fbdiv1|ref_cntrl|nctrl|propctrl|intctrl|gmpctrl| */
14 {27000000, 27000000, 0, 8, 0, 0, 0,
16 {27000000, 33750000, 0, 10, 1, 0, 0,
18 {27000000, 40500000, 0, 12, 2, 0, 0,
20 {27000000, 54000000, 0, 16, 3, 0, 0,
22 {65000000, 65000000, 0, 8, 0, 0, 0,
24 /* {74250000, 74250000, 0, 8, 0, 0, 0,
25 1, 3, 0, 2, 5, 0, 1}, */
26 {74250000, 74250000, 0, 8, 0, 0, 0,
28 {74250000, 92812500, 0, 10, 1, 0, 0,
30 {74250000, 111375000, 0, 12, 2, 0, 0,
32 {74250000, 148500000, 0, 16, 3, 0, 0,
34 {83500000, 83500000, 0, 8, 0, 0, 0,
36 {85500000, 85500000, 0, 8, 0, 0, 0,
38 {106500000, 106500000, 0, 8, 0, 0, 0,
40 {108000000, 108000000, 0, 8, 0, 0, 0,
42 {146250000, 146250000, 0, 8, 0, 0, 0,
44 {148500000, 74250000, 0, 8, 0, 0, 0,
46 {148500000, 148500000, 0, 8, 0, 0, 0,
48 {148500000, 185625000, 0, 10, 1, 0, 0,
50 {148500000, 222750000, 0, 12, 2, 0, 0,
52 {148500000, 297000000, 0, 16, 3, 0, 0,
54 {297000000, 148500000, 0, 8, 0, 0, 0,
56 {297000000, 297000000, 0, 8, 0, 0, 0,
58 {297000000, 371250000, 0, 10, 1, 3, 1,
60 {297000000, 445500000, 0, 12, 2, 3, 1,
62 {297000000, 594000000, 0, 16, 3, 3, 1,
64 /* {594000000, 297000000, 0, 8, 0, 0, 0,
65 1, 3, 3, 1, 0, 0, 3},*/
66 {594000000, 297000000, 0, 8, 0, 0, 0,
68 {594000000, 371250000, 0, 10, 1, 3, 1,
70 {594000000, 445500000, 0, 12, 2, 3, 1,
72 {594000000, 594000000, 0, 16, 3, 3, 1,
74 {594000000, 594000000, 0, 8, 0, 3, 1,
77 /* ddc i2c master reset */
78 static void rockchip_hdmiv2_i2cm_reset(struct hdmi_dev *hdmi_dev)
80 hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ,
81 m_I2CM_SOFTRST, v_I2CM_SOFTRST(0));
82 usleep_range(90, 100);
85 /*set read/write offset,set read/write mode*/
86 static void rockchip_hdmiv2_i2cm_write_request(struct hdmi_dev *hdmi_dev,
89 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
90 hdmi_writel(hdmi_dev, I2CM_DATAO, data);
91 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_WR, v_I2CM_WR(1));
94 static void rockchip_hdmiv2_i2cm_read_request(struct hdmi_dev *hdmi_dev,
97 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
98 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD, v_I2CM_RD(1));
101 static void rockchip_hdmiv2_i2cm_write_data(struct hdmi_dev *hdmi_dev,
108 while (trytime-- > 0) {
109 rockchip_hdmiv2_i2cm_write_request(hdmi_dev, offset, data);
111 usleep_range(900, 1000);
112 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
114 hdmi_writel(hdmi_dev,
115 IH_I2CM_STAT0, interrupt);
117 if (interrupt & (m_SCDC_READREQ |
118 m_I2CM_DONE | m_I2CM_ERROR))
122 if (interrupt & m_I2CM_DONE) {
123 dev_dbg(hdmi_dev->hdmi->dev,
124 "[%s] write offset %02x data %02x success\n",
125 __func__, offset, data);
127 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
128 dev_err(hdmi_dev->hdmi->dev,
129 "[%s] write data error\n", __func__);
130 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
135 static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset)
141 while (trytime-- > 0) {
142 rockchip_hdmiv2_i2cm_read_request(hdmi_dev, offset);
144 usleep_range(900, 1000);
145 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
147 hdmi_writel(hdmi_dev, IH_I2CM_STAT0, interrupt);
149 if (interrupt & (m_SCDC_READREQ |
150 m_I2CM_DONE | m_I2CM_ERROR))
154 if (interrupt & m_I2CM_DONE) {
155 val = hdmi_readl(hdmi_dev, I2CM_DATAI);
157 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
158 pr_err("[%s] read data error\n", __func__);
159 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
165 static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask)
168 hdmi_msk_reg(hdmi_dev, I2CM_INT,
169 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
170 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
171 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
172 v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));
174 hdmi_msk_reg(hdmi_dev, I2CM_INT,
175 m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
176 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
177 m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
178 v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
182 #define I2C_DIV_FACTOR 100000
183 static u16 i2c_count(u16 sfrclock, u16 sclmintime)
185 unsigned long tmp_scl_period = 0;
187 if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0)
188 tmp_scl_period = (unsigned long)((sfrclock * sclmintime) +
189 (I2C_DIV_FACTOR - ((sfrclock * sclmintime) %
190 I2C_DIV_FACTOR))) / I2C_DIV_FACTOR;
192 tmp_scl_period = (unsigned long)(sfrclock * sclmintime) /
195 return (u16)(tmp_scl_period);
198 #define EDID_I2C_MIN_SS_SCL_HIGH_TIME 50000
199 #define EDID_I2C_MIN_SS_SCL_LOW_TIME 50000
201 static void rockchip_hdmiv2_i2cm_clk_init(struct hdmi_dev *hdmi_dev)
203 /* Set DDC I2C CLK which devided from DDC_CLK. */
204 hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR,
205 i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME));
206 hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR,
207 i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME));
208 hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE,
209 v_I2CM_FAST_STD_MODE(STANDARD_MODE));
212 static int rockchip_hdmiv2_scdc_get_sink_version(struct hdmi_dev *hdmi_dev)
214 return rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SINK_VER);
217 static void rockchip_hdmiv2_scdc_set_source_version(struct hdmi_dev *hdmi_dev,
220 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, version, SCDC_SOURCE_VER);
224 static void rockchip_hdmiv2_scdc_read_request(struct hdmi_dev *hdmi_dev,
227 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
228 m_I2CM_READ_REQ_EN, v_I2CM_READ_REQ_EN(enable));
229 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, enable, SCDC_CONFIG_0);
233 static void rockchip_hdmiv2_scdc_update_read(struct hdmi_dev *hdmi_dev)
235 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
236 m_I2CM_READ_UPDATE, v_I2CM_READ_UPDATE(1));
240 static int rockchip_hdmiv2_scdc_get_scambling_status(struct hdmi_dev *hdmi_dev)
244 val = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SCRAMBLER_STAT);
248 static void rockchip_hdmiv2_scdc_enable_polling(struct hdmi_dev *hdmi_dev,
251 rockchip_hdmiv2_scdc_read_request(hdmi_dev, enable);
252 hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
253 m_I2CM_UPRD_VSYNC_EN, v_I2CM_UPRD_VSYNC_EN(enable));
256 static int rockchip_hdmiv2_scdc_get_status_reg0(struct hdmi_dev *hdmi_dev)
258 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
259 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
260 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE0);
263 static int rockchip_hdmiv2_scdc_get_status_reg1(struct hdmi_dev *hdmi_dev)
265 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
266 rockchip_hdmiv2_scdc_update_read(hdmi_dev);
267 return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE1);
271 static void rockchip_hdmiv2_scdc_init(struct hdmi_dev *hdmi_dev)
273 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
274 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
275 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
276 /* set scdc i2c addr */
277 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_SCDC_ADDR);
278 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);/*enable interrupt*/
282 static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev,
285 HDMIDBG("%s enable %d\n", __func__, enable);
287 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
288 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG);
289 /* TMDS software reset request */
290 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
291 m_TMDS_SWRST, v_TMDS_SWRST(0));
292 /* Enable/Disable Scrambling */
293 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
294 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
296 /* Enable/Disable Scrambling */
297 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
298 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
299 /* TMDS software reset request */
300 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
301 m_TMDS_SWRST, v_TMDS_SWRST(0));
302 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
303 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 0, SCDC_TMDS_CONFIG);
310 static const struct phy_mpll_config_tab *get_phy_mpll_tab(
311 unsigned int pixclock, unsigned int tmdsclk,
312 char pixrepet, char colordepth)
318 HDMIDBG("%s pixClock %u tmdsclk %u pixRepet %d colorDepth %d\n",
319 __func__, pixclock, tmdsclk, pixrepet, colordepth);
320 for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
321 if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) &&
322 (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) &&
323 (PHY_MPLL_TABLE[i].pix_repet == pixrepet) &&
324 (PHY_MPLL_TABLE[i].color_depth == colordepth))
325 return &PHY_MPLL_TABLE[i];
330 static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev)
332 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
333 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
334 m_PDDQ_SIG | m_TXPWRON_SIG |
335 m_ENHPD_RXSENSE_SIG | m_SVSRET_SIG,
336 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) |
337 v_ENHPD_RXSENSE_SIG(1)) | v_SVSRET_SIG(0);
338 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
341 int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev,
342 int reg_addr, int val)
344 int trytime = 2, i = 0, op_status = 0;
347 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
348 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff);
349 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff);
350 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE);
354 usleep_range(900, 1000);
355 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
357 hdmi_writel(hdmi_dev,
361 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
365 if (op_status & m_I2CMPHY_DONE)
368 dev_err(hdmi_dev->hdmi->dev,
369 "[%s] operation error,trytime=%d\n",
377 int rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev,
380 int trytime = 2, i = 0, op_status = 0;
384 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
385 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00);
386 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00);
387 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ);
391 usleep_range(900, 1000);
392 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
394 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
397 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
401 if (op_status & m_I2CMPHY_DONE) {
402 val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1);
403 val = (val & 0xff) << 8;
404 val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff);
405 pr_debug("phy_reg0x%02x: 0x%04x",
409 pr_err("[%s] operation error,trytime=%d\n",
418 static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev)
421 const struct phy_mpll_config_tab *phy_mpll = NULL;
423 hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV,
424 m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0));
425 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(1));
427 /* hdmi_writel(hdmi_dev, PHY_CONF0, 0x1e); */
428 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
429 m_PDDQ_SIG | m_TXPWRON_SIG | m_SVSRET_SIG,
430 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | v_SVSRET_SIG(1));
432 if (hdmi_dev->tmdsclk_ratio_change &&
433 hdmi_dev->hdmi->edid.scdc_present == 1) {
434 mutex_lock(&hdmi_dev->ddc_lock);
435 rockchip_hdmiv2_scdc_init(hdmi_dev);
436 stat = rockchip_hdmiv2_i2cm_read_data(hdmi_dev,
438 if (hdmi_dev->tmdsclk > 340000000)
442 rockchip_hdmiv2_i2cm_write_data(hdmi_dev,
443 stat, SCDC_TMDS_CONFIG);
444 mutex_unlock(&hdmi_dev->ddc_lock);
447 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
448 usleep_range(1000, 2000);
449 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
451 /* Set slave address as PHY GEN2 address */
452 hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
454 /* config the required PHY I2C register */
455 phy_mpll = get_phy_mpll_tab(hdmi_dev->pixelclk,
457 hdmi_dev->pixelrepeat - 1,
458 hdmi_dev->colordepth);
460 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG,
461 v_PREP_DIV(phy_mpll->prep_div) |
463 phy_mpll->tmdsmhl_cntrl) |
464 v_OPMODE(phy_mpll->opmode) |
466 phy_mpll->fbdiv2_cntrl) |
468 phy_mpll->fbdiv1_cntrl) |
469 v_REF_CNTRL(phy_mpll->ref_cntrl) |
470 v_MPLL_N_CNTRL(phy_mpll->n_cntrl));
471 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL,
473 phy_mpll->prop_cntrl) |
475 phy_mpll->int_cntrl));
476 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL,
478 phy_mpll->gmp_cntrl));
481 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
482 v_OVERRIDE(1) | v_SLOPEBOOST(0) |
483 v_TX_SYMON(1) | v_TX_TRAON(0) |
484 v_TX_TRBON(0) | v_CLK_SYMON(1));
485 if (hdmi_dev->tmdsclk > 340000000) {
486 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
487 v_TX_TERM(R50_OHMS));
488 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
492 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
493 v_TX_TERM(R100_OHMS));
494 if (hdmi_dev->tmdsclk > 165000000)
495 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
499 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
503 /* rockchip_hdmiv2_write_phy(hdmi_dev, 0x05, 0x8000); */
504 if (hdmi_dev->tmdsclk_ratio_change)
507 hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e);
509 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
510 m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
511 v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) |
512 v_ENHPD_RXSENSE_SIG(1));
514 /* check if the PHY PLL is locked */
515 #define PHY_TIMEOUT 10000
516 while (i++ < PHY_TIMEOUT) {
518 stat = hdmi_readl(hdmi_dev, PHY_STAT0);
519 if (stat & m_PHY_LOCK)
521 usleep_range(1000, 2000);
524 if ((stat & m_PHY_LOCK) == 0) {
525 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
526 dev_err(hdmi_dev->hdmi->dev,
527 "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n",
528 (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
531 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
535 static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
536 struct hdmi_video *vpara)
538 struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
539 int value, vsync_pol, hsync_pol, de_pol;
540 struct hdmi_video_timing *timing = NULL;
541 struct fb_videomode *mode = NULL;
542 u32 sink_version, tmdsclk;
544 vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
545 hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
546 de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
548 hdmi_msk_reg(hdmi_dev, A_VIDPOLCFG,
549 m_DATAEN_POL | m_VSYNC_POL | m_HSYNC_POL,
550 v_DATAEN_POL(de_pol) |
551 v_VSYNC_POL(vsync_pol) |
552 v_HSYNC_POL(hsync_pol));
554 timing = (struct hdmi_video_timing *)hdmi_vic2timing(vpara->vic);
555 if (timing == NULL) {
556 dev_err(hdmi_drv->dev,
557 "[%s] not found vic %d\n", __func__, vpara->vic);
560 mode = &(timing->mode);
561 if (vpara->color_input == HDMI_COLOR_YCBCR420)
562 tmdsclk = mode->pixclock / 2;
563 else if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
564 tmdsclk = 2 * mode->pixclock;
566 tmdsclk = mode->pixclock;
567 switch (vpara->color_output_depth) {
569 tmdsclk += tmdsclk / 4;
572 tmdsclk += tmdsclk / 2;
582 if (tmdsclk > 594000000) {
583 vpara->color_output_depth = 8;
584 tmdsclk = mode->pixclock;
587 if ((tmdsclk > 340000000) ||
588 (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000))
589 hdmi_dev->tmdsclk_ratio_change = true;
591 hdmi_dev->tmdsclk_ratio_change = false;
593 hdmi_dev->tmdsclk = tmdsclk;
594 if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
595 hdmi_dev->pixelclk = 2 * mode->pixclock;
597 hdmi_dev->pixelclk = mode->pixclock;
598 hdmi_dev->pixelrepeat = timing->pixelrepeat;
599 hdmi_dev->colordepth = vpara->color_output_depth;
601 pr_info("pixel clk is %lu tmds clk is %u\n",
602 hdmi_dev->pixelclk, hdmi_dev->tmdsclk);
603 /* Start/stop HDCP keepout window generation */
604 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
605 m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
606 if (hdmi_drv->edid.scdc_present == 1 && !hdmi_drv->uboot) {
607 if (tmdsclk > 340000000 ||
608 hdmi_drv->edid.lte_340mcsc_scramble) {
609 /* used for HDMI 2.0 TX */
610 mutex_lock(&hdmi_dev->ddc_lock);
611 rockchip_hdmiv2_scdc_init(hdmi_dev);
613 rockchip_hdmiv2_scdc_get_sink_version(hdmi_dev);
614 pr_info("sink scdc version is %d\n", sink_version);
615 sink_version = hdmi_drv->edid.hf_vsdb_version;
616 rockchip_hdmiv2_scdc_set_source_version(hdmi_dev,
618 if (hdmi_drv->edid.rr_capable == 1)
619 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
620 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 1);
621 mutex_unlock(&hdmi_dev->ddc_lock);
623 mutex_lock(&hdmi_dev->ddc_lock);
624 rockchip_hdmiv2_scdc_init(hdmi_dev);
625 rockchip_hdmiv2_scrambling_enable(hdmi_dev, 0);
626 mutex_unlock(&hdmi_dev->ddc_lock);
629 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
630 m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
633 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
634 m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL |
635 m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
636 v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
637 v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) |
638 v_FC_INTERLACE_MODE(mode->vmode));
639 if (mode->vmode == FB_VMODE_INTERLACED &&
640 vpara->format_3d != HDMI_3D_FRAME_PACKING)
641 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
642 m_FC_VBLANK, v_FC_VBLANK(1));
644 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
645 m_FC_VBLANK, v_FC_VBLANK(0));
648 if (vpara->color_input == HDMI_COLOR_YCBCR420)
650 hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8));
651 hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff));
653 if (vpara->format_3d == HDMI_3D_FRAME_PACKING) {
654 if (mode->vmode == 0)
655 value = 2 * mode->yres +
660 value = 2 * mode->yres +
661 3 * (mode->upper_margin +
663 mode->vsync_len) + 2;
667 hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8));
668 hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff));
670 value = mode->hsync_len + mode->left_margin + mode->right_margin;
671 if (vpara->color_input == HDMI_COLOR_YCBCR420)
673 hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(value >> 8));
674 hdmi_writel(hdmi_dev, FC_INHBLANK0, (value & 0xff));
676 value = mode->vsync_len + mode->upper_margin + mode->lower_margin;
677 hdmi_writel(hdmi_dev, FC_INVBLANK, (value & 0xff));
679 value = mode->right_margin;
680 if (vpara->color_input == HDMI_COLOR_YCBCR420)
682 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(value >> 8));
683 hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (value & 0xff));
685 value = mode->lower_margin;
686 hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (value & 0xff));
688 value = mode->hsync_len;
689 if (vpara->color_input == HDMI_COLOR_YCBCR420)
691 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(value >> 8));
692 hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (value & 0xff));
694 value = mode->vsync_len;
695 hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff));
697 /*Set the control period minimum duration
698 (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/
699 hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
700 hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
702 /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
703 * worst case: tmdsClock == 25MHz => config <= 19
705 hdmi_writel(hdmi_dev, FC_EXCTRLSPAC,
706 (hdmi_dev->tmdsclk/1000) * 50 / (256 * 512));
707 if (!hdmi_drv->uboot)
708 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
709 m_TMDS_SWRST, v_TMDS_SWRST(0));
711 /*Set PreambleFilter*/
712 for (i = 0; i < 3; i++) {
713 value = (i + 1) * 11;
714 if (i == 0) /*channel 0*/
715 hdmi_writel(hdmi_dev, FC_CH0PREAM, value);
716 else if (i == 1) /*channel 1*/
717 hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f);
718 else if (i == 2) /*channel 2*/
719 hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f);
723 hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(timing->pixelrepeat));
728 static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev,
729 struct hdmi_video *vpara)
731 unsigned char color_depth = 0;
732 unsigned char output_select = 0;
733 unsigned char remap_size = 0;
735 if (vpara->color_output == HDMI_COLOR_YCBCR422) {
736 switch (vpara->color_output_depth) {
738 remap_size = YCC422_16BIT;
741 remap_size = YCC422_20BIT;
744 remap_size = YCC422_24BIT;
747 remap_size = YCC422_16BIT;
751 output_select = OUT_FROM_YCC422_REMAP;
752 /*Config remap size for the different color Depth*/
753 hdmi_msk_reg(hdmi_dev, VP_REMAP,
754 m_YCC422_SIZE, v_YCC422_SIZE(remap_size));
756 switch (vpara->color_output_depth) {
758 color_depth = COLOR_DEPTH_30BIT;
759 output_select = OUT_FROM_PIXEL_PACKING;
762 color_depth = COLOR_DEPTH_36BIT;
763 output_select = OUT_FROM_PIXEL_PACKING;
766 color_depth = COLOR_DEPTH_48BIT;
767 output_select = OUT_FROM_PIXEL_PACKING;
771 color_depth = COLOR_DEPTH_24BIT_DEFAULT;
772 output_select = OUT_FROM_8BIT_BYPASS;
776 /*Config Color Depth*/
777 hdmi_msk_reg(hdmi_dev, VP_PR_CD,
778 m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth));
781 /*Config pixel repettion*/
782 hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR,
783 v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1));
784 if (hdmi_dev->pixelrepeat > 1)
785 hdmi_msk_reg(hdmi_dev, VP_CONF,
786 m_PIXEL_REPET_EN | m_BYPASS_SEL,
787 v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
789 hdmi_msk_reg(hdmi_dev, VP_CONF,
790 m_PIXEL_REPET_EN | m_BYPASS_SEL,
791 v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));
793 /*config output select*/
794 if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */
795 hdmi_msk_reg(hdmi_dev, VP_CONF,
796 m_BYPASS_EN | m_PIXEL_PACK_EN |
797 m_YCC422_EN | m_OUTPUT_SEL,
798 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) |
799 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
800 } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */
801 hdmi_msk_reg(hdmi_dev, VP_CONF,
802 m_BYPASS_EN | m_PIXEL_PACK_EN |
803 m_YCC422_EN | m_OUTPUT_SEL,
804 v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) |
805 v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
806 } else if (output_select == OUT_FROM_8BIT_BYPASS ||
807 output_select == 3) { /* bypass */
808 hdmi_msk_reg(hdmi_dev, VP_CONF,
809 m_BYPASS_EN | m_PIXEL_PACK_EN |
810 m_YCC422_EN | m_OUTPUT_SEL,
811 v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
812 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
815 #if defined(HDMI_VIDEO_STUFFING)
816 /* YCC422 and pixel packing stuffing*/
817 hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
818 hdmi_msk_reg(hdmi_dev, VP_STUFF,
819 m_YCC422_STUFFING | m_PP_STUFFING,
820 v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
825 static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev,
826 struct hdmi_video *vpara)
830 if (vpara->color_input == HDMI_COLOR_YCBCR422) {
831 /* YCC422 mapping is discontinued - only map 1 is supported */
832 switch (vpara->color_output_depth) {
834 map_code = VIDEO_YCBCR422_8BIT;
837 map_code = VIDEO_YCBCR422_10BIT;
840 map_code = VIDEO_YCBCR422_12BIT;
843 map_code = VIDEO_YCBCR422_8BIT;
846 } else if (vpara->color_input == HDMI_COLOR_YCBCR420 ||
847 vpara->color_input == HDMI_COLOR_YCBCR444) {
848 switch (vpara->color_output_depth) {
850 map_code = VIDEO_YCBCR444_10BIT;
853 map_code = VIDEO_YCBCR444_12BIT;
856 map_code = VIDEO_YCBCR444_16BIT;
860 map_code = VIDEO_YCBCR444_8BIT;
864 switch (vpara->color_output_depth) {
866 map_code = VIDEO_RGB444_10BIT;
869 map_code = VIDEO_RGB444_12BIT;
872 map_code = VIDEO_RGB444_16BIT;
876 map_code = VIDEO_RGB444_8BIT;
879 map_code += (vpara->color_input == HDMI_COLOR_YCBCR444) ?
883 /* Set Data enable signal from external
884 and set video sample input mapping */
885 hdmi_msk_reg(hdmi_dev, TX_INVID0,
886 m_INTERNAL_DE_GEN | m_VIDEO_MAPPING,
887 v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));
889 #if defined(HDMI_VIDEO_STUFFING)
890 hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
891 hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
892 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
893 m_GYDATA_STUFF, v_GYDATA_STUFF(1));
894 hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
895 hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
896 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
897 m_RCRDATA_STUFF, v_RCRDATA_STUFF(1));
898 hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
899 hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
900 hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
901 m_BCBDATA_STUFF, v_BCBDATA_STUFF(1));
906 static const char coeff_csc[][24] = {
910 C1 | C2 | C3 | C4 | */
911 { /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */
912 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /*G*/
913 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40, /*R*/
914 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x00, 0x40, /*B*/
916 { /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */
917 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /*G*/
918 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x01, 0x00, /*R*/
919 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x01, 0x00, /*B*/
921 { /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
922 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40, /*Y*/
923 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00, /*Cr*/
924 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
926 { /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
927 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00, /*Y*/
928 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00, /*Cr*/
929 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
931 { /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
932 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40, /*Y*/
933 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00, /*Cr*/
934 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00, /*Cb*/
936 { /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
937 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00, /*Y*/
938 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00, /*Cr*/
939 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00, /*Cb*/
942 { /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */
943 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, /*G*/
944 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, /*R*/
945 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b, /*B*/
947 { /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */
948 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, /*G*/
949 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, /*R*/
950 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25, /*B*/
954 static int rockchip_hdmiv2_video_csc(struct hdmi_dev *hdmi_dev,
955 struct hdmi_video *vpara)
957 int i, mode, interpolation, decimation, csc_scale;
958 const char *coeff = NULL;
959 unsigned char color_depth = 0;
961 if (vpara->color_input == vpara->color_output) {
962 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
963 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0));
967 if (vpara->color_input == HDMI_COLOR_YCBCR422 &&
968 vpara->color_output != HDMI_COLOR_YCBCR422 &&
969 vpara->color_output != HDMI_COLOR_YCBCR420) {
971 hdmi_msk_reg(hdmi_dev, CSC_CFG,
972 m_CSC_INTPMODE, v_CSC_INTPMODE(interpolation));
975 if ((vpara->color_input == HDMI_COLOR_RGB_0_255 ||
976 vpara->color_input == HDMI_COLOR_YCBCR444) &&
977 vpara->color_output == HDMI_COLOR_YCBCR422) {
979 hdmi_msk_reg(hdmi_dev, CSC_CFG,
980 m_CSC_DECIMODE, v_CSC_DECIMODE(decimation));
983 switch (vpara->vic) {
984 case HDMI_720X480I_60HZ_4_3:
985 case HDMI_720X576I_50HZ_4_3:
986 case HDMI_720X480P_60HZ_4_3:
987 case HDMI_720X576P_50HZ_4_3:
988 case HDMI_720X480I_60HZ_16_9:
989 case HDMI_720X576I_50HZ_16_9:
990 case HDMI_720X480P_60HZ_16_9:
991 case HDMI_720X576P_50HZ_16_9:
992 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
993 vpara->color_output >= HDMI_COLOR_YCBCR444) {
994 mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
996 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
997 vpara->color_output == HDMI_COLOR_RGB_0_255) {
998 mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
1003 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
1004 vpara->color_output >= HDMI_COLOR_YCBCR444) {
1005 mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
1007 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
1008 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1009 mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
1015 if ((vpara->color_input == HDMI_COLOR_RGB_0_255) &&
1016 (vpara->color_output == HDMI_COLOR_RGB_16_235)) {
1017 mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
1021 switch (vpara->color_output_depth) {
1023 color_depth = COLOR_DEPTH_30BIT;
1027 color_depth = COLOR_DEPTH_36BIT;
1031 color_depth = COLOR_DEPTH_48BIT;
1036 color_depth = COLOR_DEPTH_24BIT;
1040 coeff = coeff_csc[mode];
1041 for (i = 0; i < 24; i++)
1042 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
1044 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1045 m_CSC_SCALE, v_CSC_SCALE(csc_scale));
1046 /*config CSC_COLOR_DEPTH*/
1047 hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1048 m_CSC_COLOR_DEPTH, v_CSC_COLOR_DEPTH(color_depth));
1051 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1052 m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1));
1058 static int hdmi_dev_detect_hotplug(struct hdmi *hdmi)
1060 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1061 u32 value = hdmi_readl(hdmi_dev, PHY_STAT0);
1063 HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value);
1065 if (value & m_PHY_HPD)
1066 return HDMI_HPD_ACTIVED;
1068 return HDMI_HPD_REMOVED;
1071 static int hdmi_dev_read_edid(struct hdmi *hdmi, int block, unsigned char *buff)
1073 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1074 int i = 0, n = 0, index = 0, ret = -1, trytime = 5;
1075 int offset = (block % 2) * 0x80;
1078 HDMIDBG("[%s] block %d\n", __func__, block);
1080 rockchip_hdmiv2_i2cm_reset(hdmi_dev);
1082 /* Set DDC I2C CLK which devided from DDC_CLK to 100KHz. */
1083 rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
1085 /* Enable I2C interrupt for reading edid */
1086 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);
1088 hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
1089 hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
1090 hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
1091 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
1092 for (trytime = 0; trytime < 5; trytime++) {
1093 hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
1094 /* enable extend sequential read operation */
1096 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1097 m_I2CM_RD8, v_I2CM_RD8(1));
1099 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1105 usleep_range(900, 1000);
1106 interrupt = hdmi_readl(hdmi_dev,
1109 hdmi_writel(hdmi_dev,
1110 IH_I2CM_STAT0, interrupt);
1113 (m_SCDC_READREQ | m_I2CM_DONE |
1118 if (interrupt & m_I2CM_DONE) {
1119 for (index = 0; index < 8; index++)
1120 buff[8 * n + index] =
1121 hdmi_readl(hdmi_dev,
1125 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
1130 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
1132 "[%s] edid read %d error\n",
1133 __func__, offset + 8 * n);
1138 "[%s] edid read error\n", __func__);
1144 /* Disable I2C interrupt */
1145 rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
1149 static void hdmi_dev_config_avi(struct hdmi_dev *hdmi_dev,
1150 struct hdmi_video *vpara)
1152 unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0;
1153 unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT;
1155 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(0));
1156 hdmi_msk_reg(hdmi_dev, IH_FC_STAT1,
1157 m_AVI_INFOFRAME, v_AVI_INFOFRAME(1));
1158 /* Set AVI infoFrame Data byte1 */
1159 if (vpara->color_output == HDMI_COLOR_YCBCR444)
1160 y1y0 = AVI_COLOR_MODE_YCBCR444;
1161 else if (vpara->color_output == HDMI_COLOR_YCBCR422)
1162 y1y0 = AVI_COLOR_MODE_YCBCR422;
1163 else if (vpara->color_output == HDMI_COLOR_YCBCR420)
1164 y1y0 = AVI_COLOR_MODE_YCBCR420;
1166 y1y0 = AVI_COLOR_MODE_RGB;
1168 hdmi_msk_reg(hdmi_dev, FC_AVICONF0,
1169 m_FC_ACTIV_FORMAT | m_FC_RGC_YCC,
1170 v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1));
1172 /* Set AVI infoFrame Data byte2 */
1173 switch (vpara->vic) {
1174 case HDMI_720X480I_60HZ_4_3:
1175 case HDMI_720X576I_50HZ_4_3:
1176 case HDMI_720X480P_60HZ_4_3:
1177 case HDMI_720X576P_50HZ_4_3:
1178 aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
1179 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1180 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1182 case HDMI_720X480I_60HZ_16_9:
1183 case HDMI_720X576I_50HZ_16_9:
1184 case HDMI_720X480P_60HZ_16_9:
1185 case HDMI_720X576P_50HZ_16_9:
1186 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1187 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1188 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1191 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1192 if (vpara->colorimetry == HDMI_COLORIMETRY_NO_DATA)
1193 colorimetry = AVI_COLORIMETRY_ITU709;
1196 if (vpara->colorimetry > HDMI_COLORIMETRY_ITU709) {
1197 colorimetry = AVI_COLORIMETRY_EXTENDED;
1198 ext_colorimetry = vpara->colorimetry;
1199 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235 ||
1200 vpara->color_output == HDMI_COLOR_RGB_0_255) {
1201 colorimetry = AVI_COLORIMETRY_NO_DATA;
1202 ext_colorimetry = 0;
1203 } else if (vpara->colorimetry != HDMI_COLORIMETRY_NO_DATA) {
1204 colorimetry = vpara->colorimetry;
1207 hdmi_writel(hdmi_dev, FC_AVICONF1,
1208 v_FC_COLORIMETRY(colorimetry) |
1209 v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
1210 v_FC_ACT_ASPEC_RATIO(ACTIVE_ASPECT_RATE_DEFAULT));
1212 /* Set AVI infoFrame Data byte3 */
1213 hdmi_msk_reg(hdmi_dev, FC_AVICONF2,
1214 m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE,
1215 v_FC_EXT_COLORIMETRY(ext_colorimetry) |
1216 v_FC_QUAN_RANGE(rgb_quan_range));
1218 /* Set AVI infoFrame Data byte4 */
1219 if ((vpara->vic > 92 && vpara->vic < 96) || (vpara->vic == 98))
1220 hdmi_writel(hdmi_dev, FC_AVIVID, 0);
1222 hdmi_writel(hdmi_dev, FC_AVIVID, vpara->vic & 0xff);
1223 /* Set AVI infoFrame Data byte5 */
1224 hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN,
1225 v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS));
1226 hdmi_msk_reg(hdmi_dev, FC_DATAUTO3, m_AVI_AUTO, v_AVI_AUTO(1));
1229 static int hdmi_dev_config_vsi(struct hdmi *hdmi,
1230 unsigned char vic_3d, unsigned char format)
1232 int i = 0, id = 0x000c03;
1233 unsigned char data[3] = {0};
1235 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1237 HDMIDBG("[%s] vic %d format %d.\n", __func__, vic_3d, format);
1239 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0));
1240 hdmi_writel(hdmi_dev, FC_VSDIEEEID2, id & 0xff);
1241 hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff);
1242 hdmi_writel(hdmi_dev, FC_VSDIEEEID0, (id >> 16) & 0xff);
1244 data[0] = format << 5; /* PB4 --HDMI_Video_Format */
1246 case HDMI_VIDEO_FORMAT_4KX2K:
1247 data[1] = vic_3d; /* PB5--HDMI_VIC */
1250 case HDMI_VIDEO_FORMAT_3D:
1251 data[1] = vic_3d << 4; /* PB5--3D_Structure field */
1252 data[2] = 0; /* PB6--3D_Ext_Data field */
1260 for (i = 0; i < 3; i++)
1261 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
1262 hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6);
1263 /* if (auto_send) { */
1264 hdmi_writel(hdmi_dev, FC_DATAUTO1, 0);
1265 hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11);
1266 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1));
1269 hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1));
1275 static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara)
1277 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1279 HDMIDBG("%s vic %d 3dformat %d color mode %d color depth %d\n",
1280 __func__, vpara->vic, vpara->format_3d,
1281 vpara->color_output, vpara->color_output_depth);
1283 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
1284 vpara->color_input = HDMI_COLOR_RGB_0_255;
1287 /* befor configure video, we power off phy */
1288 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1289 m_PDDQ_SIG | m_TXPWRON_SIG,
1290 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1292 /* force output blue */
1293 if (vpara->color_output == HDMI_COLOR_RGB_0_255) {
1294 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/
1295 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/
1296 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/
1297 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235) {
1298 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x10); /*R*/
1299 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/
1300 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10); /*B*/
1302 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80); /*R*/
1303 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10); /*G*/
1304 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80); /*B*/
1306 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1307 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1308 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1311 if (rockchip_hdmiv2_video_framecomposer(hdmi, vpara) < 0)
1314 if (rockchip_hdmiv2_video_packetizer(hdmi_dev, vpara) < 0)
1316 /* Color space convert */
1317 if (rockchip_hdmiv2_video_csc(hdmi_dev, vpara) < 0)
1319 if (rockchip_hdmiv2_video_sampler(hdmi_dev, vpara) < 0)
1322 if (vpara->sink_hdmi == OUTPUT_HDMI) {
1323 hdmi_dev_config_avi(hdmi_dev, vpara);
1324 if (vpara->format_3d != HDMI_3D_NONE) {
1325 hdmi_dev_config_vsi(hdmi,
1327 HDMI_VIDEO_FORMAT_3D);
1328 } else if ((vpara->vic > 92 && vpara->vic < 96) ||
1329 (vpara->vic == 98)) {
1330 vpara->vic = (vpara->vic == 98) ?
1331 4 : (96 - vpara->vic);
1332 hdmi_dev_config_vsi(hdmi,
1334 HDMI_VIDEO_FORMAT_4KX2K);
1336 hdmi_dev_config_vsi(hdmi,
1338 HDMI_VIDEO_FORMAT_NORMAL);
1340 dev_info(hdmi->dev, "[%s] sucess output HDMI.\n", __func__);
1342 dev_info(hdmi->dev, "[%s] sucess output DVI.\n", __func__);
1346 rockchip_hdmiv2_config_phy(hdmi_dev);
1348 hdmi_msk_reg(hdmi_dev, PHY_MASK, m_PHY_LOCK, v_PHY_LOCK(0));
1352 static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev,
1353 struct hdmi_audio *audio)
1355 /*Refer to CEA861-E Audio infoFrame*/
1356 /*Set both Audio Channel Count and Audio Coding
1357 Type Refer to Stream Head for HDMI*/
1358 hdmi_msk_reg(hdmi_dev, FC_AUDICONF0,
1359 m_FC_CHN_CNT | m_FC_CODING_TYEP,
1360 v_FC_CHN_CNT(audio->channel-1) | v_FC_CODING_TYEP(0));
1362 /*Set both Audio Sample Size and Sample Frequency
1363 Refer to Stream Head for HDMI*/
1364 hdmi_msk_reg(hdmi_dev, FC_AUDICONF1,
1365 m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ,
1366 v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
1368 /*Set Channel Allocation*/
1369 hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1371 /*Set LFEPBL¡¢DOWN-MIX INH and LSV*/
1372 hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1375 static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio)
1377 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1378 int word_length = 0, channel = 0, mclk_fs;
1379 unsigned int N = 0, CTS = 0;
1382 HDMIDBG("%s\n", __func__);
1384 if (audio->channel < 3)
1385 channel = I2S_CHANNEL_1_2;
1386 else if (audio->channel < 5)
1387 channel = I2S_CHANNEL_3_4;
1388 else if (audio->channel < 7)
1389 channel = I2S_CHANNEL_5_6;
1391 channel = I2S_CHANNEL_7_8;
1393 switch (audio->rate) {
1394 case HDMI_AUDIO_FS_32000:
1397 if (hdmi_dev->tmdsclk >= 594000000)
1399 else if (hdmi_dev->tmdsclk >= 297000000)
1403 /*div a num to avoid the value is exceed 2^32(int)*/
1404 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 32);
1406 case HDMI_AUDIO_FS_44100:
1409 if (hdmi_dev->tmdsclk >= 594000000)
1411 else if (hdmi_dev->tmdsclk >= 297000000)
1416 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 441);
1418 case HDMI_AUDIO_FS_48000:
1421 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1423 else if (hdmi_dev->tmdsclk >= 297000000)
1428 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 48);
1430 case HDMI_AUDIO_FS_88200:
1433 if (hdmi_dev->tmdsclk >= 594000000)
1435 else if (hdmi_dev->tmdsclk >= 297000000)
1440 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 882);
1442 case HDMI_AUDIO_FS_96000:
1445 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1447 else if (hdmi_dev->tmdsclk >= 297000000)
1452 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 96);
1454 case HDMI_AUDIO_FS_176400:
1457 if (hdmi_dev->tmdsclk >= 594000000)
1458 N = N_1764K_HIGHCLK;
1459 else if (hdmi_dev->tmdsclk >= 297000000)
1464 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 1764);
1466 case HDMI_AUDIO_FS_192000:
1469 if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
1471 else if (hdmi_dev->tmdsclk >= 297000000)
1476 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 192);
1479 dev_err(hdmi_dev->hdmi->dev,
1480 "[%s] not support such sample rate %d\n",
1481 __func__, audio->rate);
1485 switch (audio->word_length) {
1486 case HDMI_AUDIO_WORD_LENGTH_16bit:
1487 word_length = I2S_16BIT_SAMPLE;
1489 case HDMI_AUDIO_WORD_LENGTH_20bit:
1490 word_length = I2S_20BIT_SAMPLE;
1492 case HDMI_AUDIO_WORD_LENGTH_24bit:
1493 word_length = I2S_24BIT_SAMPLE;
1496 word_length = I2S_16BIT_SAMPLE;
1499 HDMIDBG("rate = %d, tmdsclk = %u, N = %d, CTS = %d\n",
1500 audio->rate, hdmi_dev->tmdsclk, N, CTS);
1501 /* more than 2 channels => layout 1 else layout 0 */
1502 hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1504 v_AUD_PACK_LAYOUT((audio->channel > 2) ? 1 : 0));
1506 if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_SPDIF) {
1508 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1509 m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA));
1510 hdmi_msk_reg(hdmi_dev, AUD_SPDIF1,
1511 m_SET_NLPCM | m_SPDIF_WIDTH,
1512 v_SET_NLPCM(PCM_LINEAR) |
1513 v_SPDIF_WIDTH(word_length));
1514 /*Mask fifo empty and full int and reset fifo*/
1515 hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT,
1516 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1517 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1518 hdmi_msk_reg(hdmi_dev, AUD_SPDIF0,
1519 m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1));
1521 /*Mask fifo empty and full int and reset fifo*/
1522 hdmi_msk_reg(hdmi_dev, AUD_INT,
1523 m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1524 v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1525 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1526 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1527 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1528 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
1529 usleep_range(90, 100);
1530 if (I2S_CHANNEL_7_8 == channel) {
1531 HDMIDBG("hbr mode.\n");
1532 hdmi_writel(hdmi_dev, AUD_CONF2, 0x1);
1533 word_length = I2S_24BIT_SAMPLE;
1534 } else if ((HDMI_AUDIO_FS_48000 == audio->rate) ||
1535 (HDMI_AUDIO_FS_192000 == audio->rate)) {
1536 HDMIDBG("nlpcm mode.\n");
1537 hdmi_writel(hdmi_dev, AUD_CONF2, 0x2);
1538 word_length = I2S_24BIT_SAMPLE;
1540 hdmi_writel(hdmi_dev, AUD_CONF2, 0x0);
1542 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1543 m_I2S_SEL | m_I2S_IN_EN,
1544 v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
1545 hdmi_writel(hdmi_dev, AUD_CONF1,
1546 v_I2S_MODE(I2S_STANDARD_MODE) |
1547 v_I2S_WIDTH(word_length));
1550 hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS,
1551 m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs));
1554 hdmi_msk_reg(hdmi_dev, AUD_N3, m_NCTS_ATOMIC_WR, v_NCTS_ATOMIC_WR(1));
1555 /*Set CTS by manual*/
1556 hdmi_msk_reg(hdmi_dev, AUD_CTS3,
1557 m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
1558 v_N_SHIFT(N_SHIFT_1) |
1560 v_AUD_CTS3(CTS >> 16));
1561 hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
1562 hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
1564 hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
1565 hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
1566 hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
1568 /* set channel status register */
1569 hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7,
1570 m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate));
1571 hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2);
1573 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1574 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1576 hdmi_dev_config_aai(hdmi_dev, audio);
1581 static int hdmi_dev_control_output(struct hdmi *hdmi, int enable)
1583 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1584 struct hdmi_video vpara;
1586 HDMIDBG("[%s] %d\n", __func__, enable);
1587 if (enable == HDMI_AV_UNMUTE) {
1588 hdmi_writel(hdmi_dev, FC_DBGFORCE, 0x00);
1589 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI)
1590 hdmi_msk_reg(hdmi_dev, FC_GCP,
1591 m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE,
1592 v_FC_SET_AVMUTE(0) | v_FC_CLR_AVMUTE(1));
1594 if (enable & HDMI_VIDEO_MUTE) {
1595 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1596 m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1597 if (hdmi->edid.sink_hdmi == OUTPUT_HDMI) {
1598 hdmi_msk_reg(hdmi_dev, FC_GCP,
1601 v_FC_SET_AVMUTE(1) |
1602 v_FC_CLR_AVMUTE(0));
1603 vpara.vic = hdmi->vic;
1604 vpara.color_output = HDMI_COLOR_RGB_0_255;
1605 hdmi_dev_config_avi(hdmi_dev, &vpara);
1606 while ((!hdmi_readl(hdmi_dev, IH_FC_STAT1)) &
1608 usleep_range(900, 1000);
1612 /* if (enable & HDMI_AUDIO_MUTE) {
1613 hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1615 v_AUD_PACK_SAMPFIT(0x0F));
1617 */ if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) {
1618 if (hdmi->ops->hdcp_power_off_cb)
1619 hdmi->ops->hdcp_power_off_cb(hdmi);
1620 rockchip_hdmiv2_powerdown(hdmi_dev);
1622 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1623 m_PDDQ_SIG | m_TXPWRON_SIG,
1624 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1625 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
1631 static int hdmi_dev_insert(struct hdmi *hdmi)
1633 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1635 HDMIDBG("%s\n", __func__);
1637 hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1638 return HDMI_ERROR_SUCESS;
1641 static int hdmi_dev_remove(struct hdmi *hdmi)
1643 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1645 HDMIDBG("%s\n", __func__);
1646 if (hdmi->ops->hdcp_power_off_cb)
1647 hdmi->ops->hdcp_power_off_cb(hdmi);
1648 rockchip_hdmiv2_powerdown(hdmi_dev);
1649 hdmi_dev->tmdsclk = 0;
1650 return HDMI_ERROR_SUCESS;
1653 static int hdmi_dev_enable(struct hdmi *hdmi)
1655 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1657 HDMIDBG("%s\n", __func__);
1658 if (!hdmi_dev->enable) {
1659 hdmi_writel(hdmi_dev, IH_MUTE, 0x00);
1660 hdmi_dev->enable = 1;
1662 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 10, 0);
1666 static int hdmi_dev_disable(struct hdmi *hdmi)
1668 struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1670 HDMIDBG("%s\n", __func__);
1671 if (hdmi_dev->enable) {
1672 hdmi_dev->enable = 0;
1673 hdmi_writel(hdmi_dev, IH_MUTE, 0x1);
1678 void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops)
1681 ops->enable = hdmi_dev_enable;
1682 ops->disable = hdmi_dev_disable;
1683 ops->getstatus = hdmi_dev_detect_hotplug;
1684 ops->insert = hdmi_dev_insert;
1685 ops->remove = hdmi_dev_remove;
1686 ops->getedid = hdmi_dev_read_edid;
1687 ops->setvideo = hdmi_dev_config_video;
1688 ops->setaudio = hdmi_dev_config_audio;
1689 ops->setmute = hdmi_dev_control_output;
1690 ops->setvsi = hdmi_dev_config_vsi;
1694 void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev)
1696 struct hdmi *hdmi = hdmi_dev->hdmi;
1700 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
1701 writel_relaxed((1 << 9) | (1 << 25),
1702 RK_CRU_VIRT + 0x01d4);
1704 writel_relaxed((0 << 9) | (1 << 25),
1705 RK_CRU_VIRT + 0x01d4);
1706 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
1707 pr_info("reset hdmi\n");
1708 regmap_write(hdmi_dev->grf_base, 0x031c,
1709 (1 << 9) | (1 << 25));
1711 regmap_write(hdmi_dev->grf_base, 0x031c,
1712 (0 << 9) | (1 << 25));
1714 rockchip_hdmiv2_powerdown(hdmi_dev);
1716 /*mute unnecessary interrrupt, only enable hpd*/
1717 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff);
1718 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT1, 0xff);
1719 hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT2, 0xff);
1720 hdmi_writel(hdmi_dev, IH_MUTE_AS_STAT0, 0xff);
1721 hdmi_writel(hdmi_dev, IH_MUTE_PHY_STAT0, 0xfc);
1722 hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, 0xff);
1723 hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, 0xff);
1724 hdmi_writel(hdmi_dev, IH_MUTE_VP_STAT0, 0xff);
1725 hdmi_writel(hdmi_dev, IH_MUTE_I2CMPHY_STAT0, 0xff);
1726 hdmi_writel(hdmi_dev, IH_MUTE_AHBDMAAUD_STAT0, 0xff);
1728 /* disable hdcp interrup */
1729 hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff);
1730 hdmi_writel(hdmi_dev, PHY_MASK, 0xf1);
1732 if (hdmi->property->feature & SUPPORT_CEC)
1733 rockchip_hdmiv2_cec_init(hdmi);
1734 if (hdmi->property->feature & SUPPORT_HDCP)
1735 rockchip_hdmiv2_hdcp_init(hdmi);
1738 irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv)
1740 struct hdmi_dev *hdmi_dev = priv;
1741 struct hdmi *hdmi = hdmi_dev->hdmi;
1742 char phy_pol = hdmi_readl(hdmi_dev, PHY_POL0);
1743 char phy_status = hdmi_readl(hdmi_dev, PHY_STAT0);
1744 char phy_int0 = hdmi_readl(hdmi_dev, PHY_INI0);
1746 char fc_stat0 = hdmi_readl(hdmi_dev, IH_FC_STAT0);
1747 char fc_stat1 = hdmi_readl(hdmi_dev, IH_FC_STAT1);
1748 char fc_stat2 = hdmi_readl(hdmi_dev, IH_FC_STAT2);
1749 char aud_int = hdmi_readl(hdmi_dev, IH_AS_SATA0);
1750 char phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0);
1751 char vp_stat0 = hdmi_readl(hdmi_dev, IH_VP_STAT0);
1752 char cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0);
1753 char hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
1754 char hdcp2_int = hdmi_readl(hdmi_dev, HDCP2REG_STAT);
1757 hdmi_writel(hdmi_dev, IH_FC_STAT0, fc_stat0);
1758 hdmi_writel(hdmi_dev, IH_FC_STAT1, fc_stat1);
1759 hdmi_writel(hdmi_dev, IH_FC_STAT2, fc_stat2);
1760 hdmi_writel(hdmi_dev, IH_VP_STAT0, vp_stat0);
1762 if (phy_int0 || phy_int) {
1763 if ((phy_int0 & m_PHY_LOCK) &&
1764 (phy_pol & m_PHY_LOCK) == 0) {
1765 pr_info("hdmi phy pll unlock\n");
1766 hdmi_submit_work(hdmi, HDMI_SET_VIDEO, 0, 0);
1768 phy_pol = (phy_int0 & (~phy_status)) | ((~phy_int0) & phy_pol);
1769 hdmi_writel(hdmi_dev, PHY_POL0, phy_pol);
1770 hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int);
1771 if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c))
1772 hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, 0);
1777 hdmi_writel(hdmi_dev, IH_AS_SATA0, aud_int);
1778 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1779 m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1780 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1784 hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int);
1785 rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int);
1789 hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
1790 rockchip_hdmiv2_hdcp_isr(hdmi_dev, hdcp_int);
1795 hdmi_writel(hdmi_dev, HDCP2REG_STAT, hdcp2_int);
1796 pr_info("hdcp2_int is 0x%02x\n", hdcp2_int);
1797 if ((hdcp2_int & m_HDCP2_AUTH_FAIL ||
1798 hdcp2_int & m_HDCP2_AUTH_LOST) &&
1799 hdmi_dev->hdcp2_start) {
1800 pr_info("hdcp2 failed or lost\n");
1801 hdmi_dev->hdcp2_start();