9cca081f5d966f8f65731aefe24b4367b6f39f9f
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / chips / rk3288 / rk3288_hdmi.c
1 /*
2  * drivers/video/rockchip/hdmi/chips/rk3288/rk3188_hdmi.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *Author:zwl<zwl@rock-chips.com>
6  *This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16 #include <linux/delay.h>
17 #include <linux/interrupt.h>
18 #include <linux/clk.h>
19 #include <linux/uaccess.h>
20 #include <linux/rockchip/grf.h>
21 #include <linux/rockchip/iomap.h>
22 #if defined(CONFIG_OF)
23 #include <linux/of.h>
24 #include <linux/of_device.h>
25 #endif
26 #if defined(CONFIG_DEBUG_FS)
27 #include <linux/fs.h>
28 #include <linux/debugfs.h>
29 #include <linux/seq_file.h>
30 #endif
31
32 #include "rk3288_hdmi_hw.h"
33 #include "rk3288_hdmi.h"
34
35 #define grf_readl(offset)       readl_relaxed(RK_GRF_VIRT + offset)
36 #define grf_writel(v, offset)                           \
37 do {                                                    \
38         writel_relaxed(v, RK_GRF_VIRT + offset);        \
39         dsb();                                          \
40 } while (0)
41 #define HDMI_PD_ON              (1 << 0)
42 #define HDMI_PCLK_ON            (1 << 1)
43 #define HDMI_HDCPCLK_ON         (1 << 2)
44
45
46 static struct rk3288_hdmi_device *hdmi_dev;
47
48 #if defined(CONFIG_DEBUG_FS)
49 static const struct rk3288_hdmi_reg_table hdmi_reg_table[] = {
50         {IDENTIFICATION_BASE, CONFIG3_ID},
51         {INTERRUPT_BASE, IH_MUTE},
52         {VIDEO_SAMPLER_BASE, TX_BCBDATA1},
53         {VIDEO_PACKETIZER_BASE, VP_MASK},
54         {FRAME_COMPOSER_BASE, FC_DBGTMDS2},
55         {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2},
56         {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD},
57         {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0},
58         {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2},
59         {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2},
60         {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST},
61         {HDCP_BKSV_BASE, HDCPREG_BKSV4},
62         {HDCP_AN_BASE, HDCPREG_AN7},
63         {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6},
64         {CEC_ENGINE_BASE, CEC_WKUPCTRL},
65         {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1},
66 };
67
68 static int rk3288_hdmi_reg_show(struct seq_file *s, void *v)
69 {
70         int i = 0, j = 0;
71         u32 val = 0;
72
73         seq_puts(s, "\n>>>hdmi_ctl reg");
74         for (i = 0; i < 16; i++)
75                 seq_printf(s, " %2x", i);
76
77         seq_puts(s,
78                    "\n-----------------------------------------------------------------");
79
80         for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); i++) {
81                 for (j = hdmi_reg_table[i].reg_base;
82                      j <= hdmi_reg_table[i].reg_end; j++) {
83                         val = hdmi_readl(hdmi_dev, j);
84                         if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
85                                 seq_printf(s, "\n>>>hdmi_ctl %2x:", j);
86                         seq_printf(s, " %02x", val);
87
88                 }
89         }
90         seq_puts(s,
91                    "\n-----------------------------------------------------------------\n");
92
93         return 0;
94 }
95
96 static ssize_t rk3288_hdmi_reg_write(struct file *file, const char __user *buf,
97                                      size_t count, loff_t *ppos)
98 {
99         u32 reg;
100         u32 val;
101         char kbuf[25];
102
103         if (copy_from_user(kbuf, buf, count))
104                 return -EFAULT;
105         sscanf(kbuf, "%x%x", &reg, &val);
106         if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
107                 dev_info(hdmi_dev->dev, "it is no hdmi reg\n");
108                 return count;
109         }
110         dev_info(hdmi_dev->dev, "/**********rk3288 hdmi reg config******/");
111         dev_info(hdmi_dev->dev, "\n reg=%x val=%x\n", reg, val);
112         hdmi_writel(hdmi_dev, reg, val);
113
114         return count;
115 }
116
117 static int rk3288_hdmi_reg_open(struct inode *inode, struct file *file)
118 {
119         struct rk3288_hdmi_device *hdmi_dev = inode->i_private;
120
121         return single_open(file, rk3288_hdmi_reg_show, hdmi_dev);
122 }
123
124 static const struct file_operations rk3288_hdmi_reg_fops = {
125         .owner = THIS_MODULE,
126         .open = rk3288_hdmi_reg_open,
127         .read = seq_read,
128         .write = rk3288_hdmi_reg_write,
129         .llseek = seq_lseek,
130         .release = single_release,
131 };
132 #endif
133
134 struct hdmi *rk3288_hdmi_register_hdcp_callbacks(void (*hdcp_cb) (void),
135                                         void (*hdcp_irq_cb) (int status),
136                                         int (*hdcp_power_on_cb) (void),
137                                         void (*hdcp_power_off_cb) (void))
138 {
139         struct hdmi *hdmi_drv = NULL;
140
141         if (hdmi_dev == NULL)
142                 return NULL;
143
144         hdmi_drv = &hdmi_dev->driver;
145         hdmi_drv->hdcp_cb = hdcp_cb;
146         hdmi_drv->hdcp_irq_cb = hdcp_irq_cb;
147         hdmi_drv->hdcp_power_on_cb = hdcp_power_on_cb;
148         hdmi_drv->hdcp_power_off_cb = hdcp_power_off_cb;
149
150         return hdmi_drv;
151 }
152
153 #ifdef HDMI_INT_USE_POLL
154 #define HDMI_POLL_MDELAY        100
155 static void rk3288_poll_delay_work(struct work_struct *work)
156 {
157         struct hdmi *hdmi_drv = &hdmi_dev->driver;
158
159         if (hdmi_drv->suspend == 0) {
160                 if (hdmi_drv->enable == 1)
161                         hdmi_irq(0, hdmi_drv);
162
163                 if (hdmi_dev->irq == 0)
164                         queue_delayed_work(hdmi_drv->workqueue,
165                                            &hdmi_dev->delay_work,
166                                            msecs_to_jiffies(HDMI_POLL_MDELAY));
167         }
168 }
169 #endif
170
171 static int rk3288_hdmi_clk_enable(struct rk3288_hdmi_device *hdmi_dev)
172 {
173         if ((hdmi_dev->clk_on & HDMI_PD_ON) && (hdmi_dev->clk_on & HDMI_PCLK_ON)
174             && (hdmi_dev->clk_on & HDMI_HDCPCLK_ON))
175                 return 0;
176
177         if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
178                 if (hdmi_dev->pd == NULL) {
179                         hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi");
180                         if (IS_ERR(hdmi_dev->pd)) {
181                                 dev_err(hdmi_dev->dev,
182                                         "Unable to get hdmi pd\n");
183                                 return -1;
184                         }
185                 }
186                 clk_prepare_enable(hdmi_dev->pd);
187                 hdmi_dev->clk_on |= HDMI_PD_ON;
188         }
189
190         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
191                 if (hdmi_dev->pclk == NULL) {
192                         hdmi_dev->pclk =
193                             devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
194                         if (IS_ERR(hdmi_dev->pclk)) {
195                                 dev_err(hdmi_dev->dev,
196                                         "Unable to get hdmi pclk\n");
197                                 return -1;
198                         }
199                 }
200                 clk_prepare_enable(hdmi_dev->pclk);
201                 hdmi_dev->clk_on |= HDMI_PCLK_ON;
202         }
203
204         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
205                 if (hdmi_dev->hdcp_clk == NULL) {
206                         hdmi_dev->hdcp_clk =
207                             devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
208                         if (IS_ERR(hdmi_dev->hdcp_clk)) {
209                                 dev_err(hdmi_dev->dev,
210                                         "Unable to get hdmi hdcp_clk\n");
211                                 return -1;
212                         }
213                 }
214                 clk_prepare_enable(hdmi_dev->hdcp_clk);
215                 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
216         }
217
218         return 0;
219 }
220
221 static int rk3288_hdmi_clk_disable(struct rk3288_hdmi_device *hdmi_dev)
222 {
223         if (hdmi_dev->clk_on == 0)
224                 return 0;
225
226         if ((hdmi_dev->clk_on & HDMI_PD_ON) && (hdmi_dev->pd != NULL)) {
227                 clk_disable_unprepare(hdmi_dev->pd);
228                 hdmi_dev->clk_on &= ~HDMI_PD_ON;
229         }
230
231         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) && (hdmi_dev->pclk != NULL)) {
232                 clk_disable_unprepare(hdmi_dev->pclk);
233                 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
234         }
235
236         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON)
237             && (hdmi_dev->hdcp_clk != NULL)) {
238                 clk_disable_unprepare(hdmi_dev->hdcp_clk);
239                 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
240         }
241
242         return 0;
243 }
244
245 static int rk3288_hdmi_drv_init(struct hdmi *hdmi_drv)
246 {
247         int ret = 0;
248         struct rk_screen screen;
249
250         rk_fb_get_prmry_screen(&screen);
251
252         /* hdmi is extend as default,TODO modify if hdmi is primary */
253         hdmi_dev->lcdc_id = (screen.lcdc_id == 0) ? 1 : 0;
254         /* lcdc source select */
255         grf_writel(HDMI_SEL_LCDC(hdmi_dev->lcdc_id), RK3288_GRF_SOC_CON6);
256         if (hdmi_dev->lcdc_id == 0)
257                 hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc0");
258         else
259                 hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc1");
260         if (IS_ERR(hdmi_drv->lcdc)) {
261                 dev_err(hdmi_drv->dev,
262                         "can not connect to video source lcdc\n");
263                 ret = -ENXIO;
264                 return ret;
265         }
266
267         hdmi_drv->xscale = 100;
268         hdmi_drv->yscale = 100;
269
270         spin_lock_init(&hdmi_drv->irq_lock);
271         mutex_init(&hdmi_drv->enable_mutex);
272
273         rk3288_hdmi_initial(hdmi_drv);
274         hdmi_sys_init(hdmi_drv);
275         hdmi_drv_register(hdmi_drv);
276
277         return ret;
278 }
279
280 static void rk3288_hdmi_early_suspend(void)
281 {
282         struct hdmi *hdmi_drv = &hdmi_dev->driver;
283
284         if (hdmi_drv->suspend)
285                 return;
286
287         hdmi_dbg(hdmi_drv->dev, "hdmi enter early suspend pwr %d state %d\n",
288                  hdmi_drv->pwr_mode, hdmi_drv->state);
289         flush_delayed_work(&hdmi_drv->delay_work);
290         mutex_lock(&hdmi_drv->enable_mutex);
291         hdmi_drv->suspend = 1;
292         if (!hdmi_drv->enable) {
293                 mutex_unlock(&hdmi_drv->enable_mutex);
294                 return;
295         }
296         disable_irq(hdmi_drv->irq);
297         mutex_unlock(&hdmi_drv->enable_mutex);
298         hdmi_drv->command = HDMI_CONFIG_ENABLE;
299         init_completion(&hdmi_drv->complete);
300         hdmi_drv->wait = 1;
301         queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, 0);
302         wait_for_completion_interruptible_timeout(&hdmi_drv->complete,
303                                                   msecs_to_jiffies(5000));
304         flush_delayed_work(&hdmi_drv->delay_work);
305
306         /* iomux to gpio and pull down when suspend */
307         pinctrl_select_state(hdmi_dev->dev->pins->p,
308                              hdmi_dev->dev->pins->sleep_state);
309         rk3288_hdmi_clk_disable(hdmi_dev);
310         return;
311 }
312
313 static void rk3288_hdmi_early_resume(void)
314 {
315         struct hdmi *hdmi_drv = &hdmi_dev->driver;
316
317         if (!hdmi_drv->suspend)
318                 return;
319
320         hdmi_dbg(hdmi_drv->dev, "hdmi enter early resume\n");
321         /* iomux to default state for hdmi use when resume */
322         pinctrl_select_state(hdmi_dev->dev->pins->p,
323                              hdmi_dev->dev->pins->default_state);
324         rk3288_hdmi_clk_enable(hdmi_dev);
325         mutex_lock(&hdmi_drv->enable_mutex);
326         hdmi_drv->suspend = 0;
327         rk3288_hdmi_initial(hdmi_drv);
328         if (hdmi_dev->irq == 0) {
329 #ifdef HDMI_INT_USE_POLL
330                 queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->delay_work,
331                                    msecs_to_jiffies(5));
332 #endif
333         } else if (hdmi_drv->enable) {
334                 enable_irq(hdmi_drv->irq);
335         }
336         queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work,
337                            msecs_to_jiffies(10));
338         mutex_unlock(&hdmi_drv->enable_mutex);
339         return;
340 }
341
342 static int rk3288_hdmi_fb_event_notify(struct notifier_block *self,
343                                        unsigned long action, void *data)
344 {
345         struct fb_event *event = data;
346         int blank_mode = *((int *)event->data);
347
348         if (action == FB_EARLY_EVENT_BLANK) {
349                 switch (blank_mode) {
350                 case FB_BLANK_UNBLANK:
351                         break;
352                 default:
353                         rk3288_hdmi_early_suspend();
354                         break;
355                 }
356         } else if (action == FB_EVENT_BLANK) {
357                 switch (blank_mode) {
358                 case FB_BLANK_UNBLANK:
359                         rk3288_hdmi_early_resume();
360                         break;
361                 default:
362                         break;
363                 }
364         }
365
366         return NOTIFY_OK;
367 }
368
369 static struct notifier_block rk3288_hdmi_fb_notifier = {
370         .notifier_call = rk3288_hdmi_fb_event_notify,
371 };
372
373 #if defined(CONFIG_OF)
374 static int rk3288_hdmi_parse_dt(struct rk3288_hdmi_device *hdmi_dev)
375 {
376         int val = 0;
377         struct device_node *np = hdmi_dev->dev->of_node;
378
379         if (!of_property_read_u32(np, "rockchips,hdmi_audio_source", &val))
380                 hdmi_dev->driver.audio.type = val;
381
382         return 0;
383 }
384
385 static const struct of_device_id rk3288_hdmi_dt_ids[] = {
386         {.compatible = "rockchip,rk3288-hdmi",},
387         {}
388 };
389 #endif
390
391 static int rk3288_hdmi_probe(struct platform_device *pdev)
392 {
393         int ret;
394         struct resource *res;
395         struct hdmi *dev_drv = NULL;
396
397         hdmi_dev = kzalloc(sizeof(struct rk3288_hdmi_device), GFP_KERNEL);
398         if (!hdmi_dev) {
399                 dev_err(&pdev->dev, ">>rk3288_hdmi_device kzalloc fail!");
400                 return -ENOMEM;
401         }
402
403         hdmi_dev->dev = &pdev->dev;
404         platform_set_drvdata(pdev, hdmi_dev);
405         mutex_init(&hdmi_dev->int_mutex);
406
407         rk3288_hdmi_parse_dt(hdmi_dev);
408         /* TODO Daisen wait to add cec iomux */
409
410         /* enable pd and pclk and hdcp_clk */
411         if (rk3288_hdmi_clk_enable(hdmi_dev) < 0)
412                 goto err0;
413
414         /* request and remap iomem */
415         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
416         if (!res) {
417                 dev_err(hdmi_dev->dev, "Unable to get register resource\n");
418                 ret = -ENXIO;
419                 goto err0;
420         }
421         hdmi_dev->regbase_phy = res->start;
422         hdmi_dev->regsize_phy = resource_size(res);
423         hdmi_dev->regbase = devm_ioremap_resource(hdmi_dev->dev, res);
424         if (IS_ERR(hdmi_dev->regbase)) {
425                 ret = PTR_ERR(hdmi_dev->regbase);
426                 dev_err(hdmi_dev->dev, "cannot ioremap registers,err=%d\n",
427                         ret);
428                 goto err0;
429         }
430
431         /*init hdmi driver */
432         dev_drv = &hdmi_dev->driver;
433         dev_drv->dev = &pdev->dev;
434         if (rk3288_hdmi_drv_init(dev_drv))
435                 goto err0;
436
437         dev_drv->workqueue = create_singlethread_workqueue("hdmi");
438         INIT_DELAYED_WORK(&(dev_drv->delay_work), hdmi_work);
439
440         hdmi_register_display_sysfs(dev_drv, NULL);
441
442 #ifdef CONFIG_SWITCH
443         dev_drv->switch_hdmi.name = "hdmi";
444         switch_dev_register(&(dev_drv->switch_hdmi));
445 #endif
446
447         fb_register_client(&rk3288_hdmi_fb_notifier);
448
449 #ifndef HDMI_INT_USE_POLL
450         /* get and request the IRQ */
451         dev_drv->irq = platform_get_irq(pdev, 0);
452         if (dev_drv->irq <= 0) {
453                 dev_err(hdmi_dev->dev,
454                         "failed to get hdmi irq resource (%d).\n",
455                         hdmi_dev->irq);
456                 ret = -ENXIO;
457                 goto err1;
458         }
459
460         ret =
461             devm_request_irq(hdmi_dev->dev, dev_drv->irq, hdmi_irq, 0,
462                              dev_name(hdmi_dev->dev), dev_drv);
463         if (ret) {
464                 dev_err(hdmi_dev->dev, "hdmi request_irq failed (%d).\n", ret);
465                 goto err1;
466         }
467 #else
468         hdmi_dev->irq = 0;
469         INIT_DELAYED_WORK(&hdmi_dev->delay_work, rk3288_poll_delay_work);
470         queue_delayed_work(dev_drv->workqueue, &hdmi_dev->delay_work,
471                            msecs_to_jiffies(1));
472 #endif
473
474 #if defined(CONFIG_DEBUG_FS)
475         hdmi_dev->debugfs_dir = debugfs_create_dir("rk3288-hdmi", NULL);
476         if (IS_ERR(hdmi_dev->debugfs_dir)) {
477                 dev_err(hdmi_dev->dev,
478                         "failed to create debugfs dir for rk3288 hdmi!\n");
479         } else {
480                 debugfs_create_file("hdmi", S_IRUSR, hdmi_dev->debugfs_dir,
481                                     hdmi_dev, &rk3288_hdmi_reg_fops);
482         }
483 #endif
484
485         dev_info(hdmi_dev->dev, "rk3288 hdmi probe sucess.\n");
486         return 0;
487
488 #ifndef HDMI_INT_USE_POLL
489 err1:
490 #endif
491         fb_unregister_client(&rk3288_hdmi_fb_notifier);
492 #ifdef CONFIG_SWITCH
493         switch_dev_unregister(&(dev_drv->switch_hdmi));
494 #endif
495         hdmi_unregister_display_sysfs(dev_drv);
496
497         /*
498         iounmap((void*)hdmi_dev->regbase);
499         release_mem_region(res->start, hdmi_dev->regsize_phy);
500         */
501 err0:
502         rk3288_hdmi_clk_disable(hdmi_dev);
503         dev_info(hdmi_dev->dev, "rk3288 hdmi probe error.\n");
504         kfree(hdmi_dev);
505         hdmi_dev = NULL;
506         return ret;
507 }
508
509 static int rk3288_hdmi_remove(struct platform_device *pdev)
510 {
511         struct rk3288_hdmi_device *hdmi_dev = platform_get_drvdata(pdev);
512         struct hdmi *hdmi_drv = NULL;
513
514         if (hdmi_dev) {
515                 hdmi_drv = &hdmi_dev->driver;
516                 mutex_lock(&hdmi_drv->enable_mutex);
517                 if (!hdmi_drv->suspend && hdmi_drv->enable)
518                         disable_irq(hdmi_drv->irq);
519                 mutex_unlock(&hdmi_drv->enable_mutex);
520                 free_irq(hdmi_drv->irq, NULL);
521
522                 flush_workqueue(hdmi_drv->workqueue);
523                 destroy_workqueue(hdmi_drv->workqueue);
524
525                 fb_unregister_client(&rk3288_hdmi_fb_notifier);
526
527 #ifdef CONFIG_SWITCH
528                 switch_dev_unregister(&(hdmi_drv->switch_hdmi));
529 #endif
530                 hdmi_unregister_display_sysfs(hdmi_drv);
531
532                 /*
533                 iounmap((void*)hdmi_drv->regbase);
534                 release_mem_region(hdmi_drv->regbase_phy,
535                                         hdmi_drv->regsize_phy);
536                 */
537                 rk3288_hdmi_clk_disable(hdmi_dev);
538                 fb_destroy_modelist(&hdmi_drv->edid.modelist);
539                 kfree(hdmi_drv->edid.audio);
540                 if (hdmi_drv->edid.specs) {
541                         kfree(hdmi_drv->edid.specs->modedb);
542                         kfree(hdmi_drv->edid.specs);
543                 }
544
545                 kfree(hdmi_dev);
546                 hdmi_dev = NULL;
547         }
548         dev_info(hdmi_dev->dev, "rk3288 hdmi removed.\n");
549         return 0;
550 }
551
552 static void rk3288_hdmi_shutdown(struct platform_device *pdev)
553 {
554
555 }
556
557 static struct platform_driver rk3288_hdmi_driver = {
558         .probe = rk3288_hdmi_probe,
559         .remove = rk3288_hdmi_remove,
560         .driver = {
561                    .name = "rk3288-hdmi",
562                    .owner = THIS_MODULE,
563                    .of_match_table = of_match_ptr(rk3288_hdmi_dt_ids),
564                    },
565         .shutdown = rk3288_hdmi_shutdown,
566 };
567
568 static int __init rk3288_hdmi_init(void)
569 {
570         return platform_driver_register(&rk3288_hdmi_driver);
571 }
572
573 static void __exit rk3288_hdmi_exit(void)
574 {
575         platform_driver_unregister(&rk3288_hdmi_driver);
576 }
577
578 device_initcall_sync(rk3288_hdmi_init);
579 module_exit(rk3288_hdmi_exit);