1 #include <linux/kernel.h>
2 #include <linux/delay.h>
3 #include <linux/module.h>
4 #include <linux/platform_device.h>
5 #include <linux/interrupt.h>
7 #include <linux/rockchip/grf.h>
8 #include <linux/rockchip/iomap.h>
9 #include <linux/mfd/syscon.h>
10 #if defined(CONFIG_DEBUG_FS)
11 #include <linux/uaccess.h>
13 #include <linux/debugfs.h>
14 #include <linux/seq_file.h>
17 #include "rockchip_hdmiv2.h"
18 #include "rockchip_hdmiv2_hw.h"
20 #define HDMI_SEL_LCDC(x) ((((x)&1)<<4)|(1<<20))
21 #define grf_writel(v, offset) writel_relaxed(v, RK_GRF_VIRT + offset)
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 seq_puts(s, "\n>>>hdmi_phy reg ");
102 for (i = 0; i < 0x28; i++)
103 seq_printf(s, "regs %02x val %04x\n",
104 i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
108 static ssize_t hdmi_regs_phy_write(struct file *file,
109 const char __user *buf,
110 size_t count, loff_t *ppos)
115 if (copy_from_user(kbuf, buf, count))
117 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
119 dev_info(hdmi_dev->hdmi->dev,
120 "/**********hdmi reg phy config******/");
121 dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
122 rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
126 #define HDMI_DEBUG_ENTRY(name) \
127 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
129 return single_open(file, hdmi_##name##_show, inode->i_private); \
132 static const struct file_operations hdmi_##name##_fops = { \
133 .owner = THIS_MODULE, \
134 .open = hdmi_##name##_open, \
136 .write = hdmi_##name##_write, \
137 .llseek = seq_lseek, \
138 .release = single_release, \
141 HDMI_DEBUG_ENTRY(regs_phy);
142 HDMI_DEBUG_ENTRY(regs_ctrl);
145 #ifdef CONFIG_HAS_EARLYSUSPEND
146 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
148 struct hdmi *hdmi = hdmi_dev->hdmi;
149 struct pinctrl_state *gpio_state;
151 HDMIDBG("hdmi enter early suspend\n");
152 hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
153 /* iomux to gpio and pull down when suspend */
154 gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
155 pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
156 rockchip_hdmiv2_clk_disable(hdmi_dev);
159 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
161 struct hdmi *hdmi = hdmi_dev->hdmi;
163 HDMIDBG("hdmi exit early resume\n");
164 /* iomux to default state for hdmi use when resume */
165 pinctrl_select_state(hdmi_dev->dev->pins->p,
166 hdmi_dev->dev->pins->default_state);
167 rockchip_hdmiv2_clk_enable(hdmi_dev);
168 hdmi_dev_initial(hdmi_dev);
169 if (hdmi->ops->hdcp_power_on_cb)
170 hdmi->ops->hdcp_power_on_cb();
171 hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
175 #define HDMI_PD_ON (1 << 0)
176 #define HDMI_PCLK_ON (1 << 1)
177 #define HDMI_HDCPCLK_ON (1 << 2)
178 #define HDMI_CECCLK_ON (1 << 3)
180 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
182 if ((hdmi_dev->clk_on & HDMI_PD_ON) &&
183 (hdmi_dev->clk_on & HDMI_PCLK_ON) &&
184 (hdmi_dev->clk_on & HDMI_HDCPCLK_ON))
187 if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
188 if (hdmi_dev->pd == NULL) {
189 hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi");
190 if (IS_ERR(hdmi_dev->pd)) {
191 dev_err(hdmi_dev->dev,
192 "Unable to get hdmi pd\n");
196 clk_prepare_enable(hdmi_dev->pd);
197 hdmi_dev->clk_on |= HDMI_PD_ON;
200 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
201 if (hdmi_dev->pclk == NULL) {
203 devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
204 if (IS_ERR(hdmi_dev->pclk)) {
205 dev_err(hdmi_dev->dev,
206 "Unable to get hdmi pclk\n");
210 clk_prepare_enable(hdmi_dev->pclk);
211 hdmi_dev->clk_on |= HDMI_PCLK_ON;
214 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
215 if (hdmi_dev->hdcp_clk == NULL) {
217 devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
218 if (IS_ERR(hdmi_dev->hdcp_clk)) {
219 dev_err(hdmi_dev->dev,
220 "Unable to get hdmi hdcp_clk\n");
224 clk_prepare_enable(hdmi_dev->hdcp_clk);
225 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
228 if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
229 (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
230 if (hdmi_dev->cec_clk == NULL) {
232 devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
233 if (IS_ERR(hdmi_dev->cec_clk)) {
234 dev_err(hdmi_dev->dev,
235 "Unable to get hdmi cec_clk\n");
239 clk_prepare_enable(hdmi_dev->cec_clk);
240 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
245 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
247 if (hdmi_dev->clk_on == 0)
250 if ((hdmi_dev->clk_on & HDMI_PD_ON) && (hdmi_dev->pd != NULL)) {
251 clk_disable_unprepare(hdmi_dev->pd);
252 hdmi_dev->clk_on &= ~HDMI_PD_ON;
255 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
256 (hdmi_dev->pclk != NULL)) {
257 clk_disable_unprepare(hdmi_dev->pclk);
258 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
261 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
262 (hdmi_dev->hdcp_clk != NULL)) {
263 clk_disable_unprepare(hdmi_dev->hdcp_clk);
264 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
270 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
271 unsigned long action, void *data)
273 struct fb_event *event = data;
274 int blank_mode = *((int *)event->data);
275 struct hdmi *hdmi = hdmi_dev->hdmi;
276 struct pinctrl_state *gpio_state;
277 #ifdef CONFIG_PINCTRL
278 struct dev_pin_info *pins = hdmi_dev->dev->pins;
281 if (action == FB_EARLY_EVENT_BLANK) {
282 switch (blank_mode) {
283 case FB_BLANK_UNBLANK:
286 HDMIDBG("suspend hdmi\n");
288 hdmi_submit_work(hdmi,
291 if (hdmi_dev->hdcp2_en)
292 hdmi_dev->hdcp2_en(0);
293 rockchip_hdmiv2_clk_disable(hdmi_dev);
294 #ifdef CONFIG_PINCTRL
295 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
297 pinctrl_lookup_state(pins->p,
301 pinctrl_lookup_state(pins->p,
303 pinctrl_select_state(pins->p,
309 } else if (action == FB_EVENT_BLANK) {
310 switch (blank_mode) {
311 case FB_BLANK_UNBLANK:
312 HDMIDBG("resume hdmi\n");
314 #ifdef CONFIG_PINCTRL
315 pinctrl_select_state(pins->p,
316 pins->default_state);
318 rockchip_hdmiv2_clk_enable(hdmi_dev);
319 rockchip_hdmiv2_dev_initial(hdmi_dev);
320 if (hdmi->ops->hdcp_power_on_cb)
321 hdmi->ops->hdcp_power_on_cb();
322 if (hdmi_dev->hdcp2_reset)
323 hdmi_dev->hdcp2_reset();
324 if (hdmi_dev->hdcp2_en)
325 hdmi_dev->hdcp2_en(1);
326 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
337 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
338 .notifier_call = rockchip_hdmiv2_fb_event_notify,
340 #ifdef HDMI_INT_USE_POLL
341 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
343 if (hdmi_dev->enable) {
344 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
345 queue_delayed_work(hdmi_dev->workqueue,
346 &(hdmi_dev->delay_work),
347 msecs_to_jiffies(50));
352 static struct hdmi_ops rk_hdmi_ops;
355 #if defined(CONFIG_OF)
356 static const struct of_device_id rk_hdmi_dt_ids[] = {
357 {.compatible = "rockchip,rk3288-hdmi",},
358 {.compatible = "rockchip,rk3368-hdmi",},
362 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
365 struct device_node *np = hdmi_dev->dev->of_node;
366 const struct of_device_id *match;
368 match = of_match_node(rk_hdmi_dt_ids, np);
370 return PTR_ERR(match);
372 if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
373 hdmi_dev->soctype = HDMI_SOC_RK3288;
374 } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
375 hdmi_dev->soctype = HDMI_SOC_RK3368;
377 pr_err("It is not a valid rockchip soc!");
381 if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
382 rk_hdmi_property.videosrc = val;
384 if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
385 hdmi_dev->audiosrc = val;
387 if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
389 pr_debug("hdmi support cec\n");
390 rk_hdmi_property.feature |= SUPPORT_CEC;
392 if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
394 pr_debug("hdmi support hdcp\n");
395 rk_hdmi_property.feature |= SUPPORT_HDCP;
397 if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
399 pr_debug("default mode is %d\n", val);
400 rk_hdmi_property.defaultmode = val;
402 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
404 #ifdef CONFIG_MFD_SYSCON
406 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
412 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
415 struct resource *res;
417 HDMIDBG("%s\n", __func__);
418 hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
420 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
423 memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
424 platform_set_drvdata(pdev, hdmi_dev);
425 hdmi_dev->dev = &pdev->dev;
427 rockchip_hdmiv2_parse_dt(hdmi_dev);
429 /*request and remap iomem*/
430 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
432 dev_err(&pdev->dev, "Unable to get register resource\n");
436 hdmi_dev->regbase_phy = res->start;
437 hdmi_dev->regsize_phy = resource_size(res);
438 hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
439 if (IS_ERR(hdmi_dev->regbase)) {
440 ret = PTR_ERR(hdmi_dev->regbase);
442 "cannot ioremap registers,err=%d\n", ret);
446 /*enable pd and pclk and hdcp_clk*/
447 if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
451 /*lcdc source select*/
452 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
453 grf_writel(HDMI_SEL_LCDC(rk_hdmi_property.videosrc),
454 RK3288_GRF_SOC_CON6);
455 /* select GPIO7_C0 as cec pin */
456 grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
458 rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
459 /* Register HDMI device */
460 rk_hdmi_property.name = (char *)pdev->name;
461 rk_hdmi_property.priv = hdmi_dev;
462 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
463 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
464 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
465 rk_hdmi_property.feature |=
468 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
469 rk_hdmi_property.feature |=
476 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
477 if (hdmi_dev->hdmi == NULL) {
478 dev_err(&pdev->dev, "register hdmi device failed\n");
482 mutex_init(&hdmi_dev->ddc_lock);
483 hdmi_dev->hdmi->dev = &pdev->dev;
484 hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
485 fb_register_client(&rockchip_hdmiv2_fb_notifier);
486 rockchip_hdmiv2_dev_initial(hdmi_dev);
487 pinctrl_select_state(hdmi_dev->dev->pins->p,
488 hdmi_dev->dev->pins->default_state);
489 #if defined(CONFIG_DEBUG_FS)
490 hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
491 if (IS_ERR(hdmi_dev->debugfs_dir))
492 dev_err(hdmi_dev->hdmi->dev,
493 "failed to create debugfs dir for rockchip hdmiv2!\n");
495 debugfs_create_file("regs_ctrl", S_IRUSR,
496 hdmi_dev->debugfs_dir,
497 hdmi_dev, &hdmi_regs_ctrl_fops);
498 debugfs_create_file("regs_phy", S_IRUSR,
499 hdmi_dev->debugfs_dir,
500 hdmi_dev, &hdmi_regs_phy_fops);
503 rk_display_device_enable(hdmi_dev->hdmi->ddev);
505 #ifndef HDMI_INT_USE_POLL
506 /* get and request the IRQ */
507 hdmi_dev->irq = platform_get_irq(pdev, 0);
508 if (hdmi_dev->irq <= 0) {
509 dev_err(hdmi_dev->dev,
510 "failed to get hdmi irq resource (%d).\n",
517 devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
518 rockchip_hdmiv2_dev_irq,
520 dev_name(hdmi_dev->dev), hdmi_dev);
522 dev_err(hdmi_dev->dev, "hdmi request_irq failed (%d).\n", ret);
526 hdmi_dev->workqueue =
527 create_singlethread_workqueue("rockchip hdmiv2 irq");
528 INIT_DELAYED_WORK(&(hdmi_dev->delay_work),
529 rockchip_hdmiv2_irq_work_func);
530 rockchip_hdmiv2_irq_work_func(NULL);
533 dev_info(&pdev->dev, "rockchip hdmiv2 probe sucess.\n");
537 rockchip_hdmi_unregister(hdmi_dev->hdmi);
541 dev_err(&pdev->dev, "rk3288 hdmi probe error.\n");
545 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
547 dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
551 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
556 #ifdef CONFIG_HAS_EARLYSUSPEND
557 unregister_early_suspend(&hdmi_dev->early_suspend);
559 hdmi = hdmi_dev->hdmi;
560 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
562 hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
566 static struct platform_driver rockchip_hdmiv2_driver = {
567 .probe = rockchip_hdmiv2_probe,
568 .remove = rockchip_hdmiv2_remove,
570 .name = "rockchip-hdmiv2",
571 .owner = THIS_MODULE,
572 #if defined(CONFIG_OF)
573 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
576 .shutdown = rockchip_hdmiv2_shutdown,
579 static int __init rockchip_hdmiv2_init(void)
581 return platform_driver_register(&rockchip_hdmiv2_driver);
584 static void __exit rockchip_hdmiv2_exit(void)
586 platform_driver_unregister(&rockchip_hdmiv2_driver);
589 module_init(rockchip_hdmiv2_init);
590 module_exit(rockchip_hdmiv2_exit);