hdmi: update driver to v2.0:
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmiv2 / rockchip_hdmiv2_hw.c
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"
7
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
11         */
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,
15                 2,      3,      0,      3,      3,      0,      0},
16         {27000000,      33750000,       0,      10,     1,      0,      0,
17                 5,      1,      0,      3,      3,      0,      0},
18         {27000000,      40500000,       0,      12,     2,      0,      0,
19                 3,      3,      0,      3,      3,      0,      0},
20         {27000000,      54000000,       0,      16,     3,      0,      0,
21                 2,      3,      0,      2,      5,      0,      1},
22 /*      {74250000,      74250000,       0,      8,      0,      0,      0,
23         1,      3,      0,      2,      5,      0,      1}, */
24         {74250000,      74250000,       0,      8,      0,      0,      0,
25                 4,      3,      3,      2,      7,      0,      3},
26         {74250000,      92812500,       0,      10,     1,      0,      0,
27                 5,      0,      1,      1,      7,      0,      2},
28         {74250000,      111375000,      0,      12,     2,      0,      0,
29                 1,      2,      0,      1,      7,      0,      2},
30         {74250000,      148500000,      0,      16,     3,      0,      0,
31                 1,      3,      0,      1,      7,      0,      2},
32         {148500000,     74250000,       0,      8,      0,      0,      0,
33                 1,      1,      1,      1,      0,      0,      3},
34         {148500000,     148500000,      0,      8,      0,      0,      0,
35                 1,      1,      0,      1,      0,      0,      3},
36         {148500000,     185625000,      0,      10,     1,      0,      0,
37                 5,      0,      3,      0,      7,      0,      3},
38         {148500000,     222750000,      0,      12,     2,      0,      0,
39                 1,      2,      1,      0,      7,      0,      3},
40         {148500000,     297000000,      0,      16,     3,      0,      0,
41                 1,      1,      0,      0,      7,      0,      3},
42         {297000000,     148500000,      0,      8,      0,      0,      0,
43                 1,      0,      1,      0,      0,      0,      3},
44         {297000000,     297000000,      0,      8,      0,      0,      0,
45                 1,      0,      0,      0,      0,      0,      3},
46         {297000000,     371250000,      0,      10,     1,      3,      1,
47                 5,      0,      3,      0,      7,      0,      3},
48         {297000000,     445500000,      0,      12,     2,      3,      1,
49                 1,      2,      2,      0,      7,      0,      3},
50         {297000000,     594000000,      0,      16,     1,      3,      1,
51                 1,      3,      1,      0,      0,      0,      3},
52 /*      {594000000,     297000000,      0,      8,      0,      0,      0,
53                 1,      3,      3,      1,      0,      0,      3},*/
54         {594000000,     297000000,      0,      8,      0,      0,      0,
55                 1,      0,      1,      0,      0,      0,      3},
56         {594000000,     594000000,      0,      8,      0,      3,      1,
57                 1,      3,      3,      0,      0,      0,      3},
58 };
59 /* ddc i2c master reset */
60 static void rockchip_hdmiv2_i2cm_reset(struct hdmi_dev *hdmi_dev)
61 {
62         hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ,
63                      m_I2CM_SOFTRST, v_I2CM_SOFTRST(0));
64         usleep_range(90, 100);
65 }
66
67 /*set read/write offset,set read/write mode*/
68 static void rockchip_hdmiv2_i2cm_write_request(struct hdmi_dev *hdmi_dev,
69                                                u8 offset, u8 data)
70 {
71         hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
72         hdmi_writel(hdmi_dev, I2CM_DATAO, data);
73         hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_WR, v_I2CM_WR(1));
74 }
75
76 static void rockchip_hdmiv2_i2cm_read_request(struct hdmi_dev *hdmi_dev,
77                                               u8 offset)
78 {
79         hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset);
80         hdmi_msk_reg(hdmi_dev, I2CM_OPERATION, m_I2CM_RD, v_I2CM_RD(1));
81 }
82
83 static void rockchip_hdmiv2_i2cm_write_data(struct hdmi_dev *hdmi_dev,
84                                             u8 data, u8 offset)
85 {
86         u8 interrupt;
87         int trytime = 2;
88         int i = 20;
89
90         while (trytime-- > 0) {
91                 rockchip_hdmiv2_i2cm_write_request(hdmi_dev, offset, data);
92                 while (i--) {
93                         usleep_range(900, 1000);
94                         interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
95                         if (interrupt)
96                                 hdmi_writel(hdmi_dev,
97                                             IH_I2CM_STAT0, interrupt);
98
99                         if (interrupt & (m_SCDC_READREQ |
100                                          m_I2CM_DONE | m_I2CM_ERROR))
101                                 break;
102                 }
103
104                 if (interrupt & m_I2CM_DONE) {
105                         dev_dbg(hdmi_dev->hdmi->dev,
106                                 "[%s] write offset %02x data %02x success\n",
107                                 __func__, offset, data);
108                         trytime = 0;
109                 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
110                         dev_err(hdmi_dev->hdmi->dev,
111                                 "[%s] write data error\n", __func__);
112                         rockchip_hdmiv2_i2cm_reset(hdmi_dev);
113                 }
114         }
115 }
116
117 static int rockchip_hdmiv2_i2cm_read_data(struct hdmi_dev *hdmi_dev, u8 offset)
118 {
119         u8 interrupt, val;
120         int trytime = 2;
121         int i = 20;
122
123         while (trytime-- > 0) {
124                 rockchip_hdmiv2_i2cm_read_request(hdmi_dev, offset);
125                 while (i--) {
126                         usleep_range(900, 1000);
127                         interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
128                         if (interrupt)
129                                 hdmi_writel(hdmi_dev, IH_I2CM_STAT0, interrupt);
130
131                         if (interrupt & (m_SCDC_READREQ |
132                                 m_I2CM_DONE | m_I2CM_ERROR))
133                                 break;
134                 }
135
136                 if (interrupt & m_I2CM_DONE) {
137                         val = hdmi_readl(hdmi_dev, I2CM_DATAI);
138                         trytime = 0;
139                 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
140                         pr_err("[%s] read data error\n", __func__);
141                         rockchip_hdmiv2_i2cm_reset(hdmi_dev);
142                 }
143         }
144         return val;
145 }
146
147 static void rockchip_hdmiv2_i2cm_mask_int(struct hdmi_dev *hdmi_dev, int mask)
148 {
149         if (0 == mask) {
150                 hdmi_msk_reg(hdmi_dev, I2CM_INT,
151                              m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
152                 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
153                              m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
154                              v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));
155         } else {
156                 hdmi_msk_reg(hdmi_dev, I2CM_INT,
157                              m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
158                 hdmi_msk_reg(hdmi_dev, I2CM_CTLINT,
159                              m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
160                              v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
161         }
162 }
163
164 #define I2C_DIV_FACTOR 100000
165 static u16 i2c_count(u16 sfrclock, u16 sclmintime)
166 {
167         unsigned long tmp_scl_period = 0;
168
169         if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0)
170                 tmp_scl_period = (unsigned long)((sfrclock * sclmintime) +
171                                 (I2C_DIV_FACTOR - ((sfrclock * sclmintime) %
172                                 I2C_DIV_FACTOR))) / I2C_DIV_FACTOR;
173         else
174                 tmp_scl_period = (unsigned long)(sfrclock * sclmintime) /
175                                 I2C_DIV_FACTOR;
176
177         return (u16)(tmp_scl_period);
178 }
179
180 #define EDID_I2C_MIN_SS_SCL_HIGH_TIME   50000
181 #define EDID_I2C_MIN_SS_SCL_LOW_TIME    50000
182
183 static void rockchip_hdmiv2_i2cm_clk_init(struct hdmi_dev *hdmi_dev)
184 {
185         /* Set DDC I2C CLK which devided from DDC_CLK. */
186         hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR,
187                     i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME));
188         hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR,
189                     i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME));
190         hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE,
191                      v_I2CM_FAST_STD_MODE(STANDARD_MODE));
192 }
193
194 static int rockchip_hdmiv2_scdc_get_sink_version(struct hdmi_dev *hdmi_dev)
195 {
196         return rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SINK_VER);
197 }
198
199 static void rockchip_hdmiv2_scdc_set_source_version(struct hdmi_dev *hdmi_dev,
200                                                     u8 version)
201 {
202         rockchip_hdmiv2_i2cm_write_data(hdmi_dev, version, SCDC_SOURCE_VER);
203 }
204
205
206 static void rockchip_hdmiv2_scdc_read_request(struct hdmi_dev *hdmi_dev,
207                                               int enable)
208 {
209         hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
210                      m_I2CM_READ_REQ_EN, v_I2CM_READ_REQ_EN(enable));
211         rockchip_hdmiv2_i2cm_write_data(hdmi_dev, enable, SCDC_CONFIG_0);
212 }
213
214 #ifdef HDMI_20_SCDC
215 static void rockchip_hdmiv2_scdc_update_read(struct hdmi_dev *hdmi_dev)
216 {
217         hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
218                      m_I2CM_READ_UPDATE, v_I2CM_READ_UPDATE(1));
219 }
220
221
222 static int rockchip_hdmiv2_scdc_get_scambling_status(struct hdmi_dev *hdmi_dev)
223 {
224         int val;
225
226         val = rockchip_hdmiv2_i2cm_read_data(hdmi_dev, SCDC_SCRAMBLER_STAT);
227         return val;
228 }
229
230 static void rockchip_hdmiv2_scdc_enable_polling(struct hdmi_dev *hdmi_dev,
231                                                 int enable)
232 {
233         rockchip_hdmiv2_scdc_read_request(hdmi_dev, enable);
234         hdmi_msk_reg(hdmi_dev, I2CM_SCDC_READ_UPDATE,
235                      m_I2CM_UPRD_VSYNC_EN, v_I2CM_UPRD_VSYNC_EN(enable));
236 }
237
238 static int rockchip_hdmiv2_scdc_get_status_reg0(struct hdmi_dev *hdmi_dev)
239 {
240         rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
241         rockchip_hdmiv2_scdc_update_read(hdmi_dev);
242         return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE0);
243 }
244
245 static int rockchip_hdmiv2_scdc_get_status_reg1(struct hdmi_dev *hdmi_dev)
246 {
247         rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
248         rockchip_hdmiv2_scdc_update_read(hdmi_dev);
249         return hdmi_readl(hdmi_dev, I2CM_SCDC_UPDATE1);
250 }
251 #endif
252
253 static void rockchip_hdmiv2_scdc_init(struct hdmi_dev *hdmi_dev)
254 {
255         rockchip_hdmiv2_i2cm_reset(hdmi_dev);
256         rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
257         rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
258         /* set scdc i2c addr */
259         hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_SCDC_ADDR);
260         rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);/*enable interrupt*/
261 }
262
263
264 static int rockchip_hdmiv2_scrambling_enable(struct hdmi_dev *hdmi_dev,
265                                              int enable)
266 {
267         HDMIDBG("%s enable %d\n", __func__, enable);
268         if (1 == enable) {
269                 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
270                 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 1, SCDC_TMDS_CONFIG);
271                 /* TMDS software reset request */
272                 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
273                              m_TMDS_SWRST, v_TMDS_SWRST(0));
274                 /* Enable/Disable Scrambling */
275                 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
276                              m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
277         } else {
278                 /* Enable/Disable Scrambling */
279                 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL,
280                              m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(0));
281                 /* TMDS software reset request */
282                 hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ,
283                              m_TMDS_SWRST, v_TMDS_SWRST(0));
284                 /* Write on Rx the bit Scrambling_Enable, register 0x20 */
285                 rockchip_hdmiv2_i2cm_write_data(hdmi_dev, 0, SCDC_TMDS_CONFIG);
286         }
287         return 0;
288 }
289
290
291
292 static const struct phy_mpll_config_tab *get_phy_mpll_tab(
293                 unsigned int pixclock, unsigned int tmdsclk,
294                 char pixrepet, char colordepth)
295 {
296         int i;
297
298         if (pixclock == 0)
299                 return NULL;
300         HDMIDBG("%s pixClock %u pixRepet %d colorDepth %d\n",
301                 __func__, pixclock, pixrepet, colordepth);
302         for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
303                 if ((PHY_MPLL_TABLE[i].pix_clock == pixclock) &&
304                     (PHY_MPLL_TABLE[i].tmdsclock == tmdsclk) &&
305                     (PHY_MPLL_TABLE[i].pix_repet == pixrepet) &&
306                     (PHY_MPLL_TABLE[i].color_depth == colordepth))
307                         return &PHY_MPLL_TABLE[i];
308         }
309         return NULL;
310 }
311
312 static void rockchip_hdmiv2_powerdown(struct hdmi_dev *hdmi_dev)
313 {
314         hdmi_msk_reg(hdmi_dev, PHY_CONF0,
315                      m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
316                      v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) |
317                      v_ENHPD_RXSENSE_SIG(1));
318         hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
319 }
320
321 static int rockchip_hdmiv2_write_phy(struct hdmi_dev *hdmi_dev,
322                                      int reg_addr, int val)
323 {
324         int trytime = 2, i = 0, op_status = 0;
325
326         while (trytime--) {
327                 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
328                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff);
329                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff);
330                 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE);
331
332                 i = 20;
333                 while (i--) {
334                         usleep_range(900, 1000);
335                         op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
336                         if (op_status)
337                                 hdmi_writel(hdmi_dev,
338                                             IH_I2CMPHY_STAT0,
339                                             op_status);
340
341                         if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
342                                 break;
343                 }
344
345                 if (op_status & m_I2CMPHY_DONE)
346                         return 0;
347                 else
348                         dev_err(hdmi_dev->hdmi->dev,
349                                 "[%s] operation error,trytime=%d\n",
350                                 __func__, trytime);
351                 msleep(100);
352         }
353
354         return -1;
355 }
356
357 static int __maybe_unused rockchip_hdmiv2_read_phy(struct hdmi_dev *hdmi_dev,
358                                                    int reg_addr)
359 {
360         int trytime = 2, i = 0, op_status = 0;
361         int val = 0;
362
363         while (trytime--) {
364                 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
365                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00);
366                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00);
367                 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ);
368
369                 i = 20;
370                 while (i--) {
371                         usleep_range(900, 1000);
372                         op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
373                         if (op_status)
374                                 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
375                                             op_status);
376
377                         if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR))
378                                 break;
379                 }
380
381                 if (op_status & m_I2CMPHY_DONE) {
382                         val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1);
383                         val = (val & 0xff) << 8;
384                         val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff);
385                         pr_debug("phy_reg0x%02x: 0x%04x",
386                                  reg_addr, val);
387                         return val;
388                 } else {
389                         pr_err("[%s] operation error,trytime=%d\n",
390                                __func__, trytime);
391                 }
392                 msleep(100);
393         }
394
395         return -1;
396 }
397
398 void rockchip_hdmiv2_dump_phy_regs(struct hdmi_dev *hdmi_dev)
399 {
400         int i;
401
402         for (i = 0; i < 0x28; i++)
403                 pr_info("phy reg %02x val %04x\n",
404                         i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
405 }
406
407 static int rockchip_hdmiv2_config_phy(struct hdmi_dev *hdmi_dev)
408 {
409         int stat = 0, i = 0;
410         const struct phy_mpll_config_tab *phy_mpll = NULL;
411
412         hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV,
413                      m_PHY_I2CM_FAST_STD, v_PHY_I2CM_FAST_STD(0));
414         /* power off PHY */
415         /* hdmi_writel(hdmi_dev, PHY_CONF0, 0x1e); */
416         hdmi_msk_reg(hdmi_dev, PHY_CONF0,
417                      m_PDDQ_SIG | m_TXPWRON_SIG | m_SVSRET_SIG,
418                      v_PDDQ_SIG(1) | v_TXPWRON_SIG(0) | v_SVSRET_SIG(1));
419
420         if (hdmi_dev->tmdsclk_ratio_change &&
421             hdmi_dev->hdmi->edid.scdc_present == 1) {
422                 mutex_lock(&hdmi_dev->ddc_lock);
423                 rockchip_hdmiv2_scdc_init(hdmi_dev);
424                 stat = rockchip_hdmiv2_i2cm_read_data(hdmi_dev,
425                                                       SCDC_TMDS_CONFIG);
426                 if (hdmi_dev->tmdsclk > 340000000)
427                         stat |= 2;
428                 else
429                         stat &= 0x1;
430                 rockchip_hdmiv2_i2cm_write_data(hdmi_dev,
431                                                 stat, SCDC_TMDS_CONFIG);
432                 mutex_unlock(&hdmi_dev->ddc_lock);
433         }
434         /* reset PHY */
435         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
436         usleep_range(1000, 2000);
437         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
438
439         /* Set slave address as PHY GEN2 address */
440         hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
441
442         /* config the required PHY I2C register */
443         phy_mpll = get_phy_mpll_tab(hdmi_dev->pixelclk,
444                                     hdmi_dev->tmdsclk,
445                                     hdmi_dev->pixelrepeat - 1,
446                                     hdmi_dev->colordepth);
447         if (phy_mpll) {
448                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG,
449                                           v_PREP_DIV(phy_mpll->prep_div) |
450                                           v_TMDS_CNTRL(
451                                           phy_mpll->tmdsmhl_cntrl) |
452                                           v_OPMODE(phy_mpll->opmode) |
453                                           v_FBDIV2_CNTRL(
454                                           phy_mpll->fbdiv2_cntrl) |
455                                           v_FBDIV1_CNTRL(
456                                           phy_mpll->fbdiv1_cntrl) |
457                                           v_REF_CNTRL(phy_mpll->ref_cntrl) |
458                                           v_MPLL_N_CNTRL(phy_mpll->n_cntrl));
459                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL,
460                                           v_MPLL_PROP_CNTRL(
461                                           phy_mpll->prop_cntrl) |
462                                           v_MPLL_INT_CNTRL(
463                                           phy_mpll->int_cntrl));
464                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL,
465                                           v_MPLL_GMP_CNTRL(
466                                           phy_mpll->gmp_cntrl));
467         }
468         if (hdmi_dev->tmdsclk <= 74250000) {
469                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
470                                           v_OVERRIDE(1) | v_SLOPEBOOST(0) |
471                                           v_TX_SYMON(1) | v_TX_TRAON(0) |
472                                           v_TX_TRBON(0) | v_CLK_SYMON(1));
473                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
474                                           v_TX_TERM(R100_OHMS));
475         } else if (hdmi_dev->tmdsclk <= 148500000) {
476                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
477                                           v_OVERRIDE(1) | v_SLOPEBOOST(1) |
478                                           v_TX_SYMON(1) | v_TX_TRAON(0) |
479                                           v_TX_TRBON(0) | v_CLK_SYMON(1));
480                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
481                                           v_TX_TERM(R100_OHMS));
482         } else if (hdmi_dev->tmdsclk <= 340000000) {
483                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
484                                           v_OVERRIDE(1) | v_SLOPEBOOST(1) |
485                                           v_TX_SYMON(1) | v_TX_TRAON(0) |
486                                           v_TX_TRBON(0) | v_CLK_SYMON(1));
487                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
488                                           v_TX_TERM(R100_OHMS));
489         } else if (hdmi_dev->tmdsclk > 340000000) {
490                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
491                                           v_OVERRIDE(1) | v_SLOPEBOOST(0) |
492                                           v_TX_SYMON(1) | v_TX_TRAON(0) |
493                                           v_TX_TRBON(0) | v_CLK_SYMON(1));
494                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
495                                           v_TX_TERM(R100_OHMS));
496         }
497
498         if (hdmi_dev->tmdsclk < 297000000)
499                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
500                                           v_SUP_TXLVL(18) | v_SUP_CLKLVL(17));
501         else
502                 rockchip_hdmiv2_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
503                                           v_SUP_TXLVL(14) | v_SUP_CLKLVL(13));
504
505         rockchip_hdmiv2_write_phy(hdmi_dev, 0x05, 0x8000);
506         if (hdmi_dev->tmdsclk_ratio_change)
507                 msleep(100);
508         /* power on PHY */
509         hdmi_writel(hdmi_dev, PHY_CONF0, 0x2e);
510         /*
511         hdmi_msk_reg(hdmi_dev, PHY_CONF0,
512                      m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
513                      v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) |
514                      v_ENHPD_RXSENSE_SIG(1));
515         */
516         /* check if the PHY PLL is locked */
517         #define PHY_TIMEOUT     10000
518         while (i++ < PHY_TIMEOUT) {
519                 if ((i % 10) == 0) {
520                         stat = hdmi_readl(hdmi_dev, PHY_STAT0);
521                         if (stat & m_PHY_LOCK)
522                                 break;
523                         usleep_range(1000, 2000);
524                 }
525         }
526         if ((stat & m_PHY_LOCK) == 0) {
527                 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
528                 dev_err(hdmi_dev->hdmi->dev,
529                         "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n",
530                         (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
531                 return -1;
532         }
533
534         return 0;
535 }
536
537 static int rockchip_hdmiv2_video_framecomposer(struct hdmi *hdmi_drv,
538                                                struct hdmi_video *vpara)
539 {
540         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
541         int value, vsync_pol, hsync_pol, de_pol;
542         struct hdmi_video_timing *timing = NULL;
543         struct fb_videomode *mode = NULL;
544         u32 sink_version, tmdsclk;
545
546         vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
547         hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
548         de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
549
550         hdmi_msk_reg(hdmi_dev, A_VIDPOLCFG,
551                      m_DATAEN_POL | m_VSYNC_POL | m_HSYNC_POL,
552                      v_DATAEN_POL(de_pol) |
553                      v_VSYNC_POL(vsync_pol) |
554                      v_HSYNC_POL(hsync_pol));
555
556         timing = (struct hdmi_video_timing *)hdmi_vic2timing(vpara->vic);
557         if (timing == NULL) {
558                 dev_err(hdmi_drv->dev,
559                         "[%s] not found vic %d\n", __func__, vpara->vic);
560                 return -ENOENT;
561         }
562         mode = &(timing->mode);
563         if (vpara->color_input == HDMI_COLOR_YCBCR420)
564                 tmdsclk = mode->pixclock / 2;
565         else
566                 tmdsclk = mode->pixclock;
567         switch (vpara->color_output_depth) {
568         case 10:
569                 tmdsclk += tmdsclk / 4;
570                 break;
571         case 12:
572                 tmdsclk += tmdsclk / 2;
573                 break;
574         case 16:
575                 tmdsclk += tmdsclk;
576                 break;
577         case 8:
578         default:
579                 break;
580         }
581
582         if (tmdsclk > 594000000) {
583                 vpara->color_output_depth = 8;
584                 tmdsclk = mode->pixclock;
585         }
586         pr_info("pixel clk is %u tmds clk is %u\n", mode->pixclock, tmdsclk);
587         if ((tmdsclk > 340000000 && hdmi_dev->tmdsclk < 340000000) ||
588             (tmdsclk < 340000000 && hdmi_dev->tmdsclk > 340000000))
589                 hdmi_dev->tmdsclk_ratio_change = true;
590         else
591                 hdmi_dev->tmdsclk_ratio_change = false;
592
593         hdmi_dev->tmdsclk = tmdsclk;
594         hdmi_dev->pixelclk = mode->pixclock;
595         hdmi_dev->pixelrepeat = timing->pixelrepeat;
596         hdmi_dev->colordepth = vpara->color_output_depth;
597
598         /* Video Register has already been set in uboot,
599            so we no need to set again */
600
601         if (hdmi_drv->uboot)
602                 return -1;
603
604         /* Start/stop HDCP keepout window generation */
605         hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
606                      m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
607         if (hdmi_drv->edid.scdc_present == 1) {
608                 if (tmdsclk > 340000000) {/* used for HDMI 2.0 TX */
609                         mutex_lock(&hdmi_dev->ddc_lock);
610                         rockchip_hdmiv2_scdc_init(hdmi_dev);
611                         sink_version =
612                         rockchip_hdmiv2_scdc_get_sink_version(hdmi_dev);
613                         pr_info("sink scdc version is %d\n", sink_version);
614                         sink_version = hdmi_drv->edid.hf_vsdb_version;
615                         rockchip_hdmiv2_scdc_set_source_version(hdmi_dev,
616                                                                 sink_version);
617                         if (hdmi_drv->edid.rr_capable == 1)
618                                 rockchip_hdmiv2_scdc_read_request(hdmi_dev, 1);
619                         rockchip_hdmiv2_scrambling_enable(hdmi_dev, 1);
620                         mutex_unlock(&hdmi_dev->ddc_lock);
621                 } else {
622                         mutex_lock(&hdmi_dev->ddc_lock);
623                         rockchip_hdmiv2_scdc_init(hdmi_dev);
624                         rockchip_hdmiv2_scrambling_enable(hdmi_dev, 0);
625                         mutex_unlock(&hdmi_dev->ddc_lock);
626                 }
627         }
628
629         hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
630                      m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL |
631                      m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
632                      v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
633                      v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->sink_hdmi) |
634                      v_FC_INTERLACE_MODE(mode->vmode));
635         if (mode->vmode == FB_VMODE_INTERLACED)
636                 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
637                              m_FC_VBLANK, v_FC_VBLANK(1));
638         else
639                 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
640                              m_FC_VBLANK, v_FC_VBLANK(0));
641
642         value = mode->xres;
643         if (vpara->color_input == HDMI_COLOR_YCBCR420)
644                 value = value / 2;
645         hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(value >> 8));
646         hdmi_writel(hdmi_dev, FC_INHACTIV0, (value & 0xff));
647
648         value = mode->yres;
649         hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(value >> 8));
650         hdmi_writel(hdmi_dev, FC_INVACTIV0, (value & 0xff));
651
652         value = mode->hsync_len + mode->left_margin + mode->right_margin;
653         if (vpara->color_input == HDMI_COLOR_YCBCR420)
654                 value = value / 2;
655         hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(value >> 8));
656         hdmi_writel(hdmi_dev, FC_INHBLANK0, (value & 0xff));
657
658         value = mode->vsync_len + mode->upper_margin + mode->lower_margin;
659         hdmi_writel(hdmi_dev, FC_INVBLANK, (value & 0xff));
660
661         value = mode->right_margin;
662         if (vpara->color_input == HDMI_COLOR_YCBCR420)
663                 value = value / 2;
664         hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(value >> 8));
665         hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (value & 0xff));
666
667         value = mode->lower_margin;
668         hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (value & 0xff));
669
670         value = mode->hsync_len;
671         if (vpara->color_input == HDMI_COLOR_YCBCR420)
672                 value = value / 2;
673         hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(value >> 8));
674         hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (value & 0xff));
675
676         value = mode->vsync_len;
677         hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (value & 0xff));
678
679         /*Set the control period minimum duration
680          (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/
681         hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
682         hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
683
684         hdmi_writel(hdmi_dev, FC_EXCTRLSPAC,
685                     (hdmi_dev->tmdsclk/1000) * 50 / (256 * 512));
686
687 #if 0
688         /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
689          * worst case: tmdsClock == 25MHz => config <= 19
690          */
691         hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1);
692
693         /*Set PreambleFilter*/
694         for (i = 0; i < 3; i++) {
695                 value = (i + 1) * 11;
696                 if (i == 0)             /*channel 0*/
697                         hdmi_writel(hdmi_dev, FC_CH0PREAM, value);
698                 else if (i == 1)        /*channel 1*/
699                         hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f);
700                 else if (i == 2)        /*channel 2*/
701                         hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f);
702         }
703 #endif
704
705         hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(timing->pixelrepeat));
706
707         return 0;
708 }
709
710 static int rockchip_hdmiv2_video_packetizer(struct hdmi_dev *hdmi_dev,
711                                             struct hdmi_video *vpara)
712 {
713         unsigned char color_depth = 0;
714         unsigned char output_select = 0;
715         unsigned char remap_size = 0;
716
717         if (vpara->color_output == HDMI_COLOR_YCBCR422) {
718                 switch (vpara->color_output_depth) {
719                 case 8:
720                         remap_size = YCC422_16BIT;
721                         break;
722                 case 10:
723                         remap_size = YCC422_20BIT;
724                         break;
725                 case 12:
726                         remap_size = YCC422_24BIT;
727                         break;
728                 default:
729                         remap_size = YCC422_16BIT;
730                         break;
731                 }
732
733                 output_select = OUT_FROM_YCC422_REMAP;
734                 /*Config remap size for the different color Depth*/
735                 hdmi_msk_reg(hdmi_dev, VP_REMAP,
736                              m_YCC422_SIZE, v_YCC422_SIZE(remap_size));
737         } else {
738                 switch (vpara->color_output_depth) {
739                 case 10:
740                         color_depth = COLOR_DEPTH_30BIT;
741                         output_select = OUT_FROM_PIXEL_PACKING;
742                         break;
743                 case 12:
744                         color_depth = COLOR_DEPTH_36BIT;
745                         output_select = OUT_FROM_PIXEL_PACKING;
746                         break;
747                 case 16:
748                         color_depth = COLOR_DEPTH_48BIT;
749                         output_select = OUT_FROM_PIXEL_PACKING;
750                         break;
751                 case 8:
752                 default:
753                         color_depth = COLOR_DEPTH_24BIT_DEFAULT;
754                         output_select = OUT_FROM_8BIT_BYPASS;
755                         break;
756                 }
757
758                 /*Config Color Depth*/
759                 hdmi_msk_reg(hdmi_dev, VP_PR_CD,
760                              m_COLOR_DEPTH, v_COLOR_DEPTH(color_depth));
761         }
762
763         /*Config pixel repettion*/
764         hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR,
765                      v_DESIRED_PR_FACTOR(hdmi_dev->pixelrepeat - 1));
766         if (hdmi_dev->pixelrepeat > 1)
767                 hdmi_msk_reg(hdmi_dev, VP_CONF,
768                              m_PIXEL_REPET_EN | m_BYPASS_SEL,
769                              v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
770         else
771                 hdmi_msk_reg(hdmi_dev, VP_CONF,
772                              m_PIXEL_REPET_EN | m_BYPASS_SEL,
773                              v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));
774
775         /*config output select*/
776         if (output_select == OUT_FROM_PIXEL_PACKING) { /* pixel packing */
777                 hdmi_msk_reg(hdmi_dev, VP_CONF,
778                              m_BYPASS_EN | m_PIXEL_PACK_EN |
779                              m_YCC422_EN | m_OUTPUT_SEL,
780                              v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) |
781                              v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
782         } else if (output_select == OUT_FROM_YCC422_REMAP) { /* YCC422 */
783                 hdmi_msk_reg(hdmi_dev, VP_CONF,
784                              m_BYPASS_EN | m_PIXEL_PACK_EN |
785                              m_YCC422_EN | m_OUTPUT_SEL,
786                              v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) |
787                              v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
788         } else if (output_select == OUT_FROM_8BIT_BYPASS ||
789                    output_select == 3) { /* bypass */
790                 hdmi_msk_reg(hdmi_dev, VP_CONF,
791                              m_BYPASS_EN | m_PIXEL_PACK_EN |
792                              m_YCC422_EN | m_OUTPUT_SEL,
793                              v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
794                              v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
795         }
796
797 #if defined(HDMI_VIDEO_STUFFING)
798         /* YCC422 and pixel packing stuffing*/
799         hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
800         hdmi_msk_reg(hdmi_dev, VP_STUFF,
801                      m_YCC422_STUFFING | m_PP_STUFFING,
802                      v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
803 #endif
804         return 0;
805 }
806
807 static int rockchip_hdmiv2_video_sampler(struct hdmi_dev *hdmi_dev,
808                                          struct hdmi_video *vpara)
809 {
810         int map_code = 0;
811
812         if (vpara->color_input == HDMI_COLOR_YCBCR422) {
813                 /* YCC422 mapping is discontinued - only map 1 is supported */
814                 switch (vpara->color_output_depth) {
815                 case 8:
816                         map_code = VIDEO_YCBCR422_8BIT;
817                         break;
818                 case 10:
819                         map_code = VIDEO_YCBCR422_10BIT;
820                         break;
821                 case 12:
822                         map_code = VIDEO_YCBCR422_12BIT;
823                         break;
824                 default:
825                         map_code = VIDEO_YCBCR422_8BIT;
826                         break;
827                 }
828         } else if (vpara->color_input == HDMI_COLOR_YCBCR420 ||
829                    vpara->color_input == HDMI_COLOR_YCBCR444) {
830                 switch (vpara->color_output_depth) {
831                 case 10:
832                         map_code = VIDEO_YCBCR444_10BIT;
833                         break;
834                 case 12:
835                         map_code = VIDEO_YCBCR444_12BIT;
836                         break;
837                 case 16:
838                         map_code = VIDEO_YCBCR444_16BIT;
839                         break;
840                 case 8:
841                 default:
842                         map_code = VIDEO_YCBCR444_8BIT;
843                         break;
844                 }
845         } else {
846                 switch (vpara->color_output_depth) {
847                 case 10:
848                         map_code = VIDEO_RGB444_10BIT;
849                         break;
850                 case 12:
851                         map_code = VIDEO_RGB444_12BIT;
852                         break;
853                 case 16:
854                         map_code = VIDEO_RGB444_16BIT;
855                         break;
856                 case 8:
857                 default:
858                         map_code = VIDEO_RGB444_8BIT;
859                         break;
860                 }
861                 map_code += (vpara->color_input == HDMI_COLOR_YCBCR444) ?
862                             8 : 0;
863         }
864
865         /* Set Data enable signal from external
866            and set video sample input mapping */
867         hdmi_msk_reg(hdmi_dev, TX_INVID0,
868                      m_INTERNAL_DE_GEN | m_VIDEO_MAPPING,
869                      v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));
870
871 #if defined(HDMI_VIDEO_STUFFING)
872         hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
873         hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
874         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
875                      m_GYDATA_STUFF, v_GYDATA_STUFF(1));
876         hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
877         hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
878         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
879                      m_RCRDATA_STUFF, v_RCRDATA_STUFF(1));
880         hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
881         hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
882         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING,
883                      m_BCBDATA_STUFF, v_BCBDATA_STUFF(1));
884 #endif
885         return 0;
886 }
887
888 static const char coeff_csc[][24] = {
889                 /*   G          R           B           Bias
890                      A1    |    A2     |    A3     |    A4    |
891                      B1    |    B2     |    B3     |    B4    |
892                      C1    |    C2     |    C3     |    C4    | */
893         {       /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */
894                 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,         /*G*/
895                 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x00, 0x40,         /*R*/
896                 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x00, 0x40,         /*B*/
897         },
898         {       /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */
899                 0x36, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,         /*G*/
900                 0x00, 0x00, 0x36, 0xf7, 0x00, 0x00, 0x01, 0x00,         /*R*/
901                 0x00, 0x00, 0x00, 0x00, 0x36, 0xf7, 0x01, 0x00,         /*B*/
902         },
903         {       /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
904                 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40,         /*Y*/
905                 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00,         /*Cr*/
906                 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00,         /*Cb*/
907         },
908         {       /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
909                 0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00,         /*Y*/
910                 0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00,         /*Cr*/
911                 0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00,         /*Cb*/
912         },
913         {       /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
914                 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40,         /*Y*/
915                 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00,         /*Cr*/
916                 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00,         /*Cb*/
917         },
918         {       /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
919                 0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00,         /*Y*/
920                 0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00,         /*Cr*/
921                 0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00,         /*Cb*/
922         },
923                 /* Y            Cr          Cb          Bias */
924         {       /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */
925                 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e,         /*G*/
926                 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a,         /*R*/
927                 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b,         /*B*/
928         },
929         {       /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */
930                 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7,         /*G*/
931                 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d,         /*R*/
932                 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25,         /*B*/
933         },
934 };
935
936 static int rockchip_hdmiv2_video_csc(struct hdmi_dev *hdmi_dev,
937                                      struct hdmi_video *vpara)
938 {
939         int i, mode, interpolation, decimation, csc_scale;
940         const char *coeff = NULL;
941         unsigned char color_depth = 0;
942
943         if (vpara->color_input == vpara->color_output) {
944                 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
945                              m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0));
946                 return 0;
947         }
948
949         if (vpara->color_input == HDMI_COLOR_YCBCR422 &&
950             vpara->color_output != HDMI_COLOR_YCBCR422 &&
951             vpara->color_output != HDMI_COLOR_YCBCR420) {
952                 interpolation = 1;
953                 hdmi_msk_reg(hdmi_dev, CSC_CFG,
954                              m_CSC_INTPMODE, v_CSC_INTPMODE(interpolation));
955         }
956
957         if ((vpara->color_input == HDMI_COLOR_RGB_0_255 ||
958              vpara->color_input == HDMI_COLOR_YCBCR444) &&
959              vpara->color_output == HDMI_COLOR_YCBCR422) {
960                 decimation = 1;
961                 hdmi_msk_reg(hdmi_dev, CSC_CFG,
962                              m_CSC_DECIMODE, v_CSC_DECIMODE(decimation));
963         }
964
965         switch (vpara->vic) {
966         case HDMI_720X480I_60HZ_4_3:
967         case HDMI_720X576I_50HZ_4_3:
968         case HDMI_720X480P_60HZ_4_3:
969         case HDMI_720X576P_50HZ_4_3:
970         case HDMI_720X480I_60HZ_16_9:
971         case HDMI_720X576I_50HZ_16_9:
972         case HDMI_720X480P_60HZ_16_9:
973         case HDMI_720X576P_50HZ_16_9:
974                 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
975                     vpara->color_output >= HDMI_COLOR_YCBCR444) {
976                         mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
977                         csc_scale = 0;
978                 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
979                            vpara->color_output == HDMI_COLOR_RGB_0_255) {
980                         mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
981                         csc_scale = 1;
982                 }
983                 break;
984         default:
985                 if (vpara->color_input == HDMI_COLOR_RGB_0_255 &&
986                     vpara->color_output >= HDMI_COLOR_YCBCR444) {
987                         mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
988                         csc_scale = 0;
989                 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
990                            vpara->color_output == HDMI_COLOR_RGB_0_255) {
991                         mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
992                         csc_scale = 1;
993                 }
994                 break;
995         }
996
997         if ((vpara->color_input == HDMI_COLOR_RGB_0_255) &&
998             (vpara->color_output == HDMI_COLOR_RGB_16_235)) {
999                 mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
1000                 csc_scale = 0;
1001         }
1002
1003         switch (vpara->color_output_depth) {
1004         case 10:
1005                 color_depth = COLOR_DEPTH_30BIT;
1006                 mode += 1;
1007                 break;
1008         case 12:
1009                 color_depth = COLOR_DEPTH_36BIT;
1010                 mode += 2;
1011                 break;
1012         case 16:
1013                 color_depth = COLOR_DEPTH_48BIT;
1014                 mode += 3;
1015                 break;
1016         case 8:
1017         default:
1018                 color_depth = COLOR_DEPTH_24BIT;
1019                 break;
1020         }
1021
1022         coeff = coeff_csc[mode];
1023         for (i = 0; i < 24; i++)
1024                 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
1025
1026         hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1027                      m_CSC_SCALE, v_CSC_SCALE(csc_scale));
1028         /*config CSC_COLOR_DEPTH*/
1029         hdmi_msk_reg(hdmi_dev, CSC_SCALE,
1030                      m_CSC_COLOR_DEPTH, v_CSC_COLOR_DEPTH(color_depth));
1031
1032         /* enable CSC */
1033         hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL,
1034                      m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1));
1035
1036         return 0;
1037 }
1038
1039
1040 static int hdmi_dev_detect_hotplug(struct hdmi *hdmi)
1041 {
1042         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1043         u32 value = hdmi_readl(hdmi_dev, PHY_STAT0);
1044
1045         HDMIDBG("[%s] reg%x value %02x\n", __func__, PHY_STAT0, value);
1046
1047         if (value & m_PHY_HPD)
1048                 return HDMI_HPD_ACTIVED;
1049         else
1050                 return HDMI_HPD_REMOVED;
1051 }
1052
1053 static int hdmi_dev_read_edid(struct hdmi *hdmi, int block, unsigned char *buff)
1054 {
1055         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1056         int i = 0, n = 0, index = 0, ret = -1, trytime = 5;
1057         int offset = (block % 2) * 0x80;
1058         int interrupt = 0;
1059
1060         HDMIDBG("[%s] block %d\n", __func__, block);
1061
1062         rockchip_hdmiv2_i2cm_reset(hdmi_dev);
1063
1064         /* Set DDC I2C CLK which devided from DDC_CLK to 100KHz. */
1065         rockchip_hdmiv2_i2cm_clk_init(hdmi_dev);
1066
1067         /* Enable I2C interrupt for reading edid */
1068         rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 0);
1069
1070         hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
1071         hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
1072         hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
1073         for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
1074                 for (trytime = 0; trytime < 5; trytime++) {
1075                         hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
1076                         /* enable extend sequential read operation */
1077                         if (block == 0)
1078                                 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1079                                              m_I2CM_RD8, v_I2CM_RD8(1));
1080                         else
1081                                 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
1082                                              m_I2CM_RD8_EXT,
1083                                              v_I2CM_RD8_EXT(1));
1084
1085                         i = 20;
1086                         while (i--) {
1087                                 usleep_range(900, 1000);
1088                                 interrupt = hdmi_readl(hdmi_dev,
1089                                                        IH_I2CM_STAT0);
1090                                 if (interrupt)
1091                                         hdmi_writel(hdmi_dev,
1092                                                     IH_I2CM_STAT0, interrupt);
1093
1094                                 if (interrupt &
1095                                     (m_SCDC_READREQ | m_I2CM_DONE |
1096                                      m_I2CM_ERROR))
1097                                         break;
1098                         }
1099
1100                         if (interrupt & m_I2CM_DONE) {
1101                                 for (index = 0; index < 8; index++)
1102                                         buff[8 * n + index] =
1103                                                 hdmi_readl(hdmi_dev,
1104                                                            I2CM_READ_BUFF0 +
1105                                                            index);
1106
1107                                 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
1108                                         ret = 0;
1109                                         goto exit;
1110                                 }
1111                                 break;
1112                         } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
1113                                 dev_err(hdmi->dev,
1114                                         "[%s] edid read %d error\n",
1115                                         __func__, offset + 8 * n);
1116                         }
1117                 }
1118                 if (trytime == 5) {
1119                         dev_err(hdmi->dev,
1120                                 "[%s] edid read error\n", __func__);
1121                         break;
1122                 }
1123         }
1124
1125 exit:
1126         /* Disable I2C interrupt */
1127         rockchip_hdmiv2_i2cm_mask_int(hdmi_dev, 1);
1128
1129         #ifdef DEBUG
1130         if (!ret) {
1131                 for (index = 0; index < 128; index++) {
1132                         printk("0x%02x ,", buff[index]);
1133                         if ((index + 1) % 16 == 0)
1134                                 printk("\n");
1135                 }
1136         }
1137         #endif
1138         return ret;
1139 }
1140
1141 static void hdmi_dev_config_avi(struct hdmi_dev *hdmi_dev,
1142                                 struct hdmi_video *vpara)
1143 {
1144         unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0;
1145         unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT;
1146
1147         /* Set AVI infoFrame Data byte1 */
1148         if (vpara->color_output == HDMI_COLOR_YCBCR444)
1149                 y1y0 = AVI_COLOR_MODE_YCBCR444;
1150         else if (vpara->color_output == HDMI_COLOR_YCBCR422)
1151                 y1y0 = AVI_COLOR_MODE_YCBCR422;
1152         else if (vpara->color_output == HDMI_COLOR_YCBCR420)
1153                 y1y0 = AVI_COLOR_MODE_YCBCR420;
1154         else
1155                 y1y0 = AVI_COLOR_MODE_RGB;
1156
1157         hdmi_msk_reg(hdmi_dev, FC_AVICONF0,
1158                      m_FC_ACTIV_FORMAT | m_FC_RGC_YCC,
1159                      v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1));
1160
1161         /* Set AVI infoFrame Data byte2 */
1162         switch (vpara->vic) {
1163         case HDMI_720X480I_60HZ_4_3:
1164         case HDMI_720X576I_50HZ_4_3:
1165         case HDMI_720X480P_60HZ_4_3:
1166         case HDMI_720X576P_50HZ_4_3:
1167                 aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
1168                 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1169                 break;
1170         case HDMI_720X480I_60HZ_16_9:
1171         case HDMI_720X576I_50HZ_16_9:
1172         case HDMI_720X480P_60HZ_16_9:
1173         case HDMI_720X576P_50HZ_16_9:
1174                 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1175                 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
1176                 break;
1177         default:
1178                 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
1179                 colorimetry = AVI_COLORIMETRY_ITU709;
1180         }
1181
1182         if (vpara->color_output_depth > 8) {
1183                 colorimetry = AVI_COLORIMETRY_EXTENDED;
1184                 ext_colorimetry = 6;
1185         } else if (vpara->color_output == HDMI_COLOR_RGB_16_235 ||
1186                  vpara->color_output == HDMI_COLOR_RGB_0_255) {
1187                 colorimetry = AVI_COLORIMETRY_NO_DATA;
1188                 ext_colorimetry = 0;
1189         }
1190
1191         hdmi_writel(hdmi_dev, FC_AVICONF1,
1192                     v_FC_COLORIMETRY(colorimetry) |
1193                     v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
1194                     v_FC_ACT_ASPEC_RATIO(ACTIVE_ASPECT_RATE_DEFAULT));
1195
1196         /* Set AVI infoFrame Data byte3 */
1197         hdmi_msk_reg(hdmi_dev, FC_AVICONF2,
1198                      m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE,
1199                      v_FC_EXT_COLORIMETRY(ext_colorimetry) |
1200                      v_FC_QUAN_RANGE(rgb_quan_range));
1201
1202         /* Set AVI infoFrame Data byte4 */
1203         if ((vpara->vic > 92 && vpara->vic < 96) || (vpara->vic == 98))
1204                 hdmi_writel(hdmi_dev, FC_AVIVID, 0);
1205         else
1206                 hdmi_writel(hdmi_dev, FC_AVIVID, vpara->vic & 0xff);
1207         /* Set AVI infoFrame Data byte5 */
1208         hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN,
1209                      v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS));
1210 }
1211
1212 static int hdmi_dev_config_vsi(struct hdmi *hdmi,
1213                                unsigned char vic_3d, unsigned char format)
1214 {
1215         int i = 0, id = 0x000c03;
1216         unsigned char data[3] = {0};
1217
1218         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1219
1220         HDMIDBG("[%s] vic %d format %d.\n", __func__, vic_3d, format);
1221
1222         hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0));
1223         hdmi_writel(hdmi_dev, FC_VSDIEEEID2, id & 0xff);
1224         hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff);
1225         hdmi_writel(hdmi_dev, FC_VSDIEEEID0, (id >> 16) & 0xff);
1226
1227         data[0] = format << 5;  /* PB4 --HDMI_Video_Format */
1228         switch (format) {
1229         case HDMI_VIDEO_FORMAT_4KX2K:
1230                 data[1] = vic_3d;       /* PB5--HDMI_VIC */
1231                 data[2] = 0;
1232                 break;
1233         case HDMI_VIDEO_FORMAT_3D:
1234                 data[1] = vic_3d << 4;  /* PB5--3D_Structure field */
1235                 data[2] = 0;            /* PB6--3D_Ext_Data field */
1236                 break;
1237         default:
1238                 data[1] = 0;
1239                 data[2] = 0;
1240                 break;
1241         }
1242
1243         for (i = 0; i < 3; i++)
1244                 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
1245         hdmi_writel(hdmi_dev, FC_VSDSIZE, 0x6);
1246 /*      if (auto_send) { */
1247         hdmi_writel(hdmi_dev, FC_DATAUTO1, 0);
1248         hdmi_writel(hdmi_dev, FC_DATAUTO2, 0x11);
1249         hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(1));
1250 /*      }
1251         else {
1252                 hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1));
1253         }
1254 */
1255         return 0;
1256 }
1257
1258 static int hdmi_dev_config_video(struct hdmi *hdmi, struct hdmi_video *vpara)
1259 {
1260         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1261
1262         HDMIDBG("%s vic %d 3dformat %d color mode %d color depth %d\n",
1263                 __func__, vpara->vic, vpara->format_3d,
1264                 vpara->color_output, vpara->color_output_depth);
1265
1266         if (hdmi_dev->soctype == HDMI_SOC_RK3288)
1267                 vpara->color_input = HDMI_COLOR_RGB_0_255;
1268
1269         if (!hdmi->uboot) {
1270                 /* befor configure video, we power off phy */
1271                 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1272                              m_PDDQ_SIG | m_TXPWRON_SIG,
1273                              v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1274
1275                 /* force output blue */
1276                 if (vpara->color_output == HDMI_COLOR_RGB_0_255) {
1277                         hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00);       /*R*/
1278                         hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00);       /*G*/
1279                         hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00);       /*B*/
1280                 } else if (vpara->color_output == HDMI_COLOR_RGB_16_235) {
1281                         hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x10);       /*R*/
1282                         hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10);       /*G*/
1283                         hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x10);       /*B*/
1284                 } else {
1285                         hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x80);       /*R*/
1286                         hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x10);       /*G*/
1287                         hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x80);       /*B*/
1288                 }
1289                 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1290                              m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1291         }
1292
1293         hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1294         if (rockchip_hdmiv2_video_framecomposer(hdmi, vpara) < 0)
1295                 return -1;
1296
1297         if (rockchip_hdmiv2_video_packetizer(hdmi_dev, vpara) < 0)
1298                 return -1;
1299         /* Color space convert */
1300         if (rockchip_hdmiv2_video_csc(hdmi_dev, vpara) < 0)
1301                 return -1;
1302         if (rockchip_hdmiv2_video_sampler(hdmi_dev, vpara) < 0)
1303                 return -1;
1304
1305         if (vpara->sink_hdmi == OUTPUT_HDMI) {
1306                 hdmi_dev_config_avi(hdmi_dev, vpara);
1307                 if (vpara->format_3d != HDMI_3D_NONE) {
1308                         hdmi_dev_config_vsi(hdmi,
1309                                             vpara->format_3d,
1310                                             HDMI_VIDEO_FORMAT_3D);
1311                 } else if ((vpara->vic > 92 && vpara->vic < 96) ||
1312                          (vpara->vic == 98)) {
1313                         vpara->vic = (vpara->vic == 98) ?
1314                                      4 : (96 - vpara->vic);
1315                         hdmi_dev_config_vsi(hdmi,
1316                                             vpara->vic,
1317                                             HDMI_VIDEO_FORMAT_4KX2K);
1318                 } else {
1319                         hdmi_dev_config_vsi(hdmi,
1320                                             vpara->vic,
1321                                             HDMI_VIDEO_FORMAT_NORMAL);
1322                 }
1323                 dev_info(hdmi->dev, "[%s] sucess output HDMI.\n", __func__);
1324         } else {
1325                 dev_info(hdmi->dev, "[%s] sucess output DVI.\n", __func__);
1326         }
1327
1328         rockchip_hdmiv2_config_phy(hdmi_dev);
1329         return 0;
1330 }
1331
1332 static void hdmi_dev_config_aai(struct hdmi_dev *hdmi_dev,
1333                                 struct hdmi_audio *audio)
1334 {
1335         /*Refer to CEA861-E Audio infoFrame*/
1336         /*Set both Audio Channel Count and Audio Coding
1337           Type Refer to Stream Head for HDMI*/
1338         hdmi_msk_reg(hdmi_dev, FC_AUDICONF0,
1339                      m_FC_CHN_CNT | m_FC_CODING_TYEP,
1340                      v_FC_CHN_CNT(audio->channel-1) | v_FC_CODING_TYEP(0));
1341
1342         /*Set both Audio Sample Size and Sample Frequency
1343           Refer to Stream Head for HDMI*/
1344         hdmi_msk_reg(hdmi_dev, FC_AUDICONF1,
1345                      m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ,
1346                      v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
1347
1348         /*Set Channel Allocation*/
1349         hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1350
1351         /*Set LFEPBL¡¢DOWN-MIX INH and LSV*/
1352         hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1353 }
1354
1355 static int hdmi_dev_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio)
1356 {
1357         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1358         int word_length = 0, channel = 0, mclk_fs;
1359         unsigned int N = 0, CTS = 0;
1360         int rate = 0;
1361
1362         HDMIDBG("%s\n", __func__);
1363
1364         if (audio->channel < 3)
1365                 channel = I2S_CHANNEL_1_2;
1366         else if (audio->channel < 5)
1367                 channel = I2S_CHANNEL_3_4;
1368         else if (audio->channel < 7)
1369                 channel = I2S_CHANNEL_5_6;
1370         else
1371                 channel = I2S_CHANNEL_7_8;
1372
1373         switch (audio->rate) {
1374         case HDMI_AUDIO_FS_32000:
1375                 mclk_fs = FS_64;
1376                 rate = AUDIO_32K;
1377                 if (hdmi_dev->tmdsclk >= 594000000)
1378                         N = N_32K_HIGHCLK;
1379                 else if (hdmi_dev->tmdsclk >= 297000000)
1380                         N = N_32K_MIDCLK;
1381                 else
1382                         N = N_32K_LOWCLK;
1383                 /*div a num to avoid the value is exceed 2^32(int)*/
1384                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 32);
1385                 break;
1386         case HDMI_AUDIO_FS_44100:
1387                 mclk_fs = FS_64;
1388                 rate = AUDIO_441K;
1389                 if (hdmi_dev->tmdsclk >= 594000000)
1390                         N = N_441K_HIGHCLK;
1391                 else if (hdmi_dev->tmdsclk >= 297000000)
1392                         N = N_441K_MIDCLK;
1393                 else
1394                         N = N_441K_LOWCLK;
1395
1396                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 441);
1397                 break;
1398         case HDMI_AUDIO_FS_48000:
1399                 mclk_fs = FS_64;
1400                 rate = AUDIO_48K;
1401                 if (hdmi_dev->tmdsclk >= 594000000)     /*FS_153.6*/
1402                         N = N_48K_HIGHCLK;
1403                 else if (hdmi_dev->tmdsclk >= 297000000)
1404                         N = N_48K_MIDCLK;
1405                 else
1406                         N = N_48K_LOWCLK;
1407
1408                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 48);
1409                 break;
1410         case HDMI_AUDIO_FS_88200:
1411                 mclk_fs = FS_64;
1412                 rate = AUDIO_882K;
1413                 if (hdmi_dev->tmdsclk >= 594000000)
1414                         N = N_882K_HIGHCLK;
1415                 else if (hdmi_dev->tmdsclk >= 297000000)
1416                         N = N_882K_MIDCLK;
1417                 else
1418                         N = N_882K_LOWCLK;
1419
1420                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 882);
1421                 break;
1422         case HDMI_AUDIO_FS_96000:
1423                 mclk_fs = FS_64;
1424                 rate = AUDIO_96K;
1425                 if (hdmi_dev->tmdsclk >= 594000000)     /*FS_153.6*/
1426                         N = N_96K_HIGHCLK;
1427                 else if (hdmi_dev->tmdsclk >= 297000000)
1428                         N = N_96K_MIDCLK;
1429                 else
1430                         N = N_96K_LOWCLK;
1431
1432                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 96);
1433                 break;
1434         case HDMI_AUDIO_FS_176400:
1435                 mclk_fs = FS_64;
1436                 rate = AUDIO_1764K;
1437                 if (hdmi_dev->tmdsclk >= 594000000)
1438                         N = N_1764K_HIGHCLK;
1439                 else if (hdmi_dev->tmdsclk >= 297000000)
1440                         N = N_1764K_MIDCLK;
1441                 else
1442                         N = N_1764K_LOWCLK;
1443
1444                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 1764);
1445                 break;
1446         case HDMI_AUDIO_FS_192000:
1447                 mclk_fs = FS_64;
1448                 rate = AUDIO_192K;
1449                 if (hdmi_dev->tmdsclk >= 594000000)     /*FS_153.6*/
1450                         N = N_192K_HIGHCLK;
1451                 else if (hdmi_dev->tmdsclk >= 297000000)
1452                         N = N_192K_MIDCLK;
1453                 else
1454                         N = N_192K_LOWCLK;
1455
1456                 CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 192);
1457                 break;
1458         default:
1459                 dev_err(hdmi_dev->hdmi->dev,
1460                         "[%s] not support such sample rate %d\n",
1461                         __func__, audio->rate);
1462                 return -ENOENT;
1463         }
1464
1465         switch (audio->word_length) {
1466         case HDMI_AUDIO_WORD_LENGTH_16bit:
1467                 word_length = I2S_16BIT_SAMPLE;
1468                 break;
1469         case HDMI_AUDIO_WORD_LENGTH_20bit:
1470                 word_length = I2S_20BIT_SAMPLE;
1471                 break;
1472         case HDMI_AUDIO_WORD_LENGTH_24bit:
1473                 word_length = I2S_24BIT_SAMPLE;
1474                 break;
1475         default:
1476                 word_length = I2S_16BIT_SAMPLE;
1477         }
1478
1479         HDMIDBG("rate = %d, tmdsclk = %u, N = %d, CTS = %d\n",
1480                 audio->rate, hdmi_dev->tmdsclk, N, CTS);
1481         /* more than 2 channels => layout 1 else layout 0 */
1482         hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1483                      m_AUD_PACK_LAYOUT,
1484                      v_AUD_PACK_LAYOUT((audio->channel > 2) ? 1 : 0));
1485
1486         if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_IIS) {
1487                 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1488                              m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA));
1489                 hdmi_msk_reg(hdmi_dev, AUD_SPDIF1,
1490                              m_SET_NLPCM | m_SPDIF_WIDTH,
1491                              v_SET_NLPCM(PCM_LINEAR) |
1492                              v_SPDIF_WIDTH(word_length));
1493                 /*Mask fifo empty and full int and reset fifo*/
1494                 hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT,
1495                              m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1496                              v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1497                 hdmi_msk_reg(hdmi_dev, AUD_SPDIF0,
1498                              m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1));
1499         } else {
1500                 /*Mask fifo empty and full int and reset fifo*/
1501                 hdmi_msk_reg(hdmi_dev, AUD_INT,
1502                              m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1503                              v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1504                 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1505                              m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1506                 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1507                 usleep_range(90, 100);
1508                 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1509                              m_I2S_SEL | m_I2S_IN_EN,
1510                              v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
1511                 hdmi_writel(hdmi_dev, AUD_CONF1,
1512                             v_I2S_MODE(I2S_STANDARD_MODE) |
1513                             v_I2S_WIDTH(word_length));
1514         }
1515
1516         hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS,
1517                      m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs));
1518
1519         /*Set N value*/
1520         hdmi_msk_reg(hdmi_dev, AUD_N3, m_NCTS_ATOMIC_WR, v_NCTS_ATOMIC_WR(1));
1521         /*Set CTS by manual*/
1522         hdmi_msk_reg(hdmi_dev, AUD_CTS3,
1523                      m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
1524                      v_N_SHIFT(N_SHIFT_1) |
1525                      v_CTS_MANUAL(1) |
1526                      v_AUD_CTS3(CTS >> 16));
1527         hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
1528         hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
1529
1530         hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
1531         hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
1532         hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
1533
1534         /* set channel status register */
1535         hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7,
1536                      m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate));
1537         /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS2, 0x1); */
1538         /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2); */
1539
1540         hdmi_dev_config_aai(hdmi_dev, audio);
1541
1542         return 0;
1543 }
1544
1545 static int hdmi_dev_control_output(struct hdmi *hdmi, int enable)
1546 {
1547         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1548
1549         HDMIDBG("[%s] %d\n", __func__, enable);
1550
1551         if (enable == HDMI_AV_UNMUTE) {
1552                 hdmi_writel(hdmi_dev, FC_DBGFORCE, 0x00);
1553                 hdmi_msk_reg(hdmi_dev, FC_GCP,
1554                              m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE,
1555                              v_FC_SET_AVMUTE(0) | v_FC_CLR_AVMUTE(1));
1556         } else {
1557                 if (enable & HDMI_VIDEO_MUTE) {
1558                         hdmi_msk_reg(hdmi_dev, FC_DBGFORCE,
1559                                      m_FC_FORCEVIDEO, v_FC_FORCEVIDEO(1));
1560                         hdmi_msk_reg(hdmi_dev, FC_GCP,
1561                                      m_FC_SET_AVMUTE | m_FC_CLR_AVMUTE,
1562                                      v_FC_SET_AVMUTE(1) | v_FC_CLR_AVMUTE(0));
1563                 }
1564 /*              if (enable & HDMI_AUDIO_MUTE) {
1565                         hdmi_msk_reg(hdmi_dev, FC_AUDSCONF,
1566                                      m_AUD_PACK_SAMPFIT,
1567                                      v_AUD_PACK_SAMPFIT(0x0F));
1568                 }
1569 */              if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) {
1570                         msleep(100);
1571                         rockchip_hdmiv2_powerdown(hdmi_dev);
1572                         hdmi_dev->tmdsclk = 0;
1573 /*
1574                         hdmi_msk_reg(hdmi_dev, PHY_CONF0,
1575                                      m_PDDQ_SIG | m_TXPWRON_SIG,
1576                                      v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
1577                         hdmi_writel(hdmi_dev, MC_CLKDIS, 0x7f);
1578 */              }
1579         }
1580         return 0;
1581 }
1582
1583 static int hdmi_dev_insert(struct hdmi *hdmi)
1584 {
1585         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1586
1587         HDMIDBG("%s\n", __func__);
1588         hdmi_writel(hdmi_dev, MC_CLKDIS, m_HDCPCLK_DISABLE);
1589         return HDMI_ERROR_SUCESS;
1590 }
1591
1592 static int hdmi_dev_remove(struct hdmi *hdmi)
1593 {
1594         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1595
1596         HDMIDBG("%s\n", __func__);
1597         rockchip_hdmiv2_powerdown(hdmi_dev);
1598         hdmi_dev->tmdsclk = 0;
1599         return HDMI_ERROR_SUCESS;
1600 }
1601
1602 static int hdmi_dev_enable(struct hdmi *hdmi)
1603 {
1604         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1605
1606         HDMIDBG("%s\n", __func__);
1607         if (!hdmi_dev->enable) {
1608                 hdmi_writel(hdmi_dev, IH_MUTE, 0x00);
1609                 hdmi_dev->enable = 1;
1610         }
1611         hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 10, NULL);
1612         return 0;
1613 }
1614
1615 static int hdmi_dev_disable(struct hdmi *hdmi)
1616 {
1617         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
1618
1619         HDMIDBG("%s\n", __func__);
1620         if (hdmi_dev->enable) {
1621                 hdmi_dev->enable = 0;
1622                 hdmi_writel(hdmi_dev, IH_MUTE, 0x1);
1623         }
1624         return 0;
1625 }
1626
1627 void rockchip_hdmiv2_dev_init_ops(struct hdmi_ops *ops)
1628 {
1629         if (ops) {
1630                 ops->enable     = hdmi_dev_enable;
1631                 ops->disable    = hdmi_dev_disable;
1632                 ops->getstatus  = hdmi_dev_detect_hotplug;
1633                 ops->insert     = hdmi_dev_insert;
1634                 ops->remove     = hdmi_dev_remove;
1635                 ops->getedid    = hdmi_dev_read_edid;
1636                 ops->setvideo   = hdmi_dev_config_video;
1637                 ops->setaudio   = hdmi_dev_config_audio;
1638                 ops->setmute    = hdmi_dev_control_output;
1639                 ops->setvsi     = hdmi_dev_config_vsi;
1640         }
1641 }
1642
1643 void rockchip_hdmiv2_dev_initial(struct hdmi_dev *hdmi_dev)
1644 {
1645         struct hdmi *hdmi = hdmi_dev->hdmi;
1646
1647         if (!hdmi->uboot) {
1648                 /* reset hdmi */
1649                 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
1650                         writel_relaxed((1 << 9) | (1 << 25),
1651                                        RK_CRU_VIRT + 0x01d4);
1652                         udelay(1);
1653                         writel_relaxed((0 << 9) | (1 << 25),
1654                                        RK_CRU_VIRT + 0x01d4);
1655                 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
1656                         pr_info("reset hdmi\n");
1657                         regmap_write(hdmi_dev->grf_base, 0x031c,
1658                                      (1 << 9) | (1 << 25));
1659                         udelay(5);
1660                         regmap_write(hdmi_dev->grf_base, 0x031c,
1661                                      (0 << 9) | (1 << 25));
1662                 }
1663                 rockchip_hdmiv2_powerdown(hdmi_dev);
1664         }
1665         /*mute unnecessary interrrupt, only enable hpd*/
1666         hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT0, 0xff);
1667         hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT1, 0xff);
1668         hdmi_writel(hdmi_dev, IH_MUTE_FC_STAT2, 0xff);
1669         hdmi_writel(hdmi_dev, IH_MUTE_AS_STAT0, 0xff);
1670         hdmi_writel(hdmi_dev, IH_MUTE_PHY_STAT0, 0xfe);
1671         hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0, 0xff);
1672         hdmi_writel(hdmi_dev, IH_MUTE_CEC_STAT0, 0xff);
1673         hdmi_writel(hdmi_dev, IH_MUTE_VP_STAT0, 0xff);
1674         hdmi_writel(hdmi_dev, IH_MUTE_I2CMPHY_STAT0, 0xff);
1675         hdmi_writel(hdmi_dev, IH_MUTE_AHBDMAAUD_STAT0, 0xff);
1676
1677         /* disable hdcp interrup */
1678         hdmi_writel(hdmi_dev, A_APIINTMSK, 0xff);
1679         hdmi_writel(hdmi_dev, PHY_MASK, 0xf1);
1680
1681         if (hdmi->property->feature & SUPPORT_CEC)
1682                 rockchip_hdmiv2_cec_init(hdmi);
1683         if (hdmi->property->feature & SUPPORT_HDCP)
1684                 rockchip_hdmiv2_hdcp_init(hdmi);
1685 }
1686
1687 irqreturn_t rockchip_hdmiv2_dev_irq(int irq, void *priv)
1688 {
1689         struct hdmi_dev *hdmi_dev = priv;
1690         struct hdmi *hdmi = hdmi_dev->hdmi;
1691         char phy_pol = hdmi_readl(hdmi_dev, PHY_POL0);
1692         char phy_status = hdmi_readl(hdmi_dev, PHY_STAT0);
1693         char phy_int0 = hdmi_readl(hdmi_dev, PHY_INI0);
1694         /*read interrupt*/
1695         char fc_stat0 = hdmi_readl(hdmi_dev, IH_FC_STAT0);
1696         char fc_stat1 = hdmi_readl(hdmi_dev, IH_FC_STAT1);
1697         char fc_stat2 = hdmi_readl(hdmi_dev, IH_FC_STAT2);
1698         char aud_int = hdmi_readl(hdmi_dev, IH_AS_SATA0);
1699         char phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0);
1700         char vp_stat0 = hdmi_readl(hdmi_dev, IH_VP_STAT0);
1701         char cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0);
1702         char hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
1703         char hdcp2_int = hdmi_readl(hdmi_dev, HDCP2REG_STAT);
1704
1705         /*clear interrupt*/
1706         hdmi_writel(hdmi_dev, IH_FC_STAT0, fc_stat0);
1707         hdmi_writel(hdmi_dev, IH_FC_STAT1, fc_stat1);
1708         hdmi_writel(hdmi_dev, IH_FC_STAT2, fc_stat2);
1709         hdmi_writel(hdmi_dev, IH_VP_STAT0, vp_stat0);
1710
1711         if (phy_int0 || phy_int) {
1712                 phy_pol = (phy_int0 & (~phy_status)) | ((~phy_int0) & phy_pol);
1713                 hdmi_writel(hdmi_dev, PHY_POL0, phy_pol);
1714                 hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int);
1715                 if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c))
1716                         hdmi_submit_work(hdmi, HDMI_HPD_CHANGE, 20, NULL);
1717         }
1718
1719         /* Audio error */
1720         if (aud_int) {
1721                 hdmi_writel(hdmi_dev, IH_AS_SATA0, aud_int);
1722                 hdmi_msk_reg(hdmi_dev, AUD_CONF0,
1723                              m_SW_AUD_FIFO_RST, v_SW_AUD_FIFO_RST(1));
1724                 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xF7);
1725         }
1726         /* CEC */
1727         if (cec_int) {
1728                 hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int);
1729                 rockchip_hdmiv2_cec_isr(hdmi_dev, cec_int);
1730         }
1731         /* HDCP */
1732         if (hdcp_int) {
1733                 hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
1734                 pr_info("hdcp_int is 0x%02x\n", hdcp_int);
1735         }
1736
1737         /* HDCP2 */
1738         if (hdcp2_int) {
1739                 hdmi_writel(hdmi_dev, HDCP2REG_STAT, hdcp2_int);
1740                 pr_info("hdcp2_int is 0x%02x\n", hdcp2_int);
1741         }
1742         return IRQ_HANDLED;
1743 }