Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmiv2 / rockchip_hdmiv2.c
1 #include <linux/kernel.h>
2 #include <linux/delay.h>
3 #include <linux/module.h>
4 #include <linux/platform_device.h>
5 #include <linux/pm_runtime.h>
6 #include <linux/interrupt.h>
7 #include <linux/clk.h>
8 #include <linux/of_gpio.h>
9 #include <linux/rockchip/cpu.h>
10 #include <linux/rockchip/grf.h>
11 #include <linux/rockchip/iomap.h>
12 #include <linux/mfd/syscon.h>
13 #if defined(CONFIG_DEBUG_FS)
14 #include <linux/uaccess.h>
15 #include <linux/fs.h>
16 #include <linux/debugfs.h>
17 #include <linux/seq_file.h>
18 #endif
19
20 #include "rockchip_hdmiv2.h"
21 #include "rockchip_hdmiv2_hw.h"
22
23 #define HDMI_SEL_LCDC(x, bit)   ((((x) & 1) << bit) | (1 << (16 + bit)))
24 #define grf_writel(v, offset)   writel_relaxed(v, RK_GRF_VIRT + offset)
25 #define GRF_SOC_CON20 0x6250
26
27 static struct hdmi_dev *hdmi_dev;
28
29 static struct hdmi_property rk_hdmi_property = {
30         .videosrc = DISPLAY_SOURCE_LCDC0,
31         .display = DISPLAY_MAIN,
32 };
33
34 #if defined(CONFIG_DEBUG_FS)
35 static const struct rockchip_hdmiv2_reg_table hdmi_reg_table[] = {
36         {IDENTIFICATION_BASE, CONFIG3_ID},
37         {INTERRUPT_BASE, IH_MUTE},
38         {VIDEO_SAMPLER_BASE, TX_BCBDATA1},
39         {VIDEO_PACKETIZER_BASE, VP_MASK},
40         {FRAME_COMPOSER_BASE, FC_DBGTMDS2},
41         {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2},
42         {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD},
43         {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0},
44         {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2},
45         {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2},
46         {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST},
47         {HDCP_BKSV_BASE, HDCPREG_BKSV4},
48         {HDCP_AN_BASE, HDCPREG_AN7},
49         {HDCP2REG_BASE, HDCP2REG_MUTE},
50         {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6},
51         {CEC_ENGINE_BASE, CEC_WKUPCTRL},
52         {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1},
53 };
54
55 static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
56 {
57         u32 i = 0, j = 0, val = 0;
58
59         seq_puts(s, "\n>>>hdmi_ctl reg ");
60         for (i = 0; i < 16; i++)
61                 seq_printf(s, " %2x", i);
62         seq_puts(s, "\n-----------------------------------------------------------------");
63
64         for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); i++) {
65                 for (j = hdmi_reg_table[i].reg_base;
66                      j <= hdmi_reg_table[i].reg_end; j++) {
67                         val = hdmi_readl(hdmi_dev, j);
68                         if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
69                                 seq_printf(s, "\n>>>hdmi_ctl %04x:", j);
70                         seq_printf(s, " %02x", val);
71                 }
72         }
73         seq_puts(s, "\n-----------------------------------------------------------------\n");
74
75         return 0;
76 }
77
78 static ssize_t hdmi_regs_ctrl_write(struct file *file,
79                                     const char __user *buf,
80                                     size_t count, loff_t *ppos)
81 {
82         u32 reg, val;
83         char kbuf[25];
84
85         if (copy_from_user(kbuf, buf, count))
86                 return -EFAULT;
87         if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
88                 return -EFAULT;
89         if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
90                 dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n");
91                 return count;
92         }
93         dev_info(hdmi_dev->hdmi->dev,
94                  "/**********hdmi reg config******/");
95         dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
96         hdmi_writel(hdmi_dev, reg, val);
97
98         return count;
99 }
100
101 static int hdmi_regs_phy_show(struct seq_file *s, void *v)
102 {
103         u32 i, count;
104
105         if (hdmi_dev->soctype == HDMI_SOC_RK322X)
106                 count = 0xff;
107         else
108                 count = 0x28;
109         seq_puts(s, "\n>>>hdmi_phy reg ");
110         for (i = 0; i < count; i++)
111                 seq_printf(s, "regs %02x val %04x\n",
112                            i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
113         return 0;
114 }
115
116 static ssize_t hdmi_regs_phy_write(struct file *file,
117                                    const char __user *buf,
118                                    size_t count, loff_t *ppos)
119 {
120         u32 reg, val;
121         char kbuf[25];
122
123         if (copy_from_user(kbuf, buf, count))
124                 return -EFAULT;
125         if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
126                 return -EFAULT;
127         dev_info(hdmi_dev->hdmi->dev,
128                  "/**********hdmi reg phy config******/");
129         dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
130         rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
131         return count;
132 }
133
134 #define HDMI_DEBUG_ENTRY(name) \
135 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
136 { \
137         return single_open(file, hdmi_##name##_show, inode->i_private); \
138 } \
139 \
140 static const struct file_operations hdmi_##name##_fops = { \
141         .owner = THIS_MODULE, \
142         .open = hdmi_##name##_open, \
143         .read = seq_read, \
144         .write = hdmi_##name##_write,   \
145         .llseek = seq_lseek, \
146         .release = single_release, \
147 }
148
149 HDMI_DEBUG_ENTRY(regs_phy);
150 HDMI_DEBUG_ENTRY(regs_ctrl);
151 #endif
152
153 #ifdef CONFIG_HAS_EARLYSUSPEND
154 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
155 {
156         struct hdmi *hdmi = hdmi_dev->hdmi;
157         struct pinctrl_state *gpio_state;
158
159         HDMIDBG("hdmi enter early suspend\n");
160         hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
161         /* iomux to gpio and pull down when suspend */
162         gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
163         pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
164         rockchip_hdmiv2_clk_disable(hdmi_dev);
165 }
166
167 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
168 {
169         struct hdmi *hdmi = hdmi_dev->hdmi;
170
171         HDMIDBG("hdmi exit early resume\n");
172         /* iomux to default state for hdmi use when resume */
173         pinctrl_select_state(hdmi_dev->dev->pins->p,
174                              hdmi_dev->dev->pins->default_state);
175         rockchip_hdmiv2_clk_enable(hdmi_dev);
176         hdmi_dev_initial(hdmi_dev);
177         if (hdmi->ops->hdcp_power_on_cb)
178                 hdmi->ops->hdcp_power_on_cb();
179         hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
180 }
181 #endif
182
183 void ext_pll_set_27m_out(void)
184 {
185         if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X)
186                 return;
187         /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */
188         rockchip_hdmiv2_write_phy(hdmi_dev,
189                                   EXT_PHY_PLL_PRE_DIVIDER,
190                                   1);
191         rockchip_hdmiv2_write_phy(hdmi_dev,
192                                   EXT_PHY_PLL_FB_DIVIDER,
193                                   45);
194         rockchip_hdmiv2_write_phy(hdmi_dev,
195                                   EXT_PHY_PCLK_DIVIDER1,
196                                   0x61);
197         rockchip_hdmiv2_write_phy(hdmi_dev,
198                                   EXT_PHY_PCLK_DIVIDER2,
199                                   0x64);
200         rockchip_hdmiv2_write_phy(hdmi_dev,
201                                   EXT_PHY_TMDSCLK_DIVIDER,
202                                   0x1d);
203 }
204
205 #define HDMI_PD_ON              BIT(0)
206 #define HDMI_PCLK_ON            BIT(1)
207 #define HDMI_HDCPCLK_ON         BIT(2)
208 #define HDMI_CECCLK_ON          BIT(3)
209 #define HDMI_EXT_PHY_CLK_ON     BIT(4)
210
211 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
212 {
213         if (hdmi_dev->soctype == HDMI_SOC_RK322X ||
214             hdmi_dev->soctype == HDMI_SOC_RK3366 ||
215             hdmi_dev->soctype == HDMI_SOC_RK3399) {
216                 if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) == 0) {
217                         if (!hdmi_dev->pclk_phy) {
218                                 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
219                                         hdmi_dev->pclk_phy =
220                                                 devm_clk_get(hdmi_dev->dev,
221                                                              "pclk_hdmi_phy");
222                                 else
223                                         hdmi_dev->pclk_phy =
224                                                 devm_clk_get(hdmi_dev->dev,
225                                                              "dclk_hdmi_phy");
226                                 if (IS_ERR(hdmi_dev->pclk_phy)) {
227                                         dev_err(hdmi_dev->dev,
228                                                 "get hdmi phy pclk error\n");
229                                         return -1;
230                                 }
231                         }
232                         clk_prepare_enable(hdmi_dev->pclk_phy);
233                         hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON;
234                 }
235         } else if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
236                 pm_runtime_get_sync(hdmi_dev->dev);
237                 hdmi_dev->clk_on |= HDMI_PD_ON;
238         }
239
240         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
241                 if (!hdmi_dev->pclk) {
242                         hdmi_dev->pclk =
243                                 devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
244                         if (IS_ERR(hdmi_dev->pclk)) {
245                                 dev_err(hdmi_dev->dev,
246                                         "Unable to get hdmi pclk\n");
247                                 return -1;
248                         }
249                 }
250                 clk_prepare_enable(hdmi_dev->pclk);
251                 hdmi_dev->clk_on |= HDMI_PCLK_ON;
252         }
253
254         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
255                 if (!hdmi_dev->hdcp_clk) {
256                         hdmi_dev->hdcp_clk =
257                                 devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
258                         if (IS_ERR(hdmi_dev->hdcp_clk)) {
259                                 dev_err(hdmi_dev->dev,
260                                         "Unable to get hdmi hdcp_clk\n");
261                                 return -1;
262                         }
263                 }
264                 clk_prepare_enable(hdmi_dev->hdcp_clk);
265                 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
266         }
267
268         if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
269             (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
270                 if (!hdmi_dev->cec_clk) {
271                         hdmi_dev->cec_clk =
272                                 devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
273                         if (IS_ERR(hdmi_dev->cec_clk)) {
274                                 dev_err(hdmi_dev->dev,
275                                         "Unable to get hdmi cec_clk\n");
276                                 return -1;
277                         }
278                 }
279                 clk_prepare_enable(hdmi_dev->cec_clk);
280                 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
281         }
282         return 0;
283 }
284
285 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
286 {
287         if (hdmi_dev->clk_on == 0)
288                 return 0;
289
290         if ((hdmi_dev->clk_on & HDMI_PD_ON)) {
291                 pm_runtime_put(hdmi_dev->dev);
292                 hdmi_dev->clk_on &= ~HDMI_PD_ON;
293         }
294
295         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
296             (hdmi_dev->pclk)) {
297                 clk_disable_unprepare(hdmi_dev->pclk);
298                 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
299         }
300
301         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
302             (hdmi_dev->hdcp_clk)) {
303                 clk_disable_unprepare(hdmi_dev->hdcp_clk);
304                 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
305         }
306
307         if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) &&
308             hdmi_dev->pclk_phy) {
309                 clk_disable_unprepare(hdmi_dev->pclk_phy);
310                 hdmi_dev->clk_on &= ~HDMI_EXT_PHY_CLK_ON;
311         }
312         return 0;
313 }
314
315 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
316                                            unsigned long action, void *data)
317 {
318         struct fb_event *event = data;
319         int blank_mode = *((int *)event->data);
320         struct hdmi *hdmi = hdmi_dev->hdmi;
321         struct pinctrl_state *gpio_state;
322 #ifdef CONFIG_PINCTRL
323         struct dev_pin_info *pins = hdmi_dev->dev->pins;
324 #endif
325
326         if (action == FB_EARLY_EVENT_BLANK) {
327                 switch (blank_mode) {
328                 case FB_BLANK_UNBLANK:
329                         break;
330                 default:
331                         HDMIDBG("suspend hdmi\n");
332                         if (!hdmi->sleep) {
333                                 hdmi_submit_work(hdmi,
334                                                  HDMI_SUSPEND_CTL,
335                                                  0, 1);
336                                 if (hdmi_dev->hdcp2_en)
337                                         hdmi_dev->hdcp2_en(0);
338                                 rockchip_hdmiv2_clk_disable(hdmi_dev);
339                                 #ifdef CONFIG_PINCTRL
340                                 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
341                                         gpio_state =
342                                         pinctrl_lookup_state(pins->p,
343                                                              "sleep");
344                                 else
345                                         gpio_state =
346                                         pinctrl_lookup_state(pins->p,
347                                                              "gpio");
348                                 pinctrl_select_state(pins->p,
349                                                      gpio_state);
350                                 #endif
351                         }
352                         break;
353                 }
354         } else if (action == FB_EVENT_BLANK) {
355                 switch (blank_mode) {
356                 case FB_BLANK_UNBLANK:
357                         HDMIDBG("resume hdmi\n");
358                         if (hdmi->sleep) {
359                                 #ifdef CONFIG_PINCTRL
360                                 pinctrl_select_state(pins->p,
361                                                      pins->default_state);
362                                 #endif
363                                 rockchip_hdmiv2_clk_enable(hdmi_dev);
364                                 rockchip_hdmiv2_dev_initial(hdmi_dev);
365                                 if (hdmi->ops->hdcp_power_on_cb)
366                                         hdmi->ops->hdcp_power_on_cb();
367                                 if (hdmi_dev->hdcp2_reset)
368                                         hdmi_dev->hdcp2_reset();
369                                 if (hdmi_dev->hdcp2_en)
370                                         hdmi_dev->hdcp2_en(1);
371                                 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
372                                                  0, 0);
373                         }
374                         break;
375                 default:
376                         break;
377                 }
378         }
379         return NOTIFY_OK;
380 }
381
382 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
383         .notifier_call = rockchip_hdmiv2_fb_event_notify,
384 };
385
386 #ifdef HDMI_INT_USE_POLL
387 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
388 {
389         if (hdmi_dev->enable) {
390                 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
391                 queue_delayed_work(hdmi_dev->workqueue,
392                                    &hdmi_dev->delay_work,
393                                    msecs_to_jiffies(50));
394         }
395 }
396 #endif
397
398 static struct hdmi_ops rk_hdmi_ops;
399
400 #if defined(CONFIG_OF)
401 static const struct of_device_id rk_hdmi_dt_ids[] = {
402         {.compatible = "rockchip,rk322x-hdmi",},
403         {.compatible = "rockchip,rk3288-hdmi",},
404         {.compatible = "rockchip,rk3366-hdmi",},
405         {.compatible = "rockchip,rk3368-hdmi",},
406         {.compatible = "rockchip,rk3399-hdmi",},
407         {}
408 };
409
410 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
411 {
412         int val = 0;
413         struct device_node *np = hdmi_dev->dev->of_node;
414         const struct of_device_id *match;
415
416         match = of_match_node(rk_hdmi_dt_ids, np);
417         if (!match)
418                 return PTR_ERR(match);
419
420         if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
421                 hdmi_dev->soctype = HDMI_SOC_RK3288;
422         } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
423                 hdmi_dev->soctype = HDMI_SOC_RK3368;
424         } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) {
425                 hdmi_dev->soctype = HDMI_SOC_RK322X;
426         } else if (!strcmp(match->compatible, "rockchip,rk3366-hdmi")) {
427                 hdmi_dev->soctype = HDMI_SOC_RK3366;
428         } else if (!strcmp(match->compatible, "rockchip,rk3399-hdmi")) {
429                 hdmi_dev->soctype = HDMI_SOC_RK3399;
430         } else {
431                 pr_err("It is not a valid rockchip soc!");
432                 return -ENOMEM;
433         }
434
435         if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
436                 rk_hdmi_property.videosrc = val;
437
438         if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
439                 hdmi_dev->audiosrc = val;
440
441         if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
442             (val == 1)) {
443                 pr_debug("hdmi support cec\n");
444                 rk_hdmi_property.feature |= SUPPORT_CEC;
445         }
446         if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
447             (val == 1)) {
448                 pr_debug("hdmi support hdcp\n");
449                 rk_hdmi_property.feature |= SUPPORT_HDCP;
450         }
451         if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
452             (val > 0)) {
453                 pr_debug("default mode is %d\n", val);
454                 rk_hdmi_property.defaultmode = val;
455         } else {
456                 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
457         }
458         if (of_get_property(np, "rockchip,phy_table", &val)) {
459                 hdmi_dev->phy_table = kmalloc(val, GFP_KERNEL);
460                 if (!hdmi_dev->phy_table) {
461                         pr_err("kmalloc phy table %d error\n", val);
462                         return -ENOMEM;
463                 }
464                 hdmi_dev->phy_table_size =
465                                 val / sizeof(struct hdmi_dev_phy_para);
466                 of_property_read_u32_array(np, "rockchip,phy_table",
467                                            (u32 *)hdmi_dev->phy_table,
468                                            val / sizeof(u32));
469         } else {
470                 pr_info("hdmi phy_table not exist\n");
471         }
472
473         of_property_read_string(np, "rockchip,vendor",
474                                 &hdmi_dev->vendor_name);
475         of_property_read_string(np, "rockchip,product",
476                                 &hdmi_dev->product_name);
477         if (!of_property_read_u32(np, "rockchip,deviceinfo", &val))
478                 hdmi_dev->deviceinfo = val & 0xff;
479
480         #ifdef CONFIG_MFD_SYSCON
481         hdmi_dev->grf_base =
482                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
483         if (IS_ERR(hdmi_dev->grf_base)) {
484                 hdmi_dev->grf_base = NULL;
485         }
486         #endif
487         return 0;
488 }
489 #endif
490
491 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
492 {
493         int ret = -1;
494         struct resource *res;
495
496         HDMIDBG("%s\n", __func__);
497         hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
498         if (!hdmi_dev) {
499                 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
500                 return -ENOMEM;
501         }
502         memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
503         platform_set_drvdata(pdev, hdmi_dev);
504         hdmi_dev->dev = &pdev->dev;
505
506         if (rockchip_hdmiv2_parse_dt(hdmi_dev))
507                 goto failed;
508
509         /*request and remap iomem*/
510         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
511         if (!res) {
512                 dev_err(&pdev->dev, "Unable to get register resource\n");
513                 ret = -ENXIO;
514                 goto failed;
515         }
516         hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
517         if (IS_ERR(hdmi_dev->regbase)) {
518                 ret = PTR_ERR(hdmi_dev->regbase);
519                 dev_err(&pdev->dev,
520                         "cannot ioremap registers,err=%d\n", ret);
521                 goto failed;
522         }
523         if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
524                 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
525                 if (!res) {
526                         dev_err(&pdev->dev,
527                                 "Unable to get phy register resource\n");
528                         ret = -ENXIO;
529                         goto failed;
530                 }
531                 hdmi_dev->phybase = devm_ioremap_resource(&pdev->dev, res);
532                 if (IS_ERR(hdmi_dev->phybase)) {
533                         ret = PTR_ERR(hdmi_dev->phybase);
534                         dev_err(&pdev->dev,
535                                 "cannot ioremap registers,err=%d\n", ret);
536                         goto failed;
537                 }
538         }
539
540         hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi");
541         if (IS_ERR(hdmi_dev->reset) &&
542             hdmi_dev->soctype != HDMI_SOC_RK3288) {
543                 ret = PTR_ERR(hdmi_dev->reset);
544                 dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret);
545                 goto failed;
546         }
547         pm_runtime_enable(hdmi_dev->dev);
548         /*enable pd and pclk and hdcp_clk*/
549         if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
550                 dev_err(&pdev->dev, "failed to enable hdmi clk\n");
551                 ret = -ENXIO;
552                 goto failed1;
553         }
554         /*lcdc source select*/
555         if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
556                 grf_writel(HDMI_SEL_LCDC(rk_hdmi_property.videosrc, 4),
557                            RK3288_GRF_SOC_CON6);
558                 /* select GPIO7_C0 as cec pin */
559                 grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
560         } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
561                 regmap_write(hdmi_dev->grf_base,
562                              GRF_SOC_CON20,
563                              HDMI_SEL_LCDC(rk_hdmi_property.videosrc, 6));
564         }
565         rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
566         /* Register HDMI device */
567         rk_hdmi_property.name = (char *)pdev->name;
568         rk_hdmi_property.priv = hdmi_dev;
569         if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
570                 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
571                 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
572                         rk_hdmi_property.feature |=
573                                                 SUPPORT_4K |
574                                                 SUPPORT_TMDS_600M;
575         } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
576                 rk_hdmi_property.feature |=
577                                 SUPPORT_4K |
578                                 SUPPORT_4K_4096 |
579                                 SUPPORT_YUV420 |
580                                 SUPPORT_YCBCR_INPUT |
581                                 SUPPORT_VESA_DMT;
582         } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
583                 rk_hdmi_property.feature |=
584                                 SUPPORT_4K |
585                                 SUPPORT_4K_4096 |
586                                 SUPPORT_YCBCR_INPUT |
587                                 SUPPORT_1080I |
588                                 SUPPORT_480I_576I;
589                 /*
590                  *if (rockchip_get_cpu_version())
591                  *      rk_hdmi_property.feature |=
592                  *              SUPPORT_YUV420 |
593                  *              SUPPORT_DEEP_10BIT;
594                  */
595         } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
596                 rk_hdmi_property.feature |=
597                                 SUPPORT_YCBCR_INPUT |
598                                 SUPPORT_1080I |
599                                 SUPPORT_480I_576I;
600                 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
601                         rk_hdmi_property.feature |=
602                                                 SUPPORT_4K |
603                                                 SUPPORT_4K_4096 |
604                                                 SUPPORT_YUV420 |
605                                                 SUPPORT_YCBCR_INPUT |
606                                                 SUPPORT_TMDS_600M;
607         } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
608                 rk_hdmi_property.feature |=
609                                 SUPPORT_DEEP_10BIT |
610                                 SUPPORT_YCBCR_INPUT |
611                                 SUPPORT_1080I |
612                                 SUPPORT_480I_576I;
613                 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
614                         rk_hdmi_property.feature |=
615                                                 SUPPORT_4K |
616                                                 SUPPORT_4K_4096 |
617                                                 SUPPORT_YUV420 |
618                                                 SUPPORT_YCBCR_INPUT |
619                                                 SUPPORT_TMDS_600M;
620         } else {
621                 ret = -ENXIO;
622                 goto failed1;
623         }
624         hdmi_dev->hdmi =
625                 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
626         if (!hdmi_dev->hdmi) {
627                 dev_err(&pdev->dev, "register hdmi device failed\n");
628                 ret = -ENOMEM;
629                 goto failed1;
630         }
631         mutex_init(&hdmi_dev->ddc_lock);
632         hdmi_dev->hdmi->dev = &pdev->dev;
633         hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
634         fb_register_client(&rockchip_hdmiv2_fb_notifier);
635         rockchip_hdmiv2_dev_initial(hdmi_dev);
636         pinctrl_select_state(hdmi_dev->dev->pins->p,
637                              hdmi_dev->dev->pins->default_state);
638 #if defined(CONFIG_DEBUG_FS)
639         hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
640         if (IS_ERR(hdmi_dev->debugfs_dir))
641                 dev_err(hdmi_dev->hdmi->dev,
642                         "failed to create debugfs dir for rockchip hdmiv2!\n");
643         else {
644                 debugfs_create_file("regs_ctrl", S_IRUSR,
645                                     hdmi_dev->debugfs_dir,
646                                     hdmi_dev, &hdmi_regs_ctrl_fops);
647                 debugfs_create_file("regs_phy", S_IRUSR,
648                                     hdmi_dev->debugfs_dir,
649                                     hdmi_dev, &hdmi_regs_phy_fops);
650         }
651 #endif
652
653 #ifndef HDMI_INT_USE_POLL
654         /* get and request the IRQ */
655         hdmi_dev->irq = platform_get_irq(pdev, 0);
656         if (hdmi_dev->irq <= 0) {
657                 dev_err(hdmi_dev->dev,
658                         "failed to get hdmi irq resource (%d).\n",
659                         hdmi_dev->irq);
660                 ret = -ENXIO;
661                 goto failed1;
662         }
663
664         ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
665                                rockchip_hdmiv2_dev_irq,
666                                IRQF_TRIGGER_HIGH,
667                                dev_name(hdmi_dev->dev), hdmi_dev);
668         if (ret) {
669                 dev_err(hdmi_dev->dev,
670                         "hdmi request_irq failed (%d).\n",
671                         ret);
672                 goto failed1;
673         }
674 #else
675         hdmi_dev->workqueue =
676                 create_singlethread_workqueue("rockchip hdmiv2 irq");
677         INIT_DELAYED_WORK(&hdmi_dev->delay_work,
678                           rockchip_hdmiv2_irq_work_func);
679         rockchip_hdmiv2_irq_work_func(NULL);
680
681 #endif
682         rk_display_device_enable(hdmi_dev->hdmi->ddev);
683         dev_info(&pdev->dev, "rockchip hdmiv2 probe success.\n");
684         return 0;
685
686 failed1:
687         rockchip_hdmi_unregister(hdmi_dev->hdmi);
688 failed:
689         kfree(hdmi_dev->phy_table);
690         kfree(hdmi_dev);
691         hdmi_dev = NULL;
692         dev_err(&pdev->dev, "rockchip hdmiv2 probe error.\n");
693         return ret;
694 }
695
696 static int rockchip_hdmiv2_suspend(struct platform_device *pdev,
697                                    pm_message_t state)
698 {
699         if (hdmi_dev &&
700             hdmi_dev->grf_base &&
701             hdmi_dev->soctype == HDMI_SOC_RK322X) {
702                 regmap_write(hdmi_dev->grf_base,
703                              RK322X_GRF_SOC_CON2,
704                              RK322X_PLL_POWER_DOWN);
705         }
706         return 0;
707 }
708
709 static int rockchip_hdmiv2_resume(struct platform_device *pdev)
710 {
711         if (hdmi_dev &&
712             hdmi_dev->grf_base &&
713             hdmi_dev->soctype == HDMI_SOC_RK322X) {
714                 regmap_write(hdmi_dev->grf_base,
715                              RK322X_GRF_SOC_CON2,
716                              RK322X_PLL_POWER_UP);
717         }
718         return 0;
719 }
720
721 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
722 {
723         dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
724         return 0;
725 }
726
727 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
728 {
729         struct hdmi *hdmi;
730
731         if (hdmi_dev) {
732                 #ifdef CONFIG_HAS_EARLYSUSPEND
733                 unregister_early_suspend(&hdmi_dev->early_suspend);
734                 #endif
735                 hdmi = hdmi_dev->hdmi;
736                 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
737                     hdmi->ops->setmute)
738                         hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
739         }
740 }
741
742 static struct platform_driver rockchip_hdmiv2_driver = {
743         .probe          = rockchip_hdmiv2_probe,
744         .remove         = rockchip_hdmiv2_remove,
745         .driver         = {
746                 .name   = "rockchip-hdmiv2",
747                 .owner  = THIS_MODULE,
748                 #if defined(CONFIG_OF)
749                 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
750                 #endif
751         },
752         .suspend        = rockchip_hdmiv2_suspend,
753         .resume         = rockchip_hdmiv2_resume,
754         .shutdown       = rockchip_hdmiv2_shutdown,
755 };
756
757 static int __init rockchip_hdmiv2_init(void)
758 {
759         return platform_driver_register(&rockchip_hdmiv2_driver);
760 }
761
762 static void __exit rockchip_hdmiv2_exit(void)
763 {
764         platform_driver_unregister(&rockchip_hdmiv2_driver);
765 }
766
767 module_init(rockchip_hdmiv2_init);
768 module_exit(rockchip_hdmiv2_exit);