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>
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>
16 #include <linux/debugfs.h>
17 #include <linux/seq_file.h>
20 #include "rockchip_hdmiv2.h"
21 #include "rockchip_hdmiv2_hw.h"
23 static struct hdmi_dev *hdmi_dev;
25 static struct hdmi_property rk_hdmi_property = {
26 .videosrc = DISPLAY_SOURCE_LCDC0,
27 .display = DISPLAY_MAIN,
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},
51 static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
53 u32 i = 0, j = 0, val = 0;
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-----------------------------------------------------------------");
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);
69 seq_puts(s, "\n-----------------------------------------------------------------\n");
74 static ssize_t hdmi_regs_ctrl_write(struct file *file,
75 const char __user *buf,
76 size_t count, loff_t *ppos)
81 if (copy_from_user(kbuf, buf, count))
83 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
85 if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
86 dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n");
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);
97 static int hdmi_regs_phy_show(struct seq_file *s, void *v)
101 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
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));
112 static ssize_t hdmi_regs_phy_write(struct file *file,
113 const char __user *buf,
114 size_t count, loff_t *ppos)
119 if (copy_from_user(kbuf, buf, count))
121 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
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);
130 #define HDMI_DEBUG_ENTRY(name) \
131 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
133 return single_open(file, hdmi_##name##_show, inode->i_private); \
136 static const struct file_operations hdmi_##name##_fops = { \
137 .owner = THIS_MODULE, \
138 .open = hdmi_##name##_open, \
140 .write = hdmi_##name##_write, \
141 .llseek = seq_lseek, \
142 .release = single_release, \
145 HDMI_DEBUG_ENTRY(regs_phy);
146 HDMI_DEBUG_ENTRY(regs_ctrl);
149 #ifdef CONFIG_HAS_EARLYSUSPEND
150 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
152 struct hdmi *hdmi = hdmi_dev->hdmi;
153 struct pinctrl_state *gpio_state;
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);
163 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
165 struct hdmi *hdmi = hdmi_dev->hdmi;
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);
179 void ext_pll_set_27m_out(void)
181 if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X)
183 /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */
184 rockchip_hdmiv2_write_phy(hdmi_dev,
185 EXT_PHY_PLL_PRE_DIVIDER,
187 rockchip_hdmiv2_write_phy(hdmi_dev,
188 EXT_PHY_PLL_FB_DIVIDER,
190 rockchip_hdmiv2_write_phy(hdmi_dev,
191 EXT_PHY_PCLK_DIVIDER1,
193 rockchip_hdmiv2_write_phy(hdmi_dev,
194 EXT_PHY_PCLK_DIVIDER2,
196 rockchip_hdmiv2_write_phy(hdmi_dev,
197 EXT_PHY_TMDSCLK_DIVIDER,
201 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
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;
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)
215 devm_clk_get(hdmi_dev->dev,
219 devm_clk_get(hdmi_dev->dev,
221 if (IS_ERR(hdmi_dev->pclk_phy)) {
222 dev_err(hdmi_dev->dev,
223 "get hdmi phy pclk error\n");
227 clk_prepare_enable(hdmi_dev->pclk_phy);
228 hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON;
231 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
232 if (!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");
241 clk_prepare_enable(hdmi_dev->pclk);
242 hdmi_dev->clk_on |= HDMI_PCLK_ON;
245 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
246 if (!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");
255 clk_prepare_enable(hdmi_dev->hdcp_clk);
256 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
259 if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
260 (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
261 if (!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");
270 clk_prepare_enable(hdmi_dev->cec_clk);
271 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
274 if ((hdmi_dev->clk_on & HDMI_SFRCLK_ON) == 0) {
275 if (!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");
284 clk_prepare_enable(hdmi_dev->sfr_clk);
285 hdmi_dev->clk_on |= HDMI_SFRCLK_ON;
291 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
293 if (hdmi_dev->clk_on == 0)
296 if ((hdmi_dev->clk_on & HDMI_PD_ON)) {
297 pm_runtime_put(hdmi_dev->dev);
298 hdmi_dev->clk_on &= ~HDMI_PD_ON;
301 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
303 clk_disable_unprepare(hdmi_dev->pclk);
304 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
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;
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;
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;
329 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
330 unsigned long action, void *data)
332 struct fb_event *event = data;
333 struct hdmi *hdmi = hdmi_dev->hdmi;
334 struct pinctrl_state *gpio_state;
335 #ifdef CONFIG_PINCTRL
336 struct dev_pin_info *pins = hdmi_dev->dev->pins;
339 if (action == FB_EARLY_EVENT_BLANK) {
340 switch (*((int *)event->data)) {
341 case FB_BLANK_UNBLANK:
344 HDMIDBG("suspend hdmi\n");
346 hdmi_submit_work(hdmi,
349 if (hdmi_dev->hdcp2_en)
350 hdmi_dev->hdcp2_en(0);
351 mutex_lock(&hdmi->pclk_lock);
352 rockchip_hdmiv2_clk_disable(hdmi_dev);
353 mutex_unlock(&hdmi->pclk_lock);
354 #ifdef CONFIG_PINCTRL
355 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
357 pinctrl_lookup_state(pins->p,
361 pinctrl_lookup_state(pins->p,
363 pinctrl_select_state(pins->p,
369 } else if (action == FB_EVENT_BLANK) {
370 switch (*((int *)event->data)) {
371 case FB_BLANK_UNBLANK:
372 HDMIDBG("resume hdmi\n");
374 #ifdef CONFIG_PINCTRL
375 pinctrl_select_state(pins->p,
376 pins->default_state);
378 mutex_lock(&hdmi->pclk_lock);
379 rockchip_hdmiv2_clk_enable(hdmi_dev);
380 mutex_unlock(&hdmi->pclk_lock);
381 rockchip_hdmiv2_dev_initial(hdmi_dev);
382 if (hdmi->ops->hdcp_power_on_cb)
383 hdmi->ops->hdcp_power_on_cb();
384 if (hdmi_dev->hdcp2_reset)
385 hdmi_dev->hdcp2_reset();
386 if (hdmi_dev->hdcp2_en)
387 hdmi_dev->hdcp2_en(1);
388 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
399 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
400 .notifier_call = rockchip_hdmiv2_fb_event_notify,
403 #ifdef HDMI_INT_USE_POLL
404 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
406 if (hdmi_dev->enable) {
407 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
408 queue_delayed_work(hdmi_dev->workqueue,
409 &hdmi_dev->delay_work,
410 msecs_to_jiffies(50));
415 static struct hdmi_ops rk_hdmi_ops;
417 #if defined(CONFIG_OF)
418 static const struct of_device_id rk_hdmi_dt_ids[] = {
419 {.compatible = "rockchip,rk322x-hdmi",},
420 {.compatible = "rockchip,rk3288-hdmi",},
421 {.compatible = "rockchip,rk3366-hdmi",},
422 {.compatible = "rockchip,rk3368-hdmi",},
423 {.compatible = "rockchip,rk3399-hdmi",},
427 static int hdmi_get_prop_dts(struct hdmi *hdmi, struct device_node *np)
429 const struct property *prop;
430 int i = 0, nstates = 0;
433 struct edid_prop_value *pval = NULL;
436 pr_info("%s:line=%d hdmi or np is null\n", __func__, __LINE__);
440 if (!of_property_read_u32(np, "hdmi_edid_auto_support", &value))
441 hdmi->edid_auto_support = value;
443 prop = of_find_property(np, "hdmi_edid_prop_value", NULL);
444 if (!prop || !prop->value) {
445 pr_info("%s:No edid-prop-value, %d\n", __func__, !prop);
449 nstates = (prop->length / sizeof(struct edid_prop_value));
450 pval = kcalloc(nstates, sizeof(struct edid_prop_value), GFP_NOWAIT);
452 for (i = 0, val = prop->value; i < nstates; i++) {
453 pval[i].vid = be32_to_cpup(val++);
454 pval[i].pid = be32_to_cpup(val++);
455 pval[i].sn = be32_to_cpup(val++);
456 pval[i].xres = be32_to_cpup(val++);
457 pval[i].yres = be32_to_cpup(val++);
458 pval[i].vic = be32_to_cpup(val++);
459 pval[i].width = be32_to_cpup(val++);
460 pval[i].height = be32_to_cpup(val++);
461 pval[i].x_w = be32_to_cpup(val++);
462 pval[i].x_h = be32_to_cpup(val++);
463 pval[i].hwrotation = be32_to_cpup(val++);
464 pval[i].einit = be32_to_cpup(val++);
465 pval[i].vsync = be32_to_cpup(val++);
466 pval[i].panel = be32_to_cpup(val++);
467 pval[i].scan = be32_to_cpup(val++);
469 pr_info("%s: 0x%x 0x%x 0x%x %d %d %d %d %d %d %d %d %d %d %d %d\n",
470 __func__, pval[i].vid, pval[i].pid, pval[i].sn,
471 pval[i].width, pval[i].height, pval[i].xres,
472 pval[i].yres, pval[i].vic, pval[i].x_w,
473 pval[i].x_h, pval[i].hwrotation, pval[i].einit,
474 pval[i].vsync, pval[i].panel, pval[i].scan);
478 hdmi->nstates = nstates;
483 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
486 struct device_node *np = hdmi_dev->dev->of_node;
487 const struct of_device_id *match;
489 match = of_match_node(rk_hdmi_dt_ids, np);
491 return PTR_ERR(match);
493 if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
494 hdmi_dev->soctype = HDMI_SOC_RK3288;
495 } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
496 hdmi_dev->soctype = HDMI_SOC_RK3368;
497 } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) {
498 hdmi_dev->soctype = HDMI_SOC_RK322X;
499 } else if (!strcmp(match->compatible, "rockchip,rk3366-hdmi")) {
500 hdmi_dev->soctype = HDMI_SOC_RK3366;
501 } else if (!strcmp(match->compatible, "rockchip,rk3399-hdmi")) {
502 hdmi_dev->soctype = HDMI_SOC_RK3399;
504 pr_err("It is not a valid rockchip soc!");
508 if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
509 rk_hdmi_property.videosrc = val;
511 if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
512 hdmi_dev->audiosrc = val;
514 if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
516 pr_debug("hdmi support cec\n");
517 rk_hdmi_property.feature |= SUPPORT_CEC;
519 if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
521 pr_debug("hdmi support hdcp\n");
522 rk_hdmi_property.feature |= SUPPORT_HDCP;
524 if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
526 pr_debug("default mode is %d\n", val);
527 rk_hdmi_property.defaultmode = val;
529 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
531 if (of_get_property(np, "rockchip,phy_table", &val)) {
532 hdmi_dev->phy_table = kmalloc(val, GFP_KERNEL);
533 if (!hdmi_dev->phy_table) {
534 pr_err("kmalloc phy table %d error\n", val);
537 hdmi_dev->phy_table_size =
538 val / sizeof(struct hdmi_dev_phy_para);
539 of_property_read_u32_array(np, "rockchip,phy_table",
540 (u32 *)hdmi_dev->phy_table,
543 pr_info("hdmi phy_table not exist\n");
546 of_property_read_string(np, "rockchip,vendor",
547 &hdmi_dev->vendor_name);
548 of_property_read_string(np, "rockchip,product",
549 &hdmi_dev->product_name);
550 if (!of_property_read_u32(np, "rockchip,deviceinfo", &val))
551 hdmi_dev->deviceinfo = val & 0xff;
553 #ifdef CONFIG_MFD_SYSCON
555 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
556 if (IS_ERR(hdmi_dev->grf_base)) {
557 hdmi_dev->grf_base = NULL;
564 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
567 struct resource *res;
569 HDMIDBG("%s\n", __func__);
570 hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
572 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
575 memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
576 platform_set_drvdata(pdev, hdmi_dev);
577 hdmi_dev->dev = &pdev->dev;
579 if (rockchip_hdmiv2_parse_dt(hdmi_dev))
582 /*request and remap iomem*/
583 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
585 dev_err(&pdev->dev, "Unable to get register resource\n");
589 hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
590 if (IS_ERR(hdmi_dev->regbase)) {
591 ret = PTR_ERR(hdmi_dev->regbase);
593 "cannot ioremap registers,err=%d\n", ret);
596 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
597 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
600 "Unable to get phy register resource\n");
604 hdmi_dev->phybase = devm_ioremap_resource(&pdev->dev, res);
605 if (IS_ERR(hdmi_dev->phybase)) {
606 ret = PTR_ERR(hdmi_dev->phybase);
608 "cannot ioremap registers,err=%d\n", ret);
613 hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi");
614 if (IS_ERR(hdmi_dev->reset) &&
615 hdmi_dev->soctype != HDMI_SOC_RK3288) {
616 ret = PTR_ERR(hdmi_dev->reset);
617 dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret);
620 pm_runtime_enable(hdmi_dev->dev);
621 /*enable pd and clk*/
622 if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
623 dev_err(&pdev->dev, "failed to enable hdmi clk\n");
627 rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
628 /* Register HDMI device */
629 rk_hdmi_property.name = (char *)pdev->name;
630 rk_hdmi_property.priv = hdmi_dev;
631 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
632 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
633 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
634 rk_hdmi_property.feature |=
637 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
638 rk_hdmi_property.feature |=
642 SUPPORT_YCBCR_INPUT |
644 } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
645 rk_hdmi_property.feature |=
648 SUPPORT_YCBCR_INPUT |
652 *if (rockchip_get_cpu_version())
653 * rk_hdmi_property.feature |=
655 * SUPPORT_DEEP_10BIT;
657 } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
658 rk_hdmi_property.feature |=
659 SUPPORT_YCBCR_INPUT |
662 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
663 rk_hdmi_property.feature |=
667 SUPPORT_YCBCR_INPUT |
669 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
670 rk_hdmi_property.feature |=
672 SUPPORT_YCBCR_INPUT |
676 SUPPORT_RK_DISCRETE_VR;
677 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
678 rk_hdmi_property.feature |=
682 SUPPORT_YCBCR_INPUT |
689 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
690 if (!hdmi_dev->hdmi) {
691 dev_err(&pdev->dev, "register hdmi device failed\n");
696 hdmi_get_prop_dts(hdmi_dev->hdmi, hdmi_dev->dev->of_node);
697 mutex_init(&hdmi_dev->ddc_lock);
698 hdmi_dev->hdmi->dev = &pdev->dev;
699 hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
700 fb_register_client(&rockchip_hdmiv2_fb_notifier);
701 rockchip_hdmiv2_dev_initial(hdmi_dev);
702 pinctrl_select_state(hdmi_dev->dev->pins->p,
703 hdmi_dev->dev->pins->default_state);
704 #if defined(CONFIG_DEBUG_FS)
705 hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
706 if (IS_ERR(hdmi_dev->debugfs_dir))
707 dev_err(hdmi_dev->hdmi->dev,
708 "failed to create debugfs dir for rockchip hdmiv2!\n");
710 debugfs_create_file("regs_ctrl", S_IRUSR,
711 hdmi_dev->debugfs_dir,
712 hdmi_dev, &hdmi_regs_ctrl_fops);
713 debugfs_create_file("regs_phy", S_IRUSR,
714 hdmi_dev->debugfs_dir,
715 hdmi_dev, &hdmi_regs_phy_fops);
719 #ifndef HDMI_INT_USE_POLL
720 /* get and request the IRQ */
721 hdmi_dev->irq = platform_get_irq(pdev, 0);
722 if (hdmi_dev->irq <= 0) {
723 dev_err(hdmi_dev->dev,
724 "failed to get hdmi irq resource (%d).\n",
730 ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
731 rockchip_hdmiv2_dev_irq,
733 dev_name(hdmi_dev->dev), hdmi_dev);
735 dev_err(hdmi_dev->dev,
736 "hdmi request_irq failed (%d).\n",
741 hdmi_dev->workqueue =
742 create_singlethread_workqueue("rockchip hdmiv2 irq");
743 INIT_DELAYED_WORK(&hdmi_dev->delay_work,
744 rockchip_hdmiv2_irq_work_func);
745 rockchip_hdmiv2_irq_work_func(NULL);
748 rk_display_device_enable(hdmi_dev->hdmi->ddev);
749 dev_info(&pdev->dev, "rockchip hdmiv2 probe success.\n");
753 rockchip_hdmi_unregister(hdmi_dev->hdmi);
755 kfree(hdmi_dev->phy_table);
758 dev_err(&pdev->dev, "rockchip hdmiv2 probe error.\n");
762 static int rockchip_hdmiv2_suspend(struct platform_device *pdev,
766 hdmi_dev->grf_base &&
767 hdmi_dev->soctype == HDMI_SOC_RK322X) {
768 regmap_write(hdmi_dev->grf_base,
770 RK322X_PLL_POWER_DOWN);
775 static int rockchip_hdmiv2_resume(struct platform_device *pdev)
778 hdmi_dev->grf_base &&
779 hdmi_dev->soctype == HDMI_SOC_RK322X) {
780 regmap_write(hdmi_dev->grf_base,
782 RK322X_PLL_POWER_UP);
787 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
789 dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
793 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
798 #ifdef CONFIG_HAS_EARLYSUSPEND
799 unregister_early_suspend(&hdmi_dev->early_suspend);
801 hdmi = hdmi_dev->hdmi;
802 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
804 hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
806 pm_runtime_disable(hdmi_dev->dev);
809 static struct platform_driver rockchip_hdmiv2_driver = {
810 .probe = rockchip_hdmiv2_probe,
811 .remove = rockchip_hdmiv2_remove,
813 .name = "rockchip-hdmiv2",
814 .owner = THIS_MODULE,
815 #if defined(CONFIG_OF)
816 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
819 .suspend = rockchip_hdmiv2_suspend,
820 .resume = rockchip_hdmiv2_resume,
821 .shutdown = rockchip_hdmiv2_shutdown,
824 static int __init rockchip_hdmiv2_init(void)
826 return platform_driver_register(&rockchip_hdmiv2_driver);
829 static void __exit rockchip_hdmiv2_exit(void)
831 platform_driver_unregister(&rockchip_hdmiv2_driver);
834 module_init(rockchip_hdmiv2_init);
835 module_exit(rockchip_hdmiv2_exit);