1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Zheng Yang <zhengyang@rock-chips.com>
5 * Yakir Yang <ykk@rock-chips.com>
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/hdmi.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/of_device.h>
17 #include <linux/component.h>
18 #include <linux/reset.h>
19 #include <drm/drm_scdc_helper.h>
20 #include <drm/bridge/dw_hdmi.h>
21 #include <drm/drm_atomic_helper.h>
22 #include <drm/drm_edid.h>
23 #include <drm/drm_of.h>
24 #include <drm/drm_probe_helper.h>
25 #include <drm/drm_simple_kms_helper.h>
26 #include <linux/regulator/consumer.h>
30 #include "inno_hdmi.h"
32 #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
34 struct hdmi_data_info {
38 unsigned int enc_in_format;
39 unsigned int enc_out_format;
40 unsigned int colorimetry;
43 struct inno_hdmi_i2c {
44 struct i2c_adapter adap;
50 struct completion cmp;
55 struct drm_device *drm_dev;
62 struct reset_control *tx_rst;
65 struct drm_connector connector;
66 struct drm_encoder encoder;
68 struct inno_hdmi_i2c *i2c;
69 struct i2c_adapter *ddc;
71 unsigned long tmds_rate;
73 struct hdmi_data_info hdmi_data;
74 struct drm_display_mode previous_mode;
75 struct regulator *hdmi_1p8;
76 struct regulator *hdmi_0p9;
77 const struct pre_pll_config *pre_cfg;
78 const struct post_pll_config *post_cfg;
82 CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
83 CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
84 CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
85 CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
86 CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
87 CSC_RGB_0_255_TO_RGB_16_235_8BIT,
90 static const struct pre_pll_config pre_pll_cfg_table[] = {
91 { 25175000, 25175000, 1, 100, 2, 3, 3, 12, 3, 3, 4, 0, 0},
92 { 25200000, 25200000, 1, 100, 2, 3, 3, 12, 3, 3, 4, 0, 0},
93 { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
94 { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
95 { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0},
96 { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B},
97 { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0},
98 { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B},
99 { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0},
100 { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B},
101 { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0},
102 { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817},
103 { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0},
104 {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B},
105 {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0},
106 {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817},
107 {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0},
108 {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B},
109 {297000000, 297000000, 1, 99, 1, 0, 0, 1, 2, 1, 1, 0, 0},
110 {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817},
111 {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0},
112 {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B},
113 {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0},
114 {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817},
115 {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
116 {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
117 {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
121 static const struct post_pll_config post_pll_cfg_table[] = {
122 {25200000, 1, 80, 7, 3, 1},
123 {27000000, 1, 40, 11, 3, 1},
124 {33750000, 1, 40, 8, 3, 1},
125 //{33750000, 1, 80, 8, 2},
126 {74250000, 1, 20, 1, 3, 1},
127 //{74250000, 18, 80, 8, 2},
128 {148500000, 1, 20, 1, 3, 3},
129 {297000000, 4, 20, 0, 0, 3},
130 {594000000, 4, 20, 0, 0, 0},//postpll_postdiv_en = 0
134 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
136 return readl_relaxed(hdmi->regs + (offset) * 0x04);
139 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val)
141 writel_relaxed(val, hdmi->regs + (offset) * 0x04);
144 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
147 u8 temp = hdmi_readb(hdmi, offset) & ~msk;
150 hdmi_writeb(hdmi, offset, temp);
153 static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
157 val = readl_relaxed(hdmi->regs + (0x1b0) * 0x04);
159 writel_relaxed(val, hdmi->regs + (0x1b0) * 0x04);
160 writel_relaxed(0xf, hdmi->regs + (0x1cc) * 0x04);
163 val = readl_relaxed(hdmi->regs + (0x1a0) * 0x04);
165 writel_relaxed(val, hdmi->regs + (0x1a0) * 0x04);
167 val = readl_relaxed(hdmi->regs + (0x1aa) * 0x04);
169 writel_relaxed(val, hdmi->regs + (0x1aa) * 0x04);
171 while (!(readl_relaxed(hdmi->regs + (0x1a9) * 0x04) & 0x1))
173 while (!(readl_relaxed(hdmi->regs + (0x1af) * 0x04) & 0x1))
177 writel_relaxed(0x7, hdmi->regs + (0x1b4) * 0x04);
178 /*turn on serializer*/
179 writel_relaxed(0x70, hdmi->regs + (0x1be) * 0x04);
182 static void inno_hdmi_tx_phy_power_down(struct inno_hdmi *hdmi)
184 hdmi_writeb(hdmi, 0x00, 0x63);
187 static void inno_hdmi_config_pll(struct inno_hdmi *hdmi)
189 u8 reg_1ad_value = hdmi->post_cfg->post_div_en ?
190 hdmi->post_cfg->postdiv : 0x00;
191 u8 reg_1aa_value = hdmi->post_cfg->post_div_en ?
193 if(1 == hdmi->hdmi_data.vic){
194 reg_1ad_value = 0x0d;
197 const reg_value_t cfg_pll_data[] = {
200 {0x1a1, hdmi->pre_cfg->prediv},
201 {0x1a2, 0xf0 | hdmi->pre_cfg->fbdiv>>8},
202 {0x1a3, hdmi->pre_cfg->fbdiv},
203 {0x1a4, ((hdmi->pre_cfg->tmds_div_a << 4) | (hdmi->pre_cfg->tmds_div_b << 2) | (hdmi->pre_cfg->tmds_div_c))},
204 {0x1a5, (hdmi->pre_cfg->pclk_div_b << 5) | hdmi->pre_cfg->pclk_div_a},
205 {0x1a6, (hdmi->pre_cfg->pclk_div_c << 5) | hdmi->pre_cfg->pclk_div_d},
206 {0x1ab, hdmi->post_cfg->prediv},
207 {0x1ac, hdmi->post_cfg->fbdiv & 0xff},
208 {0x1ad, reg_1ad_value},
209 {0x1aa, reg_1aa_value},
214 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++)
216 //dev_info(hdmi->dev, "%s %d reg[%02x],val[%02x]\n",__func__, __LINE__,cfg_pll_data[i].reg,cfg_pll_data[i].value);
217 //writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
218 hdmi_writeb(hdmi, cfg_pll_data[i].reg, cfg_pll_data[i].value);
223 static void inno_hdmi_config_1920x1080p60(struct inno_hdmi *hdmi)
226 const reg_value_t cfg_pll_data[] = {
227 /* config pll: 1080p, 60hz*/
244 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++)
245 writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
250 static void inno_hdmi_tx_ctrl(struct inno_hdmi *hdmi)
252 hdmi_writeb(hdmi, 0x9f, 0x06);
253 hdmi_writeb(hdmi, 0xa7, hdmi->hdmi_data.vic);
256 static void inno_hdmi_tx_phy_param_config(struct inno_hdmi *hdmi)
258 inno_hdmi_config_1920x1080p60(hdmi);
259 inno_hdmi_tx_ctrl(hdmi);
262 static void inno_hdmi_tx_phy_power_on(struct inno_hdmi *hdmi)
264 const reg_value_t pwon_data[] = {
268 for (i = 0; i < sizeof(pwon_data)/sizeof(reg_value_t); i++) {
269 //writel_relaxed(pwon_data[i].value, hdmi->regs + (pwon_data[i].reg) * 0x04);
270 hdmi_writeb(hdmi, pwon_data[i].reg, pwon_data[i].value);
275 void inno_hdmi_tmds_driver_on(struct inno_hdmi *hdmi)
277 //writel_relaxed(0x8f, hdmi->regs + (0x1b2) * 0x04);
278 hdmi_writeb(hdmi, 0x1b2, 0x8f);
282 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
286 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
288 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
289 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
291 /* Clear the EDID interrupt flag and mute the interrupt */
292 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
293 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
296 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
299 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
301 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
304 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
308 inno_hdmi_sys_power(hdmi, true);
312 inno_hdmi_sys_power(hdmi, false);
316 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
320 static void inno_hdmi_init(struct inno_hdmi *hdmi)
322 inno_hdmi_power_up(hdmi);
323 inno_hdmi_tx_phy_power_down(hdmi);
324 inno_hdmi_tx_phy_param_config(hdmi);
326 inno_hdmi_tx_phy_power_on(hdmi);
327 inno_hdmi_tmds_driver_on(hdmi);
329 writel_relaxed(0x0, hdmi->regs + (0xce) * 0x04);
330 writel_relaxed(0x1, hdmi->regs + (0xce) * 0x04);
334 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
340 val = v_INT_POL_HIGH;
341 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
343 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
346 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
349 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
353 struct pre_pll_config *inno_hdmi_phy_get_pre_pll_cfg(struct inno_hdmi *hdmi,
356 const struct pre_pll_config *cfg = pre_pll_cfg_table;
357 rate = (rate / 1000) * 1000;
359 for (; cfg->pixclock != 0; cfg++)
360 if (cfg->tmdsclock == rate && cfg->pixclock == rate)
363 if (cfg->pixclock == 0)
364 return ERR_PTR(-EINVAL);
369 #define PRE_PLL_POWER_DOWN BIT(0)
371 /* phy tuning values for an undocumented set of registers */
372 static const struct phy_config inno_phy_cfg[] = {
374 0x07, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x08, 0x08,
375 0x00, 0xac, 0xcc, 0xcc, 0xcc,
379 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
380 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
384 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
385 0x00, 0xac, 0xcc, 0xcc, 0xcc,
387 }, { /* sentinel */ },
390 static int inno_hdmi_phy_clk_set_rate(struct inno_hdmi *hdmi,unsigned long rate)
392 unsigned long tmdsclock;
393 hdmi->post_cfg = post_pll_cfg_table;
395 tmdsclock = hdmi->tmds_rate;
396 dev_info(hdmi->dev, "%s rate %lu tmdsclk %lu\n",__func__, rate, tmdsclock);
398 hdmi->pre_cfg = inno_hdmi_phy_get_pre_pll_cfg(hdmi, tmdsclock);
399 if (IS_ERR(hdmi->pre_cfg))
400 return PTR_ERR(hdmi->pre_cfg);
402 for (; hdmi->post_cfg->tmdsclock != 0; hdmi->post_cfg++)
403 if (tmdsclock <= hdmi->post_cfg->tmdsclock)
406 dev_info(hdmi->dev, "%s hdmi->pre_cfg->pixclock = %lu\n",__func__, hdmi->pre_cfg->pixclock);
407 dev_info(hdmi->dev, "%s hdmi->pre_cfg->tmdsclock = %lu\n",__func__, hdmi->pre_cfg->tmdsclock);
408 dev_info(hdmi->dev, "%s hdmi->pre_cfg->prediv = %d\n",__func__, hdmi->pre_cfg->prediv);
409 dev_info(hdmi->dev, "%s hdmi->pre_cfg->fbdiv = %d\n",__func__, hdmi->pre_cfg->fbdiv);
410 dev_info(hdmi->dev, "%s hdmi->pre_cfg->tmds_div_a = %d\n",__func__, hdmi->pre_cfg->tmds_div_a);
411 dev_info(hdmi->dev, "%s hdmi->pre_cfg->tmds_div_b = %d\n",__func__, hdmi->pre_cfg->tmds_div_b);
412 dev_info(hdmi->dev, "%s hdmi->pre_cfg->tmds_div_c = %d\n",__func__, hdmi->pre_cfg->tmds_div_c);
413 dev_info(hdmi->dev, "%s hdmi->pre_cfg->pclk_div_a = %d\n",__func__, hdmi->pre_cfg->pclk_div_a);
414 dev_info(hdmi->dev, "%s hdmi->pre_cfg->pclk_div_b = %d\n",__func__, hdmi->pre_cfg->pclk_div_b);
415 dev_info(hdmi->dev, "%s hdmi->pre_cfg->pclk_div_c = %d\n",__func__, hdmi->pre_cfg->pclk_div_c);
416 dev_info(hdmi->dev, "%s hdmi->pre_cfg->pclk_div_d = %d\n",__func__, hdmi->pre_cfg->pclk_div_d);
417 dev_info(hdmi->dev, "%s hdmi->pre_cfg->vco_div_5_en = %d\n",__func__, hdmi->pre_cfg->vco_div_5_en);
418 dev_info(hdmi->dev, "%s hdmi->pre_cfg->fracdiv = %d\n",__func__, hdmi->pre_cfg->fracdiv);
421 dev_info(hdmi->dev, "*******************************************************\n");
423 dev_info(hdmi->dev, "%s hdmi->post_cfg->tmdsclock = %lu\n",__func__, hdmi->post_cfg->tmdsclock);
424 dev_info(hdmi->dev, "%s hdmi->post_cfg->prediv = %d\n",__func__, hdmi->post_cfg->prediv);
425 dev_info(hdmi->dev, "%s hdmi->post_cfg->fbdiv = %d\n",__func__, hdmi->post_cfg->fbdiv);
426 dev_info(hdmi->dev, "%s hdmi->post_cfg->postdiv = %d\n",__func__, hdmi->post_cfg->postdiv);
427 dev_info(hdmi->dev, "%s hdmi->post_cfg->post_div_en = %d\n",__func__, hdmi->post_cfg->post_div_en);
428 dev_info(hdmi->dev, "%s hdmi->post_cfg->version = %d\n",__func__, hdmi->post_cfg->version);
430 inno_hdmi_config_pll(hdmi);
431 //inno_hdmi_tx_ctrl(hdmi);
433 #if 0 //pre pll + post pll configire
435 /*pre-pll power down*/
436 hdmi_modb(hdmi, 0x1a0, INNO_PRE_PLL_POWER_DOWN, INNO_PRE_PLL_POWER_DOWN);
438 /* Configure pre-pll */
439 hdmi_modb(hdmi, 0x1a0, INNO_PCLK_VCO_DIV_5_MASK, INNO_PCLK_VCO_DIV_5(hdmi->pre_cfg->vco_div_5_en));
440 hdmi_writeb(hdmi, 0x1a1, INNO_PRE_PLL_PRE_DIV(hdmi->pre_cfg->prediv));
443 val = INNO_SPREAD_SPECTRUM_MOD_DISABLE;
444 if (!hdmi->pre_cfg->fracdiv)
445 val |= INNO_PRE_PLL_FRAC_DIV_DISABLE;
446 hdmi_writeb(hdmi, 0x1a2, INNO_PRE_PLL_FB_DIV_11_8(hdmi->pre_cfg->fbdiv | val));
448 hdmi_writeb(hdmi, 0x1a3, INNO_PRE_PLL_FB_DIV_7_0(hdmi->pre_cfg->fbdiv));
450 hdmi_writeb(hdmi, 0x1a5, INNO_PRE_PLL_PCLK_DIV_A(hdmi->pre_cfg->pclk_div_a) |
451 INNO_PRE_PLL_PCLK_DIV_B(hdmi->pre_cfg->pclk_div_b));
453 hdmi_writeb(hdmi, 0x1a6, INNO_PRE_PLL_PCLK_DIV_C(hdmi->pre_cfg->pclk_div_c) |
454 INNO_PRE_PLL_PCLK_DIV_D(hdmi->pre_cfg->pclk_div_d));
456 hdmi_writeb(hdmi, 0x1a4, INNO_PRE_PLL_TMDSCLK_DIV_C(hdmi->pre_cfg->tmds_div_c) |
457 INNO_PRE_PLL_TMDSCLK_DIV_A(hdmi->pre_cfg->tmds_div_a) |
458 INNO_PRE_PLL_TMDSCLK_DIV_B(hdmi->pre_cfg->tmds_div_b));
460 hdmi_writeb(hdmi, 0x1d3, INNO_PRE_PLL_FRAC_DIV_7_0(hdmi->pre_cfg->fracdiv));
461 hdmi_writeb(hdmi, 0x1d2, INNO_PRE_PLL_FRAC_DIV_15_8(hdmi->pre_cfg->fracdiv));
462 hdmi_writeb(hdmi, 0x1d1, INNO_PRE_PLL_FRAC_DIV_23_16(hdmi->pre_cfg->fracdiv));
464 /*pre-pll power down*/
465 hdmi_modb(hdmi, 0x1a0, INNO_PRE_PLL_POWER_DOWN, 0);
467 const struct phy_config *phy_cfg = inno_phy_cfg;
469 for (; phy_cfg->tmdsclock != 0; phy_cfg++)
470 if (tmdsclock <= phy_cfg->tmdsclock)
473 hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POWER_DOWN, INNO_POST_PLL_POWER_DOWN);
475 hdmi_writeb(hdmi, 0x1ac, INNO_POST_PLL_FB_DIV_7_0(hdmi->post_cfg->fbdiv));
477 if (hdmi->post_cfg->postdiv == 1) {
478 hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_REFCLK_SEL_TMDS, INNO_POST_PLL_REFCLK_SEL_TMDS);
479 hdmi_modb(hdmi, 0x1aa, BIT(4), INNO_POST_PLL_FB_DIV_8(hdmi->post_cfg->fbdiv));
480 hdmi_modb(hdmi, 0x1ab, INNO_POST_PLL_Pre_DIV_MASK, INNO_POST_PLL_PRE_DIV(hdmi->post_cfg->prediv));
482 v = (hdmi->post_cfg->postdiv / 2) - 1;
483 v &= INNO_POST_PLL_POST_DIV_MASK;
484 hdmi_modb(hdmi, 0x1ad, INNO_POST_PLL_POST_DIV_MASK, v);
485 hdmi_modb(hdmi, 0x1aa, BIT(4), INNO_POST_PLL_FB_DIV_8(hdmi->post_cfg->fbdiv));
486 hdmi_modb(hdmi, 0x1ab, INNO_POST_PLL_Pre_DIV_MASK, INNO_POST_PLL_PRE_DIV(hdmi->post_cfg->prediv));
487 hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_REFCLK_SEL_TMDS, INNO_POST_PLL_REFCLK_SEL_TMDS);
488 hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POST_DIV_ENABLE, INNO_POST_PLL_POST_DIV_ENABLE);
491 for (v = 0; v < 14; v++){
492 hdmi_writeb(hdmi, 0x1b5 + v, phy_cfg->regs[v]);
495 if (phy_cfg->tmdsclock > 340000000) {
496 /* Set termination resistor to 100ohm */
497 v = clk_get_rate(hdmi->sys_clk) / 100000;
499 hdmi_writeb(hdmi, 0x1c5, INNO_TERM_RESISTOR_CALIB_SPEED_14_8(v)
500 | INNO_BYPASS_TERM_RESISTOR_CALIB);
502 hdmi_writeb(hdmi, 0x1c6, INNO_TERM_RESISTOR_CALIB_SPEED_7_0(v));
503 hdmi_writeb(hdmi, 0x1c7, INNO_TERM_RESISTOR_100);
504 hdmi_modb(hdmi, 0x1c5, INNO_BYPASS_TERM_RESISTOR_CALIB, 0);
506 hdmi_writeb(hdmi, 0x1c5, INNO_BYPASS_TERM_RESISTOR_CALIB);
508 /* clk termination resistor is 50ohm (parallel resistors) */
509 if (phy_cfg->tmdsclock > 165000000){
510 hdmi_modb(hdmi, 0x1c8,
511 INNO_ESD_DETECT_MASK,
512 INNO_TERM_RESISTOR_200);
514 /* data termination resistor for D2, D1 and D0 is 150ohm */
515 for (v = 0; v < 3; v++){
516 hdmi_modb(hdmi, 0x1c9 + v,
517 INNO_ESD_DETECT_MASK,
518 INNO_TERM_RESISTOR_200);
522 hdmi_modb(hdmi, 0x1aa, INNO_POST_PLL_POWER_DOWN, 0);
529 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
530 struct drm_display_mode *mode)
534 val = readl_relaxed(hdmi->regs + (0x1b0) * 0x04);
536 hdmi_writeb(hdmi, 0x1b0, val);
537 hdmi_writeb(hdmi, 0x1cc, 0xf);
538 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
540 hdmi->tmds_rate = mode->clock * 1000;
541 inno_hdmi_phy_clk_set_rate(hdmi,hdmi->tmds_rate);
543 while (!(hdmi_readb(hdmi, 0x1a9) & 0x1))
545 while (!(hdmi_readb(hdmi, 0x1af) & 0x1))
549 hdmi_writeb(hdmi, 0x1b4, 0x7);
550 /*turn on serializer*/
551 hdmi_writeb(hdmi, 0x1be, 0x70);
552 inno_hdmi_tx_phy_power_down(hdmi);
554 inno_hdmi_tx_ctrl(hdmi);
556 hdmi_writeb(hdmi, 0x35, 0x01);
557 hdmi_writeb(hdmi, 0x38, 0x04);
558 hdmi_writeb(hdmi, 0x40, 0x18);
559 hdmi_writeb(hdmi, 0x41, 0x80);
561 inno_hdmi_tx_phy_power_on(hdmi);
562 inno_hdmi_tmds_driver_on(hdmi);
564 hdmi_writeb(hdmi, 0xce, 0x0);
565 hdmi_writeb(hdmi, 0xce, 0x1);
570 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
571 struct drm_display_mode *mode,
572 struct drm_display_mode *adj_mode)
574 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
576 inno_hdmi_setup(hdmi, adj_mode);
578 /* Store the display mode for plugin/DPMS poweron events */
579 memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
582 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
584 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
586 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
589 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
591 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
593 hdmi_modb(hdmi, 0x1b2, 0xf, 0);
594 hdmi_modb(hdmi, 0x1be, 0xf, 0);
595 hdmi_modb(hdmi, 0x1b4, 0xf, 0);
596 hdmi_modb(hdmi, 0x1a0, 1, 1);
597 hdmi_modb(hdmi, 0x1aa, 1, 1);
598 hdmi_modb(hdmi, 0x1cc, 0x0f, 0);
599 hdmi_modb(hdmi, 0x1b0, 1<<2, 0);
601 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
604 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
605 const struct drm_display_mode *mode,
606 struct drm_display_mode *adj_mode)
612 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
613 struct drm_crtc_state *crtc_state,
614 struct drm_connector_state *conn_state)
619 static const struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
620 .enable = inno_hdmi_encoder_enable,
621 .disable = inno_hdmi_encoder_disable,
622 .mode_fixup = inno_hdmi_encoder_mode_fixup,
623 .mode_set = inno_hdmi_encoder_mode_set,
624 .atomic_check = inno_hdmi_encoder_atomic_check,
627 static enum drm_connector_status
628 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
630 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
632 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
633 connector_status_connected : connector_status_disconnected;
636 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
638 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
645 edid = drm_get_edid(connector, hdmi->ddc);
647 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
648 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
649 drm_connector_update_edid_property(connector, edid);
650 ret = drm_add_edid_modes(connector, edid);
657 static const struct dw_hdmi_mpll_config starfive_mpll_cfg[] = {
743 static enum drm_mode_status
744 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
745 struct drm_display_mode *mode)
748 const struct dw_hdmi_mpll_config *mpll_cfg = starfive_mpll_cfg;
749 int pclk = mode->clock * 1000;
753 for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
754 if (pclk == mpll_cfg[i].mpixelclock) {
760 return (valid) ? MODE_OK : MODE_BAD;
762 u32 vic = drm_match_cea_mode(mode);
773 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
774 uint32_t maxX, uint32_t maxY)
776 return drm_helper_probe_single_connector_modes(connector, 3840, 2160);//3840x2160
779 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
781 drm_connector_unregister(connector);
782 drm_connector_cleanup(connector);
785 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
786 .fill_modes = inno_hdmi_probe_single_connector_modes,
787 .detect = inno_hdmi_connector_detect,
788 .destroy = inno_hdmi_connector_destroy,
789 .reset = drm_atomic_helper_connector_reset,
790 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
791 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
794 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
795 .get_modes = inno_hdmi_connector_get_modes,
796 .mode_valid = inno_hdmi_connector_mode_valid,
799 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
801 struct drm_encoder *encoder = &hdmi->encoder;
802 struct device *dev = hdmi->dev;
804 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
807 * If we failed to find the CRTC(s) which this encoder is
808 * supposed to be connected to, it's because the CRTC has
809 * not been registered yet. Defer probing, and hope that
810 * the required CRTC is added later.
812 if (encoder->possible_crtcs == 0)
813 return -EPROBE_DEFER;
815 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
816 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
818 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
820 drm_connector_helper_add(&hdmi->connector,
821 &inno_hdmi_connector_helper_funcs);
822 drm_connector_init_with_ddc(drm, &hdmi->connector,
823 &inno_hdmi_connector_funcs,
824 DRM_MODE_CONNECTOR_HDMIA,
827 drm_connector_attach_encoder(&hdmi->connector, encoder);
832 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
834 struct inno_hdmi_i2c *i2c = hdmi->i2c;
837 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
838 if (!(stat & m_INT_EDID_READY))
841 /* Clear HDMI EDID interrupt flag */
842 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
849 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
851 struct inno_hdmi *hdmi = dev_id;
852 irqreturn_t ret = IRQ_NONE;
856 ret = inno_hdmi_i2c_irq(hdmi);
858 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
859 if (interrupt & m_INT_HOTPLUG) {
860 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
861 ret = IRQ_WAKE_THREAD;
867 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
869 struct inno_hdmi *hdmi = dev_id;
871 drm_helper_hpd_irq_event(hdmi->connector.dev);
876 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
878 int length = msgs->len;
882 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
887 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
892 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
895 * The DDC module only support read EDID message, so
896 * we assume that each word write to this i2c adapter
897 * should be the offset of EDID word address.
899 if ((msgs->len != 1) ||
900 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
903 reinit_completion(&hdmi->i2c->cmp);
905 if (msgs->addr == DDC_SEGMENT_ADDR)
906 hdmi->i2c->segment_addr = msgs->buf[0];
907 if (msgs->addr == DDC_ADDR)
908 hdmi->i2c->ddc_addr = msgs->buf[0];
910 /* Set edid fifo first addr */
911 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
913 /* Set edid word address 0x00/0x80 */
914 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
916 /* Set edid segment pointer */
917 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
922 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
923 struct i2c_msg *msgs, int num)
925 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
926 struct inno_hdmi_i2c *i2c = hdmi->i2c;
929 mutex_lock(&i2c->lock);
931 /* Clear the EDID interrupt flag and unmute the interrupt */
932 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
933 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
935 for (i = 0; i < num; i++) {
936 DRM_DEV_DEBUG(hdmi->dev,
937 "xfer: num: %d/%d, len: %d, flags: %#x\n",
938 i + 1, num, msgs[i].len, msgs[i].flags);
940 if (msgs[i].flags & I2C_M_RD)
941 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
943 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
952 /* Mute HDMI EDID interrupt */
953 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
955 mutex_unlock(&i2c->lock);
960 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
962 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
965 static const struct i2c_algorithm inno_hdmi_algorithm = {
966 .master_xfer = inno_hdmi_i2c_xfer,
967 .functionality = inno_hdmi_i2c_func,
970 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
972 struct i2c_adapter *adap;
973 struct inno_hdmi_i2c *i2c;
976 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
978 return ERR_PTR(-ENOMEM);
980 mutex_init(&i2c->lock);
981 init_completion(&i2c->cmp);
984 adap->class = I2C_CLASS_DDC;
985 adap->owner = THIS_MODULE;
986 adap->dev.parent = hdmi->dev;
987 adap->algo = &inno_hdmi_algorithm;
988 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name));
989 i2c_set_adapdata(adap, hdmi);
991 ret = i2c_add_adapter(adap);
993 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
994 devm_kfree(hdmi->dev, i2c);
1000 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver success\n", adap->name);
1005 static int inno_hdmi_get_clk_rst(struct device *dev, struct inno_hdmi *hdmi)
1007 hdmi->sys_clk = devm_clk_get(dev, "sysclk");
1008 if (IS_ERR(hdmi->sys_clk)) {
1009 DRM_DEV_ERROR(dev, "Unable to get HDMI sysclk clk\n");
1010 return PTR_ERR(hdmi->sys_clk);
1012 hdmi->mclk = devm_clk_get(dev, "mclk");
1013 if (IS_ERR(hdmi->mclk)) {
1014 DRM_DEV_ERROR(dev, "Unable to get HDMI mclk clk\n");
1015 return PTR_ERR(hdmi->mclk);
1017 hdmi->bclk = devm_clk_get(dev, "bclk");
1018 if (IS_ERR(hdmi->bclk)) {
1019 DRM_DEV_ERROR(dev, "Unable to get HDMI bclk clk\n");
1020 return PTR_ERR(hdmi->bclk);
1022 hdmi->tx_rst = reset_control_get_exclusive(dev, "hdmi_tx");
1023 if (IS_ERR(hdmi->tx_rst)) {
1024 DRM_DEV_ERROR(dev, "Unable to get HDMI tx rst\n");
1025 return PTR_ERR(hdmi->tx_rst);
1030 static int inno_hdmi_en_clk_deas_rst(struct device *dev, struct inno_hdmi *hdmi)
1034 ret = clk_prepare_enable(hdmi->sys_clk);
1037 "Cannot enable HDMI sys clock: %d\n", ret);
1040 ret = clk_prepare_enable(hdmi->mclk);
1043 "Cannot enable HDMI mclk clock: %d\n", ret);
1046 ret = clk_prepare_enable(hdmi->bclk);
1049 "Cannot enable HDMI bclk clock: %d\n", ret);
1053 ret = reset_control_deassert(hdmi->tx_rst);
1055 dev_err(dev, "failed to deassert tx_rst\n");
1062 static int inno_hdmi_bind(struct device *dev, struct device *master,
1065 struct platform_device *pdev = to_platform_device(dev);
1066 struct drm_device *drm = data;
1067 struct inno_hdmi *hdmi;
1068 struct resource *iores;
1072 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1077 hdmi->drm_dev = drm;
1079 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1080 hdmi->regs = devm_ioremap_resource(dev, iores);
1081 if (IS_ERR(hdmi->regs))
1082 return PTR_ERR(hdmi->regs);
1084 hdmi->hdmi_1p8 = devm_regulator_get(dev, "hdmi_1p8");
1085 if (IS_ERR(hdmi->hdmi_1p8))
1086 return PTR_ERR(hdmi->hdmi_1p8);
1088 hdmi->hdmi_0p9 = devm_regulator_get(dev, "hdmi_0p9");
1089 if (IS_ERR(hdmi->hdmi_0p9))
1090 return PTR_ERR(hdmi->hdmi_0p9);
1093 ret = regulator_enable(hdmi->hdmi_1p8);
1095 dev_err(dev, "Cannot enable hdmi_1p8 regulator\n");
1099 ret = regulator_enable(hdmi->hdmi_0p9);
1101 dev_err(dev, "Cannot enable hdmi_0p9 regulator\n");
1106 ret = inno_hdmi_get_clk_rst(dev, hdmi);
1107 ret = inno_hdmi_en_clk_deas_rst(dev, hdmi);
1109 irq = platform_get_irq(pdev, 0);
1112 goto err_disable_clk;
1114 #ifdef CONFIG_DRM_I2C_NXP_TDA998X
1115 hdmi->hdmi_data.vic = 0x10;
1116 inno_hdmi_init(hdmi);
1118 inno_hdmi_reset(hdmi);
1120 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
1121 if (IS_ERR(hdmi->ddc)) {
1122 ret = PTR_ERR(hdmi->ddc);
1124 goto err_disable_clk;
1127 hdmi->tmds_rate = 51200000;
1129 inno_hdmi_i2c_init(hdmi);
1131 ret = inno_hdmi_register(drm, hdmi);
1133 goto err_put_adapter;
1135 dev_set_drvdata(dev, hdmi);
1137 /* Unmute hotplug interrupt */
1138 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
1140 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
1141 inno_hdmi_irq, IRQF_SHARED,
1142 dev_name(dev), hdmi);
1144 goto err_cleanup_hdmi;
1148 hdmi->connector.funcs->destroy(&hdmi->connector);
1149 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1151 i2c_put_adapter(hdmi->ddc);
1153 //clk_disable_unprepare(hdmi->pclk);
1155 regulator_disable(hdmi->hdmi_1p8);
1160 static void inno_hdmi_unbind(struct device *dev, struct device *master,
1163 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
1166 hdmi->connector.funcs->destroy(&hdmi->connector);
1167 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1169 i2c_put_adapter(hdmi->ddc);
1171 ret = reset_control_assert(hdmi->tx_rst);
1173 dev_err(dev, "failed to assert tx_rst\n");
1175 clk_disable_unprepare(hdmi->sys_clk);
1176 clk_disable_unprepare(hdmi->mclk);
1177 clk_disable_unprepare(hdmi->bclk);
1179 regulator_disable(hdmi->hdmi_1p8);
1181 regulator_disable(hdmi->hdmi_0p9);
1184 static const struct component_ops inno_hdmi_ops = {
1185 .bind = inno_hdmi_bind,
1186 .unbind = inno_hdmi_unbind,
1189 static int inno_hdmi_probe(struct platform_device *pdev)
1191 return component_add(&pdev->dev, &inno_hdmi_ops);
1194 static int inno_hdmi_remove(struct platform_device *pdev)
1196 component_del(&pdev->dev, &inno_hdmi_ops);
1201 static const struct of_device_id inno_hdmi_dt_ids[] = {
1202 { .compatible = "rockchip,rk3036-inno-hdmi",
1206 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
1208 struct platform_driver inno_hdmi_driver = {
1209 .probe = inno_hdmi_probe,
1210 .remove = inno_hdmi_remove,
1212 .name = "innohdmi-rockchip",
1213 .of_match_table = inno_hdmi_dt_ids,