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