• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hdmi.c
3  *
4  * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6  * Authors: Yong Zhi
7  *	Mythri pk <mythripk@ti.com>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License version 2 as published by
11  * the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #define DSS_SUBSYS_NAME "HDMI"
23 
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/err.h>
27 #include <linux/io.h>
28 #include <linux/interrupt.h>
29 #include <linux/mutex.h>
30 #include <linux/delay.h>
31 #include <linux/string.h>
32 #include <linux/platform_device.h>
33 #include <linux/pm_runtime.h>
34 #include <linux/clk.h>
35 #include <linux/gpio.h>
36 #include <linux/regulator/consumer.h>
37 #include <video/omapdss.h>
38 
39 #include "ti_hdmi.h"
40 #include "dss.h"
41 #include "dss_features.h"
42 
43 #define HDMI_WP			0x0
44 #define HDMI_CORE_SYS		0x400
45 #define HDMI_CORE_AV		0x900
46 #define HDMI_PLLCTRL		0x200
47 #define HDMI_PHY		0x300
48 
49 /* HDMI EDID Length move this */
50 #define HDMI_EDID_MAX_LENGTH			256
51 #define EDID_TIMING_DESCRIPTOR_SIZE		0x12
52 #define EDID_DESCRIPTOR_BLOCK0_ADDRESS		0x36
53 #define EDID_DESCRIPTOR_BLOCK1_ADDRESS		0x80
54 #define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR	4
55 #define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR	4
56 
57 #define HDMI_DEFAULT_REGN 16
58 #define HDMI_DEFAULT_REGM2 1
59 
60 static struct {
61 	struct mutex lock;
62 	struct platform_device *pdev;
63 
64 	struct hdmi_ip_data ip_data;
65 
66 	struct clk *sys_clk;
67 	struct regulator *vdda_hdmi_dac_reg;
68 
69 	int ct_cp_hpd_gpio;
70 	int ls_oe_gpio;
71 	int hpd_gpio;
72 
73 	struct omap_dss_output output;
74 } hdmi;
75 
76 /*
77  * Logic for the below structure :
78  * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
79  * There is a correspondence between CEA/VESA timing and code, please
80  * refer to section 6.3 in HDMI 1.3 specification for timing code.
81  *
82  * In the below structure, cea_vesa_timings corresponds to all OMAP4
83  * supported CEA and VESA timing values.code_cea corresponds to the CEA
84  * code, It is used to get the timing from cea_vesa_timing array.Similarly
85  * with code_vesa. Code_index is used for back mapping, that is once EDID
86  * is read from the TV, EDID is parsed to find the timing values and then
87  * map it to corresponding CEA or VESA index.
88  */
89 
90 static const struct hdmi_config cea_timings[] = {
91 	{
92 		{ 640, 480, 25200, 96, 16, 48, 2, 10, 33,
93 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
94 			false, },
95 		{ 1, HDMI_HDMI },
96 	},
97 	{
98 		{ 720, 480, 27027, 62, 16, 60, 6, 9, 30,
99 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
100 			false, },
101 		{ 2, HDMI_HDMI },
102 	},
103 	{
104 		{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
105 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
106 			false, },
107 		{ 4, HDMI_HDMI },
108 	},
109 	{
110 		{ 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
111 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
112 			true, },
113 		{ 5, HDMI_HDMI },
114 	},
115 	{
116 		{ 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
117 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
118 			true, },
119 		{ 6, HDMI_HDMI },
120 	},
121 	{
122 		{ 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
123 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
124 			false, },
125 		{ 16, HDMI_HDMI },
126 	},
127 	{
128 		{ 720, 576, 27000, 64, 12, 68, 5, 5, 39,
129 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
130 			false, },
131 		{ 17, HDMI_HDMI },
132 	},
133 	{
134 		{ 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
135 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
136 			false, },
137 		{ 19, HDMI_HDMI },
138 	},
139 	{
140 		{ 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
141 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
142 			true, },
143 		{ 20, HDMI_HDMI },
144 	},
145 	{
146 		{ 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
147 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
148 			true, },
149 		{ 21, HDMI_HDMI },
150 	},
151 	{
152 		{ 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
153 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
154 			false, },
155 		{ 29, HDMI_HDMI },
156 	},
157 	{
158 		{ 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
159 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
160 			false, },
161 		{ 31, HDMI_HDMI },
162 	},
163 	{
164 		{ 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
165 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
166 			false, },
167 		{ 32, HDMI_HDMI },
168 	},
169 	{
170 		{ 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
171 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
172 			false, },
173 		{ 35, HDMI_HDMI },
174 	},
175 	{
176 		{ 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
177 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
178 			false, },
179 		{ 37, HDMI_HDMI },
180 	},
181 };
182 
183 static const struct hdmi_config vesa_timings[] = {
184 /* VESA From Here */
185 	{
186 		{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
187 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
188 			false, },
189 		{ 4, HDMI_DVI },
190 	},
191 	{
192 		{ 800, 600, 40000, 128, 40, 88, 4, 1, 23,
193 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
194 			false, },
195 		{ 9, HDMI_DVI },
196 	},
197 	{
198 		{ 848, 480, 33750, 112, 16, 112, 8, 6, 23,
199 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
200 			false, },
201 		{ 0xE, HDMI_DVI },
202 	},
203 	{
204 		{ 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
205 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
206 			false, },
207 		{ 0x17, HDMI_DVI },
208 	},
209 	{
210 		{ 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
211 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
212 			false, },
213 		{ 0x1C, HDMI_DVI },
214 	},
215 	{
216 		{ 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
217 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
218 			false, },
219 		{ 0x27, HDMI_DVI },
220 	},
221 	{
222 		{ 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
223 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
224 			false, },
225 		{ 0x20, HDMI_DVI },
226 	},
227 	{
228 		{ 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
229 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
230 			false, },
231 		{ 0x23, HDMI_DVI },
232 	},
233 	{
234 		{ 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
235 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
236 			false, },
237 		{ 0x10, HDMI_DVI },
238 	},
239 	{
240 		{ 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
241 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
242 			false, },
243 		{ 0x2A, HDMI_DVI },
244 	},
245 	{
246 		{ 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
247 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
248 			false, },
249 		{ 0x2F, HDMI_DVI },
250 	},
251 	{
252 		{ 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
253 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
254 			false, },
255 		{ 0x3A, HDMI_DVI },
256 	},
257 	{
258 		{ 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
259 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
260 			false, },
261 		{ 0x51, HDMI_DVI },
262 	},
263 	{
264 		{ 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
265 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
266 			false, },
267 		{ 0x52, HDMI_DVI },
268 	},
269 	{
270 		{ 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
271 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
272 			false, },
273 		{ 0x16, HDMI_DVI },
274 	},
275 	{
276 		{ 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
277 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
278 			false, },
279 		{ 0x29, HDMI_DVI },
280 	},
281 	{
282 		{ 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
283 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
284 			false, },
285 		{ 0x39, HDMI_DVI },
286 	},
287 	{
288 		{ 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
289 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
290 			false, },
291 		{ 0x1B, HDMI_DVI },
292 	},
293 	{
294 		{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
295 			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
296 			false, },
297 		{ 0x55, HDMI_DVI },
298 	},
299 	{
300 		{ 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
301 			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
302 			false, },
303 		{ 0x44, HDMI_DVI },
304 	},
305 };
306 
hdmi_runtime_get(void)307 static int hdmi_runtime_get(void)
308 {
309 	int r;
310 
311 	DSSDBG("hdmi_runtime_get\n");
312 
313 	r = pm_runtime_get_sync(&hdmi.pdev->dev);
314 	WARN_ON(r < 0);
315 	if (r < 0)
316 		return r;
317 
318 	return 0;
319 }
320 
hdmi_runtime_put(void)321 static void hdmi_runtime_put(void)
322 {
323 	int r;
324 
325 	DSSDBG("hdmi_runtime_put\n");
326 
327 	r = pm_runtime_put_sync(&hdmi.pdev->dev);
328 	WARN_ON(r < 0 && r != -ENOSYS);
329 }
330 
hdmi_init_display(struct omap_dss_device * dssdev)331 static int hdmi_init_display(struct omap_dss_device *dssdev)
332 {
333 	int r;
334 
335 	struct gpio gpios[] = {
336 		{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
337 		{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
338 		{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
339 	};
340 
341 	DSSDBG("init_display\n");
342 
343 	dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
344 
345 	if (hdmi.vdda_hdmi_dac_reg == NULL) {
346 		struct regulator *reg;
347 
348 		reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
349 
350 		/* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
351 		if (IS_ERR(reg))
352 			reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
353 
354 		if (IS_ERR(reg)) {
355 			DSSERR("can't get VDDA_HDMI_DAC regulator\n");
356 			return PTR_ERR(reg);
357 		}
358 
359 		hdmi.vdda_hdmi_dac_reg = reg;
360 	}
361 
362 	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
363 	if (r)
364 		return r;
365 
366 	return 0;
367 }
368 
hdmi_uninit_display(struct omap_dss_device * dssdev)369 static void hdmi_uninit_display(struct omap_dss_device *dssdev)
370 {
371 	DSSDBG("uninit_display\n");
372 
373 	gpio_free(hdmi.ct_cp_hpd_gpio);
374 	gpio_free(hdmi.ls_oe_gpio);
375 	gpio_free(hdmi.hpd_gpio);
376 }
377 
hdmi_find_timing(const struct hdmi_config * timings_arr,int len)378 static const struct hdmi_config *hdmi_find_timing(
379 					const struct hdmi_config *timings_arr,
380 					int len)
381 {
382 	int i;
383 
384 	for (i = 0; i < len; i++) {
385 		if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
386 			return &timings_arr[i];
387 	}
388 	return NULL;
389 }
390 
hdmi_get_timings(void)391 static const struct hdmi_config *hdmi_get_timings(void)
392 {
393        const struct hdmi_config *arr;
394        int len;
395 
396        if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
397                arr = vesa_timings;
398                len = ARRAY_SIZE(vesa_timings);
399        } else {
400                arr = cea_timings;
401                len = ARRAY_SIZE(cea_timings);
402        }
403 
404        return hdmi_find_timing(arr, len);
405 }
406 
hdmi_timings_compare(struct omap_video_timings * timing1,const struct omap_video_timings * timing2)407 static bool hdmi_timings_compare(struct omap_video_timings *timing1,
408 				const struct omap_video_timings *timing2)
409 {
410 	int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
411 
412 	if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
413 			DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
414 		(timing2->x_res == timing1->x_res) &&
415 		(timing2->y_res == timing1->y_res)) {
416 
417 		timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
418 		timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
419 		timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
420 		timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
421 
422 		DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
423 			"timing2_hsync = %d timing2_vsync = %d\n",
424 			timing1_hsync, timing1_vsync,
425 			timing2_hsync, timing2_vsync);
426 
427 		if ((timing1_hsync == timing2_hsync) &&
428 			(timing1_vsync == timing2_vsync)) {
429 			return true;
430 		}
431 	}
432 	return false;
433 }
434 
hdmi_get_code(struct omap_video_timings * timing)435 static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
436 {
437 	int i;
438 	struct hdmi_cm cm = {-1};
439 	DSSDBG("hdmi_get_code\n");
440 
441 	for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
442 		if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
443 			cm = cea_timings[i].cm;
444 			goto end;
445 		}
446 	}
447 	for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
448 		if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
449 			cm = vesa_timings[i].cm;
450 			goto end;
451 		}
452 	}
453 
454 end:	return cm;
455 
456 }
457 
hdmi_get_pixel_clock(void)458 unsigned long hdmi_get_pixel_clock(void)
459 {
460 	/* HDMI Pixel Clock in Mhz */
461 	return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
462 }
463 
hdmi_compute_pll(struct omap_dss_device * dssdev,int phy,struct hdmi_pll_info * pi)464 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
465 		struct hdmi_pll_info *pi)
466 {
467 	unsigned long clkin, refclk;
468 	u32 mf;
469 
470 	clkin = clk_get_rate(hdmi.sys_clk) / 10000;
471 	/*
472 	 * Input clock is predivided by N + 1
473 	 * out put of which is reference clk
474 	 */
475 
476 	pi->regn = HDMI_DEFAULT_REGN;
477 
478 	refclk = clkin / pi->regn;
479 
480 	pi->regm2 = HDMI_DEFAULT_REGM2;
481 
482 	/*
483 	 * multiplier is pixel_clk/ref_clk
484 	 * Multiplying by 100 to avoid fractional part removal
485 	 */
486 	pi->regm = phy * pi->regm2 / refclk;
487 
488 	/*
489 	 * fractional multiplier is remainder of the difference between
490 	 * multiplier and actual phy(required pixel clock thus should be
491 	 * multiplied by 2^18(262144) divided by the reference clock
492 	 */
493 	mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
494 	pi->regmf = pi->regm2 * mf / refclk;
495 
496 	/*
497 	 * Dcofreq should be set to 1 if required pixel clock
498 	 * is greater than 1000MHz
499 	 */
500 	pi->dcofreq = phy > 1000 * 100;
501 	pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
502 
503 	/* Set the reference clock to sysclk reference */
504 	pi->refsel = HDMI_REFSEL_SYSCLK;
505 
506 	DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
507 	DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
508 }
509 
hdmi_power_on_core(struct omap_dss_device * dssdev)510 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
511 {
512 	int r;
513 
514 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
515 	gpio_set_value(hdmi.ls_oe_gpio, 1);
516 
517 	/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
518 	udelay(300);
519 
520 	r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
521 	if (r)
522 		goto err_vdac_enable;
523 
524 	r = hdmi_runtime_get();
525 	if (r)
526 		goto err_runtime_get;
527 
528 	/* Make selection of HDMI in DSS */
529 	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
530 
531 	return 0;
532 
533 err_runtime_get:
534 	regulator_disable(hdmi.vdda_hdmi_dac_reg);
535 err_vdac_enable:
536 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
537 	gpio_set_value(hdmi.ls_oe_gpio, 0);
538 	return r;
539 }
540 
hdmi_power_off_core(struct omap_dss_device * dssdev)541 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
542 {
543 	hdmi_runtime_put();
544 	regulator_disable(hdmi.vdda_hdmi_dac_reg);
545 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
546 	gpio_set_value(hdmi.ls_oe_gpio, 0);
547 }
548 
hdmi_power_on_full(struct omap_dss_device * dssdev)549 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
550 {
551 	int r;
552 	struct omap_video_timings *p;
553 	struct omap_overlay_manager *mgr = dssdev->output->manager;
554 	unsigned long phy;
555 
556 	r = hdmi_power_on_core(dssdev);
557 	if (r)
558 		return r;
559 
560 	dss_mgr_disable(mgr);
561 
562 	p = &hdmi.ip_data.cfg.timings;
563 
564 	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
565 
566 	phy = p->pixel_clock;
567 
568 	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
569 
570 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
571 
572 	/* config the PLL and PHY hdmi_set_pll_pwrfirst */
573 	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
574 	if (r) {
575 		DSSDBG("Failed to lock PLL\n");
576 		goto err_pll_enable;
577 	}
578 
579 	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
580 	if (r) {
581 		DSSDBG("Failed to start PHY\n");
582 		goto err_phy_enable;
583 	}
584 
585 	hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
586 
587 	/* bypass TV gamma table */
588 	dispc_enable_gamma_table(0);
589 
590 	/* tv size */
591 	dss_mgr_set_timings(mgr, p);
592 
593 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
594 	if (r)
595 		goto err_vid_enable;
596 
597 	r = dss_mgr_enable(mgr);
598 	if (r)
599 		goto err_mgr_enable;
600 
601 	return 0;
602 
603 err_mgr_enable:
604 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
605 err_vid_enable:
606 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
607 err_phy_enable:
608 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
609 err_pll_enable:
610 	hdmi_power_off_core(dssdev);
611 	return -EIO;
612 }
613 
hdmi_power_off_full(struct omap_dss_device * dssdev)614 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
615 {
616 	struct omap_overlay_manager *mgr = dssdev->output->manager;
617 
618 	dss_mgr_disable(mgr);
619 
620 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
621 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
622 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
623 
624 	hdmi_power_off_core(dssdev);
625 }
626 
omapdss_hdmi_display_check_timing(struct omap_dss_device * dssdev,struct omap_video_timings * timings)627 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
628 					struct omap_video_timings *timings)
629 {
630 	struct hdmi_cm cm;
631 
632 	cm = hdmi_get_code(timings);
633 	if (cm.code == -1) {
634 		return -EINVAL;
635 	}
636 
637 	return 0;
638 
639 }
640 
omapdss_hdmi_display_set_timing(struct omap_dss_device * dssdev,struct omap_video_timings * timings)641 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
642 		struct omap_video_timings *timings)
643 {
644 	struct hdmi_cm cm;
645 	const struct hdmi_config *t;
646 
647 	mutex_lock(&hdmi.lock);
648 
649 	cm = hdmi_get_code(timings);
650 	hdmi.ip_data.cfg.cm = cm;
651 
652 	t = hdmi_get_timings();
653 	if (t != NULL)
654 		hdmi.ip_data.cfg = *t;
655 
656 	mutex_unlock(&hdmi.lock);
657 }
658 
hdmi_dump_regs(struct seq_file * s)659 static void hdmi_dump_regs(struct seq_file *s)
660 {
661 	mutex_lock(&hdmi.lock);
662 
663 	if (hdmi_runtime_get()) {
664 		mutex_unlock(&hdmi.lock);
665 		return;
666 	}
667 
668 	hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
669 	hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
670 	hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
671 	hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
672 
673 	hdmi_runtime_put();
674 	mutex_unlock(&hdmi.lock);
675 }
676 
omapdss_hdmi_read_edid(u8 * buf,int len)677 int omapdss_hdmi_read_edid(u8 *buf, int len)
678 {
679 	int r;
680 
681 	mutex_lock(&hdmi.lock);
682 
683 	r = hdmi_runtime_get();
684 	BUG_ON(r);
685 
686 	r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
687 
688 	hdmi_runtime_put();
689 	mutex_unlock(&hdmi.lock);
690 
691 	return r;
692 }
693 
omapdss_hdmi_detect(void)694 bool omapdss_hdmi_detect(void)
695 {
696 	int r;
697 
698 	mutex_lock(&hdmi.lock);
699 
700 	r = hdmi_runtime_get();
701 	BUG_ON(r);
702 
703 	r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
704 
705 	hdmi_runtime_put();
706 	mutex_unlock(&hdmi.lock);
707 
708 	return r == 1;
709 }
710 
omapdss_hdmi_display_enable(struct omap_dss_device * dssdev)711 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
712 {
713 	struct omap_dss_output *out = dssdev->output;
714 	int r = 0;
715 
716 	DSSDBG("ENTER hdmi_display_enable\n");
717 
718 	mutex_lock(&hdmi.lock);
719 
720 	if (out == NULL || out->manager == NULL) {
721 		DSSERR("failed to enable display: no output/manager\n");
722 		r = -ENODEV;
723 		goto err0;
724 	}
725 
726 	hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
727 
728 	r = omap_dss_start_device(dssdev);
729 	if (r) {
730 		DSSERR("failed to start device\n");
731 		goto err0;
732 	}
733 
734 	r = hdmi_power_on_full(dssdev);
735 	if (r) {
736 		DSSERR("failed to power on device\n");
737 		goto err1;
738 	}
739 
740 	mutex_unlock(&hdmi.lock);
741 	return 0;
742 
743 err1:
744 	omap_dss_stop_device(dssdev);
745 err0:
746 	mutex_unlock(&hdmi.lock);
747 	return r;
748 }
749 
omapdss_hdmi_display_disable(struct omap_dss_device * dssdev)750 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
751 {
752 	DSSDBG("Enter hdmi_display_disable\n");
753 
754 	mutex_lock(&hdmi.lock);
755 
756 	hdmi_power_off_full(dssdev);
757 
758 	omap_dss_stop_device(dssdev);
759 
760 	mutex_unlock(&hdmi.lock);
761 }
762 
omapdss_hdmi_core_enable(struct omap_dss_device * dssdev)763 int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
764 {
765 	int r = 0;
766 
767 	DSSDBG("ENTER omapdss_hdmi_core_enable\n");
768 
769 	mutex_lock(&hdmi.lock);
770 
771 	hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
772 
773 	r = hdmi_power_on_core(dssdev);
774 	if (r) {
775 		DSSERR("failed to power on device\n");
776 		goto err0;
777 	}
778 
779 	mutex_unlock(&hdmi.lock);
780 	return 0;
781 
782 err0:
783 	mutex_unlock(&hdmi.lock);
784 	return r;
785 }
786 
omapdss_hdmi_core_disable(struct omap_dss_device * dssdev)787 void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
788 {
789 	DSSDBG("Enter omapdss_hdmi_core_disable\n");
790 
791 	mutex_lock(&hdmi.lock);
792 
793 	hdmi_power_off_core(dssdev);
794 
795 	mutex_unlock(&hdmi.lock);
796 }
797 
hdmi_get_clocks(struct platform_device * pdev)798 static int hdmi_get_clocks(struct platform_device *pdev)
799 {
800 	struct clk *clk;
801 
802 	clk = devm_clk_get(&pdev->dev, "sys_clk");
803 	if (IS_ERR(clk)) {
804 		DSSERR("can't get sys_clk\n");
805 		return PTR_ERR(clk);
806 	}
807 
808 	hdmi.sys_clk = clk;
809 
810 	return 0;
811 }
812 
813 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
hdmi_compute_acr(u32 sample_freq,u32 * n,u32 * cts)814 int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
815 {
816 	u32 deep_color;
817 	bool deep_color_correct = false;
818 	u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock;
819 
820 	if (n == NULL || cts == NULL)
821 		return -EINVAL;
822 
823 	/* TODO: When implemented, query deep color mode here. */
824 	deep_color = 100;
825 
826 	/*
827 	 * When using deep color, the default N value (as in the HDMI
828 	 * specification) yields to an non-integer CTS. Hence, we
829 	 * modify it while keeping the restrictions described in
830 	 * section 7.2.1 of the HDMI 1.4a specification.
831 	 */
832 	switch (sample_freq) {
833 	case 32000:
834 	case 48000:
835 	case 96000:
836 	case 192000:
837 		if (deep_color == 125)
838 			if (pclk == 27027 || pclk == 74250)
839 				deep_color_correct = true;
840 		if (deep_color == 150)
841 			if (pclk == 27027)
842 				deep_color_correct = true;
843 		break;
844 	case 44100:
845 	case 88200:
846 	case 176400:
847 		if (deep_color == 125)
848 			if (pclk == 27027)
849 				deep_color_correct = true;
850 		break;
851 	default:
852 		return -EINVAL;
853 	}
854 
855 	if (deep_color_correct) {
856 		switch (sample_freq) {
857 		case 32000:
858 			*n = 8192;
859 			break;
860 		case 44100:
861 			*n = 12544;
862 			break;
863 		case 48000:
864 			*n = 8192;
865 			break;
866 		case 88200:
867 			*n = 25088;
868 			break;
869 		case 96000:
870 			*n = 16384;
871 			break;
872 		case 176400:
873 			*n = 50176;
874 			break;
875 		case 192000:
876 			*n = 32768;
877 			break;
878 		default:
879 			return -EINVAL;
880 		}
881 	} else {
882 		switch (sample_freq) {
883 		case 32000:
884 			*n = 4096;
885 			break;
886 		case 44100:
887 			*n = 6272;
888 			break;
889 		case 48000:
890 			*n = 6144;
891 			break;
892 		case 88200:
893 			*n = 12544;
894 			break;
895 		case 96000:
896 			*n = 12288;
897 			break;
898 		case 176400:
899 			*n = 25088;
900 			break;
901 		case 192000:
902 			*n = 24576;
903 			break;
904 		default:
905 			return -EINVAL;
906 		}
907 	}
908 	/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
909 	*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
910 
911 	return 0;
912 }
913 
hdmi_audio_enable(void)914 int hdmi_audio_enable(void)
915 {
916 	DSSDBG("audio_enable\n");
917 
918 	return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
919 }
920 
hdmi_audio_disable(void)921 void hdmi_audio_disable(void)
922 {
923 	DSSDBG("audio_disable\n");
924 
925 	hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
926 }
927 
hdmi_audio_start(void)928 int hdmi_audio_start(void)
929 {
930 	DSSDBG("audio_start\n");
931 
932 	return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
933 }
934 
hdmi_audio_stop(void)935 void hdmi_audio_stop(void)
936 {
937 	DSSDBG("audio_stop\n");
938 
939 	hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
940 }
941 
hdmi_mode_has_audio(void)942 bool hdmi_mode_has_audio(void)
943 {
944 	if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI)
945 		return true;
946 	else
947 		return false;
948 }
949 
hdmi_audio_config(struct omap_dss_audio * audio)950 int hdmi_audio_config(struct omap_dss_audio *audio)
951 {
952 	return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
953 }
954 
955 #endif
956 
hdmi_find_dssdev(struct platform_device * pdev)957 static struct omap_dss_device *hdmi_find_dssdev(struct platform_device *pdev)
958 {
959 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
960 	const char *def_disp_name = omapdss_get_default_display_name();
961 	struct omap_dss_device *def_dssdev;
962 	int i;
963 
964 	def_dssdev = NULL;
965 
966 	for (i = 0; i < pdata->num_devices; ++i) {
967 		struct omap_dss_device *dssdev = pdata->devices[i];
968 
969 		if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
970 			continue;
971 
972 		if (def_dssdev == NULL)
973 			def_dssdev = dssdev;
974 
975 		if (def_disp_name != NULL &&
976 				strcmp(dssdev->name, def_disp_name) == 0) {
977 			def_dssdev = dssdev;
978 			break;
979 		}
980 	}
981 
982 	return def_dssdev;
983 }
984 
hdmi_probe_pdata(struct platform_device * pdev)985 static int hdmi_probe_pdata(struct platform_device *pdev)
986 {
987 	struct omap_dss_device *plat_dssdev;
988 	struct omap_dss_device *dssdev;
989 	struct omap_dss_hdmi_data *priv;
990 	int r;
991 
992 	plat_dssdev = hdmi_find_dssdev(pdev);
993 
994 	if (!plat_dssdev)
995 		return 0;
996 
997 	dssdev = dss_alloc_and_init_device(&pdev->dev);
998 	if (!dssdev)
999 		return -ENOMEM;
1000 
1001 	dss_copy_device_pdata(dssdev, plat_dssdev);
1002 
1003 	priv = dssdev->data;
1004 
1005 	hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
1006 	hdmi.ls_oe_gpio = priv->ls_oe_gpio;
1007 	hdmi.hpd_gpio = priv->hpd_gpio;
1008 
1009 	r = hdmi_init_display(dssdev);
1010 	if (r) {
1011 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
1012 		dss_put_device(dssdev);
1013 		return r;
1014 	}
1015 
1016 	r = omapdss_output_set_device(&hdmi.output, dssdev);
1017 	if (r) {
1018 		DSSERR("failed to connect output to new device: %s\n",
1019 				dssdev->name);
1020 		dss_put_device(dssdev);
1021 		return r;
1022 	}
1023 
1024 	r = dss_add_device(dssdev);
1025 	if (r) {
1026 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
1027 		omapdss_output_unset_device(&hdmi.output);
1028 		hdmi_uninit_display(dssdev);
1029 		dss_put_device(dssdev);
1030 		return r;
1031 	}
1032 
1033 	return 0;
1034 }
1035 
hdmi_init_output(struct platform_device * pdev)1036 static void hdmi_init_output(struct platform_device *pdev)
1037 {
1038 	struct omap_dss_output *out = &hdmi.output;
1039 
1040 	out->pdev = pdev;
1041 	out->id = OMAP_DSS_OUTPUT_HDMI;
1042 	out->type = OMAP_DISPLAY_TYPE_HDMI;
1043 	out->name = "hdmi.0";
1044 	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
1045 
1046 	dss_register_output(out);
1047 }
1048 
hdmi_uninit_output(struct platform_device * pdev)1049 static void __exit hdmi_uninit_output(struct platform_device *pdev)
1050 {
1051 	struct omap_dss_output *out = &hdmi.output;
1052 
1053 	dss_unregister_output(out);
1054 }
1055 
1056 /* HDMI HW IP initialisation */
omapdss_hdmihw_probe(struct platform_device * pdev)1057 static int omapdss_hdmihw_probe(struct platform_device *pdev)
1058 {
1059 	struct resource *res;
1060 	int r;
1061 
1062 	hdmi.pdev = pdev;
1063 
1064 	mutex_init(&hdmi.lock);
1065 	mutex_init(&hdmi.ip_data.lock);
1066 
1067 	res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1068 
1069 	/* Base address taken from platform */
1070 	hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res);
1071 	if (IS_ERR(hdmi.ip_data.base_wp))
1072 		return PTR_ERR(hdmi.ip_data.base_wp);
1073 
1074 	r = hdmi_get_clocks(pdev);
1075 	if (r) {
1076 		DSSERR("can't get clocks\n");
1077 		return r;
1078 	}
1079 
1080 	pm_runtime_enable(&pdev->dev);
1081 
1082 	hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
1083 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
1084 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1085 	hdmi.ip_data.phy_offset = HDMI_PHY;
1086 
1087 	hdmi_init_output(pdev);
1088 
1089 	r = hdmi_panel_init();
1090 	if (r) {
1091 		DSSERR("can't init panel\n");
1092 		return r;
1093 	}
1094 
1095 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1096 
1097 	r = hdmi_probe_pdata(pdev);
1098 	if (r) {
1099 		hdmi_panel_exit();
1100 		hdmi_uninit_output(pdev);
1101 		pm_runtime_disable(&pdev->dev);
1102 		return r;
1103 	}
1104 
1105 	return 0;
1106 }
1107 
hdmi_remove_child(struct device * dev,void * data)1108 static int __exit hdmi_remove_child(struct device *dev, void *data)
1109 {
1110 	struct omap_dss_device *dssdev = to_dss_device(dev);
1111 	hdmi_uninit_display(dssdev);
1112 	return 0;
1113 }
1114 
omapdss_hdmihw_remove(struct platform_device * pdev)1115 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1116 {
1117 	device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
1118 
1119 	dss_unregister_child_devices(&pdev->dev);
1120 
1121 	hdmi_panel_exit();
1122 
1123 	hdmi_uninit_output(pdev);
1124 
1125 	pm_runtime_disable(&pdev->dev);
1126 
1127 	return 0;
1128 }
1129 
hdmi_runtime_suspend(struct device * dev)1130 static int hdmi_runtime_suspend(struct device *dev)
1131 {
1132 	clk_disable_unprepare(hdmi.sys_clk);
1133 
1134 	dispc_runtime_put();
1135 
1136 	return 0;
1137 }
1138 
hdmi_runtime_resume(struct device * dev)1139 static int hdmi_runtime_resume(struct device *dev)
1140 {
1141 	int r;
1142 
1143 	r = dispc_runtime_get();
1144 	if (r < 0)
1145 		return r;
1146 
1147 	clk_prepare_enable(hdmi.sys_clk);
1148 
1149 	return 0;
1150 }
1151 
1152 static const struct dev_pm_ops hdmi_pm_ops = {
1153 	.runtime_suspend = hdmi_runtime_suspend,
1154 	.runtime_resume = hdmi_runtime_resume,
1155 };
1156 
1157 static struct platform_driver omapdss_hdmihw_driver = {
1158 	.probe		= omapdss_hdmihw_probe,
1159 	.remove         = __exit_p(omapdss_hdmihw_remove),
1160 	.driver         = {
1161 		.name   = "omapdss_hdmi",
1162 		.owner  = THIS_MODULE,
1163 		.pm	= &hdmi_pm_ops,
1164 	},
1165 };
1166 
hdmi_init_platform_driver(void)1167 int __init hdmi_init_platform_driver(void)
1168 {
1169 	return platform_driver_register(&omapdss_hdmihw_driver);
1170 }
1171 
hdmi_uninit_platform_driver(void)1172 void __exit hdmi_uninit_platform_driver(void)
1173 {
1174 	platform_driver_unregister(&omapdss_hdmihw_driver);
1175 }
1176