diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 1437 |
1 files changed, 1326 insertions, 111 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 3429d3fd93f3..575a8cbd3533 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -41,44 +41,83 @@ | |||
41 | #include "exynos_hdmi.h" | 41 | #include "exynos_hdmi.h" |
42 | 42 | ||
43 | #define HDMI_OVERLAY_NUMBER 3 | 43 | #define HDMI_OVERLAY_NUMBER 3 |
44 | #define MAX_WIDTH 1920 | ||
45 | #define MAX_HEIGHT 1080 | ||
44 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) | 46 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) |
45 | 47 | ||
46 | static const u8 hdmiphy_conf27[32] = { | 48 | struct hdmi_resources { |
49 | struct clk *hdmi; | ||
50 | struct clk *sclk_hdmi; | ||
51 | struct clk *sclk_pixel; | ||
52 | struct clk *sclk_hdmiphy; | ||
53 | struct clk *hdmiphy; | ||
54 | struct regulator_bulk_data *regul_bulk; | ||
55 | int regul_count; | ||
56 | }; | ||
57 | |||
58 | struct hdmi_context { | ||
59 | struct device *dev; | ||
60 | struct drm_device *drm_dev; | ||
61 | struct fb_videomode *default_timing; | ||
62 | unsigned int is_v13:1; | ||
63 | unsigned int default_win; | ||
64 | unsigned int default_bpp; | ||
65 | bool hpd_handle; | ||
66 | bool enabled; | ||
67 | |||
68 | struct resource *regs_res; | ||
69 | void __iomem *regs; | ||
70 | unsigned int irq; | ||
71 | struct workqueue_struct *wq; | ||
72 | struct work_struct hotplug_work; | ||
73 | |||
74 | struct i2c_client *ddc_port; | ||
75 | struct i2c_client *hdmiphy_port; | ||
76 | |||
77 | /* current hdmiphy conf index */ | ||
78 | int cur_conf; | ||
79 | |||
80 | struct hdmi_resources res; | ||
81 | void *parent_ctx; | ||
82 | }; | ||
83 | |||
84 | /* HDMI Version 1.3 */ | ||
85 | static const u8 hdmiphy_v13_conf27[32] = { | ||
47 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, | 86 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, |
48 | 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, | 87 | 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, |
49 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, | 88 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, |
50 | 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, | 89 | 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, |
51 | }; | 90 | }; |
52 | 91 | ||
53 | static const u8 hdmiphy_conf27_027[32] = { | 92 | static const u8 hdmiphy_v13_conf27_027[32] = { |
54 | 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, | 93 | 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, |
55 | 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, | 94 | 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, |
56 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, | 95 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, |
57 | 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, | 96 | 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, |
58 | }; | 97 | }; |
59 | 98 | ||
60 | static const u8 hdmiphy_conf74_175[32] = { | 99 | static const u8 hdmiphy_v13_conf74_175[32] = { |
61 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, | 100 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, |
62 | 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, | 101 | 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, |
63 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, | 102 | 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, |
64 | 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, | 103 | 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, |
65 | }; | 104 | }; |
66 | 105 | ||
67 | static const u8 hdmiphy_conf74_25[32] = { | 106 | static const u8 hdmiphy_v13_conf74_25[32] = { |
68 | 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, | 107 | 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, |
69 | 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, | 108 | 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, |
70 | 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, | 109 | 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, |
71 | 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, | 110 | 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, |
72 | }; | 111 | }; |
73 | 112 | ||
74 | static const u8 hdmiphy_conf148_5[32] = { | 113 | static const u8 hdmiphy_v13_conf148_5[32] = { |
75 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, | 114 | 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, |
76 | 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, | 115 | 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, |
77 | 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, | 116 | 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, |
78 | 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, | 117 | 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, |
79 | }; | 118 | }; |
80 | 119 | ||
81 | struct hdmi_tg_regs { | 120 | struct hdmi_v13_tg_regs { |
82 | u8 cmd; | 121 | u8 cmd; |
83 | u8 h_fsz_l; | 122 | u8 h_fsz_l; |
84 | u8 h_fsz_h; | 123 | u8 h_fsz_h; |
@@ -110,7 +149,7 @@ struct hdmi_tg_regs { | |||
110 | u8 field_bot_hdmi_h; | 149 | u8 field_bot_hdmi_h; |
111 | }; | 150 | }; |
112 | 151 | ||
113 | struct hdmi_core_regs { | 152 | struct hdmi_v13_core_regs { |
114 | u8 h_blank[2]; | 153 | u8 h_blank[2]; |
115 | u8 v_blank[3]; | 154 | u8 v_blank[3]; |
116 | u8 h_v_line[3]; | 155 | u8 h_v_line[3]; |
@@ -123,12 +162,21 @@ struct hdmi_core_regs { | |||
123 | u8 v_sync_gen3[3]; | 162 | u8 v_sync_gen3[3]; |
124 | }; | 163 | }; |
125 | 164 | ||
126 | struct hdmi_preset_conf { | 165 | struct hdmi_v13_preset_conf { |
127 | struct hdmi_core_regs core; | 166 | struct hdmi_v13_core_regs core; |
128 | struct hdmi_tg_regs tg; | 167 | struct hdmi_v13_tg_regs tg; |
129 | }; | 168 | }; |
130 | 169 | ||
131 | static const struct hdmi_preset_conf hdmi_conf_480p = { | 170 | struct hdmi_v13_conf { |
171 | int width; | ||
172 | int height; | ||
173 | int vrefresh; | ||
174 | bool interlace; | ||
175 | const u8 *hdmiphy_data; | ||
176 | const struct hdmi_v13_preset_conf *conf; | ||
177 | }; | ||
178 | |||
179 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = { | ||
132 | .core = { | 180 | .core = { |
133 | .h_blank = {0x8a, 0x00}, | 181 | .h_blank = {0x8a, 0x00}, |
134 | .v_blank = {0x0d, 0x6a, 0x01}, | 182 | .v_blank = {0x0d, 0x6a, 0x01}, |
@@ -154,7 +202,7 @@ static const struct hdmi_preset_conf hdmi_conf_480p = { | |||
154 | }, | 202 | }, |
155 | }; | 203 | }; |
156 | 204 | ||
157 | static const struct hdmi_preset_conf hdmi_conf_720p60 = { | 205 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = { |
158 | .core = { | 206 | .core = { |
159 | .h_blank = {0x72, 0x01}, | 207 | .h_blank = {0x72, 0x01}, |
160 | .v_blank = {0xee, 0xf2, 0x00}, | 208 | .v_blank = {0xee, 0xf2, 0x00}, |
@@ -182,7 +230,7 @@ static const struct hdmi_preset_conf hdmi_conf_720p60 = { | |||
182 | }, | 230 | }, |
183 | }; | 231 | }; |
184 | 232 | ||
185 | static const struct hdmi_preset_conf hdmi_conf_1080i50 = { | 233 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = { |
186 | .core = { | 234 | .core = { |
187 | .h_blank = {0xd0, 0x02}, | 235 | .h_blank = {0xd0, 0x02}, |
188 | .v_blank = {0x32, 0xB2, 0x00}, | 236 | .v_blank = {0x32, 0xB2, 0x00}, |
@@ -210,7 +258,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i50 = { | |||
210 | }, | 258 | }, |
211 | }; | 259 | }; |
212 | 260 | ||
213 | static const struct hdmi_preset_conf hdmi_conf_1080p50 = { | 261 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = { |
214 | .core = { | 262 | .core = { |
215 | .h_blank = {0xd0, 0x02}, | 263 | .h_blank = {0xd0, 0x02}, |
216 | .v_blank = {0x65, 0x6c, 0x01}, | 264 | .v_blank = {0x65, 0x6c, 0x01}, |
@@ -238,7 +286,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080p50 = { | |||
238 | }, | 286 | }, |
239 | }; | 287 | }; |
240 | 288 | ||
241 | static const struct hdmi_preset_conf hdmi_conf_1080i60 = { | 289 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = { |
242 | .core = { | 290 | .core = { |
243 | .h_blank = {0x18, 0x01}, | 291 | .h_blank = {0x18, 0x01}, |
244 | .v_blank = {0x32, 0xB2, 0x00}, | 292 | .v_blank = {0x32, 0xB2, 0x00}, |
@@ -266,7 +314,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i60 = { | |||
266 | }, | 314 | }, |
267 | }; | 315 | }; |
268 | 316 | ||
269 | static const struct hdmi_preset_conf hdmi_conf_1080p60 = { | 317 | static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = { |
270 | .core = { | 318 | .core = { |
271 | .h_blank = {0x18, 0x01}, | 319 | .h_blank = {0x18, 0x01}, |
272 | .v_blank = {0x65, 0x6c, 0x01}, | 320 | .v_blank = {0x65, 0x6c, 0x01}, |
@@ -294,13 +342,530 @@ static const struct hdmi_preset_conf hdmi_conf_1080p60 = { | |||
294 | }, | 342 | }, |
295 | }; | 343 | }; |
296 | 344 | ||
345 | static const struct hdmi_v13_conf hdmi_v13_confs[] = { | ||
346 | { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, | ||
347 | { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, | ||
348 | { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p }, | ||
349 | { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 }, | ||
350 | { 1920, 1080, 50, false, hdmiphy_v13_conf148_5, | ||
351 | &hdmi_v13_conf_1080p50 }, | ||
352 | { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 }, | ||
353 | { 1920, 1080, 60, false, hdmiphy_v13_conf148_5, | ||
354 | &hdmi_v13_conf_1080p60 }, | ||
355 | }; | ||
356 | |||
357 | /* HDMI Version 1.4 */ | ||
358 | static const u8 hdmiphy_conf27_027[32] = { | ||
359 | 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08, | ||
360 | 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, | ||
361 | 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, | ||
362 | 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, | ||
363 | }; | ||
364 | |||
365 | static const u8 hdmiphy_conf74_25[32] = { | ||
366 | 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08, | ||
367 | 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, | ||
368 | 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, | ||
369 | 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, | ||
370 | }; | ||
371 | |||
372 | static const u8 hdmiphy_conf148_5[32] = { | ||
373 | 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08, | ||
374 | 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, | ||
375 | 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, | ||
376 | 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, | ||
377 | }; | ||
378 | |||
379 | struct hdmi_tg_regs { | ||
380 | u8 cmd; | ||
381 | u8 h_fsz_l; | ||
382 | u8 h_fsz_h; | ||
383 | u8 hact_st_l; | ||
384 | u8 hact_st_h; | ||
385 | u8 hact_sz_l; | ||
386 | u8 hact_sz_h; | ||
387 | u8 v_fsz_l; | ||
388 | u8 v_fsz_h; | ||
389 | u8 vsync_l; | ||
390 | u8 vsync_h; | ||
391 | u8 vsync2_l; | ||
392 | u8 vsync2_h; | ||
393 | u8 vact_st_l; | ||
394 | u8 vact_st_h; | ||
395 | u8 vact_sz_l; | ||
396 | u8 vact_sz_h; | ||
397 | u8 field_chg_l; | ||
398 | u8 field_chg_h; | ||
399 | u8 vact_st2_l; | ||
400 | u8 vact_st2_h; | ||
401 | u8 vact_st3_l; | ||
402 | u8 vact_st3_h; | ||
403 | u8 vact_st4_l; | ||
404 | u8 vact_st4_h; | ||
405 | u8 vsync_top_hdmi_l; | ||
406 | u8 vsync_top_hdmi_h; | ||
407 | u8 vsync_bot_hdmi_l; | ||
408 | u8 vsync_bot_hdmi_h; | ||
409 | u8 field_top_hdmi_l; | ||
410 | u8 field_top_hdmi_h; | ||
411 | u8 field_bot_hdmi_l; | ||
412 | u8 field_bot_hdmi_h; | ||
413 | u8 tg_3d; | ||
414 | }; | ||
415 | |||
416 | struct hdmi_core_regs { | ||
417 | u8 h_blank[2]; | ||
418 | u8 v2_blank[2]; | ||
419 | u8 v1_blank[2]; | ||
420 | u8 v_line[2]; | ||
421 | u8 h_line[2]; | ||
422 | u8 hsync_pol[1]; | ||
423 | u8 vsync_pol[1]; | ||
424 | u8 int_pro_mode[1]; | ||
425 | u8 v_blank_f0[2]; | ||
426 | u8 v_blank_f1[2]; | ||
427 | u8 h_sync_start[2]; | ||
428 | u8 h_sync_end[2]; | ||
429 | u8 v_sync_line_bef_2[2]; | ||
430 | u8 v_sync_line_bef_1[2]; | ||
431 | u8 v_sync_line_aft_2[2]; | ||
432 | u8 v_sync_line_aft_1[2]; | ||
433 | u8 v_sync_line_aft_pxl_2[2]; | ||
434 | u8 v_sync_line_aft_pxl_1[2]; | ||
435 | u8 v_blank_f2[2]; /* for 3D mode */ | ||
436 | u8 v_blank_f3[2]; /* for 3D mode */ | ||
437 | u8 v_blank_f4[2]; /* for 3D mode */ | ||
438 | u8 v_blank_f5[2]; /* for 3D mode */ | ||
439 | u8 v_sync_line_aft_3[2]; | ||
440 | u8 v_sync_line_aft_4[2]; | ||
441 | u8 v_sync_line_aft_5[2]; | ||
442 | u8 v_sync_line_aft_6[2]; | ||
443 | u8 v_sync_line_aft_pxl_3[2]; | ||
444 | u8 v_sync_line_aft_pxl_4[2]; | ||
445 | u8 v_sync_line_aft_pxl_5[2]; | ||
446 | u8 v_sync_line_aft_pxl_6[2]; | ||
447 | u8 vact_space_1[2]; | ||
448 | u8 vact_space_2[2]; | ||
449 | u8 vact_space_3[2]; | ||
450 | u8 vact_space_4[2]; | ||
451 | u8 vact_space_5[2]; | ||
452 | u8 vact_space_6[2]; | ||
453 | }; | ||
454 | |||
455 | struct hdmi_preset_conf { | ||
456 | struct hdmi_core_regs core; | ||
457 | struct hdmi_tg_regs tg; | ||
458 | }; | ||
459 | |||
460 | struct hdmi_conf { | ||
461 | int width; | ||
462 | int height; | ||
463 | int vrefresh; | ||
464 | bool interlace; | ||
465 | const u8 *hdmiphy_data; | ||
466 | const struct hdmi_preset_conf *conf; | ||
467 | }; | ||
468 | |||
469 | static const struct hdmi_preset_conf hdmi_conf_480p60 = { | ||
470 | .core = { | ||
471 | .h_blank = {0x8a, 0x00}, | ||
472 | .v2_blank = {0x0d, 0x02}, | ||
473 | .v1_blank = {0x2d, 0x00}, | ||
474 | .v_line = {0x0d, 0x02}, | ||
475 | .h_line = {0x5a, 0x03}, | ||
476 | .hsync_pol = {0x01}, | ||
477 | .vsync_pol = {0x01}, | ||
478 | .int_pro_mode = {0x00}, | ||
479 | .v_blank_f0 = {0xff, 0xff}, | ||
480 | .v_blank_f1 = {0xff, 0xff}, | ||
481 | .h_sync_start = {0x0e, 0x00}, | ||
482 | .h_sync_end = {0x4c, 0x00}, | ||
483 | .v_sync_line_bef_2 = {0x0f, 0x00}, | ||
484 | .v_sync_line_bef_1 = {0x09, 0x00}, | ||
485 | .v_sync_line_aft_2 = {0xff, 0xff}, | ||
486 | .v_sync_line_aft_1 = {0xff, 0xff}, | ||
487 | .v_sync_line_aft_pxl_2 = {0xff, 0xff}, | ||
488 | .v_sync_line_aft_pxl_1 = {0xff, 0xff}, | ||
489 | .v_blank_f2 = {0xff, 0xff}, | ||
490 | .v_blank_f3 = {0xff, 0xff}, | ||
491 | .v_blank_f4 = {0xff, 0xff}, | ||
492 | .v_blank_f5 = {0xff, 0xff}, | ||
493 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
494 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
495 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
496 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
497 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
498 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
499 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
500 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
501 | .vact_space_1 = {0xff, 0xff}, | ||
502 | .vact_space_2 = {0xff, 0xff}, | ||
503 | .vact_space_3 = {0xff, 0xff}, | ||
504 | .vact_space_4 = {0xff, 0xff}, | ||
505 | .vact_space_5 = {0xff, 0xff}, | ||
506 | .vact_space_6 = {0xff, 0xff}, | ||
507 | /* other don't care */ | ||
508 | }, | ||
509 | .tg = { | ||
510 | 0x00, /* cmd */ | ||
511 | 0x5a, 0x03, /* h_fsz */ | ||
512 | 0x8a, 0x00, 0xd0, 0x02, /* hact */ | ||
513 | 0x0d, 0x02, /* v_fsz */ | ||
514 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
515 | 0x2d, 0x00, 0xe0, 0x01, /* vact */ | ||
516 | 0x33, 0x02, /* field_chg */ | ||
517 | 0x48, 0x02, /* vact_st2 */ | ||
518 | 0x00, 0x00, /* vact_st3 */ | ||
519 | 0x00, 0x00, /* vact_st4 */ | ||
520 | 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ | ||
521 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
522 | 0x00, /* 3d FP */ | ||
523 | }, | ||
524 | }; | ||
525 | |||
526 | static const struct hdmi_preset_conf hdmi_conf_720p50 = { | ||
527 | .core = { | ||
528 | .h_blank = {0xbc, 0x02}, | ||
529 | .v2_blank = {0xee, 0x02}, | ||
530 | .v1_blank = {0x1e, 0x00}, | ||
531 | .v_line = {0xee, 0x02}, | ||
532 | .h_line = {0xbc, 0x07}, | ||
533 | .hsync_pol = {0x00}, | ||
534 | .vsync_pol = {0x00}, | ||
535 | .int_pro_mode = {0x00}, | ||
536 | .v_blank_f0 = {0xff, 0xff}, | ||
537 | .v_blank_f1 = {0xff, 0xff}, | ||
538 | .h_sync_start = {0xb6, 0x01}, | ||
539 | .h_sync_end = {0xde, 0x01}, | ||
540 | .v_sync_line_bef_2 = {0x0a, 0x00}, | ||
541 | .v_sync_line_bef_1 = {0x05, 0x00}, | ||
542 | .v_sync_line_aft_2 = {0xff, 0xff}, | ||
543 | .v_sync_line_aft_1 = {0xff, 0xff}, | ||
544 | .v_sync_line_aft_pxl_2 = {0xff, 0xff}, | ||
545 | .v_sync_line_aft_pxl_1 = {0xff, 0xff}, | ||
546 | .v_blank_f2 = {0xff, 0xff}, | ||
547 | .v_blank_f3 = {0xff, 0xff}, | ||
548 | .v_blank_f4 = {0xff, 0xff}, | ||
549 | .v_blank_f5 = {0xff, 0xff}, | ||
550 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
551 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
552 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
553 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
554 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
555 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
556 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
557 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
558 | .vact_space_1 = {0xff, 0xff}, | ||
559 | .vact_space_2 = {0xff, 0xff}, | ||
560 | .vact_space_3 = {0xff, 0xff}, | ||
561 | .vact_space_4 = {0xff, 0xff}, | ||
562 | .vact_space_5 = {0xff, 0xff}, | ||
563 | .vact_space_6 = {0xff, 0xff}, | ||
564 | /* other don't care */ | ||
565 | }, | ||
566 | .tg = { | ||
567 | 0x00, /* cmd */ | ||
568 | 0xbc, 0x07, /* h_fsz */ | ||
569 | 0xbc, 0x02, 0x00, 0x05, /* hact */ | ||
570 | 0xee, 0x02, /* v_fsz */ | ||
571 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
572 | 0x1e, 0x00, 0xd0, 0x02, /* vact */ | ||
573 | 0x33, 0x02, /* field_chg */ | ||
574 | 0x48, 0x02, /* vact_st2 */ | ||
575 | 0x00, 0x00, /* vact_st3 */ | ||
576 | 0x00, 0x00, /* vact_st4 */ | ||
577 | 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ | ||
578 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
579 | 0x00, /* 3d FP */ | ||
580 | }, | ||
581 | }; | ||
582 | |||
583 | static const struct hdmi_preset_conf hdmi_conf_720p60 = { | ||
584 | .core = { | ||
585 | .h_blank = {0x72, 0x01}, | ||
586 | .v2_blank = {0xee, 0x02}, | ||
587 | .v1_blank = {0x1e, 0x00}, | ||
588 | .v_line = {0xee, 0x02}, | ||
589 | .h_line = {0x72, 0x06}, | ||
590 | .hsync_pol = {0x00}, | ||
591 | .vsync_pol = {0x00}, | ||
592 | .int_pro_mode = {0x00}, | ||
593 | .v_blank_f0 = {0xff, 0xff}, | ||
594 | .v_blank_f1 = {0xff, 0xff}, | ||
595 | .h_sync_start = {0x6c, 0x00}, | ||
596 | .h_sync_end = {0x94, 0x00}, | ||
597 | .v_sync_line_bef_2 = {0x0a, 0x00}, | ||
598 | .v_sync_line_bef_1 = {0x05, 0x00}, | ||
599 | .v_sync_line_aft_2 = {0xff, 0xff}, | ||
600 | .v_sync_line_aft_1 = {0xff, 0xff}, | ||
601 | .v_sync_line_aft_pxl_2 = {0xff, 0xff}, | ||
602 | .v_sync_line_aft_pxl_1 = {0xff, 0xff}, | ||
603 | .v_blank_f2 = {0xff, 0xff}, | ||
604 | .v_blank_f3 = {0xff, 0xff}, | ||
605 | .v_blank_f4 = {0xff, 0xff}, | ||
606 | .v_blank_f5 = {0xff, 0xff}, | ||
607 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
608 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
609 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
610 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
611 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
612 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
613 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
614 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
615 | .vact_space_1 = {0xff, 0xff}, | ||
616 | .vact_space_2 = {0xff, 0xff}, | ||
617 | .vact_space_3 = {0xff, 0xff}, | ||
618 | .vact_space_4 = {0xff, 0xff}, | ||
619 | .vact_space_5 = {0xff, 0xff}, | ||
620 | .vact_space_6 = {0xff, 0xff}, | ||
621 | /* other don't care */ | ||
622 | }, | ||
623 | .tg = { | ||
624 | 0x00, /* cmd */ | ||
625 | 0x72, 0x06, /* h_fsz */ | ||
626 | 0x72, 0x01, 0x00, 0x05, /* hact */ | ||
627 | 0xee, 0x02, /* v_fsz */ | ||
628 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
629 | 0x1e, 0x00, 0xd0, 0x02, /* vact */ | ||
630 | 0x33, 0x02, /* field_chg */ | ||
631 | 0x48, 0x02, /* vact_st2 */ | ||
632 | 0x00, 0x00, /* vact_st3 */ | ||
633 | 0x00, 0x00, /* vact_st4 */ | ||
634 | 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ | ||
635 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
636 | 0x00, /* 3d FP */ | ||
637 | }, | ||
638 | }; | ||
639 | |||
640 | static const struct hdmi_preset_conf hdmi_conf_1080i50 = { | ||
641 | .core = { | ||
642 | .h_blank = {0xd0, 0x02}, | ||
643 | .v2_blank = {0x32, 0x02}, | ||
644 | .v1_blank = {0x16, 0x00}, | ||
645 | .v_line = {0x65, 0x04}, | ||
646 | .h_line = {0x50, 0x0a}, | ||
647 | .hsync_pol = {0x00}, | ||
648 | .vsync_pol = {0x00}, | ||
649 | .int_pro_mode = {0x01}, | ||
650 | .v_blank_f0 = {0x49, 0x02}, | ||
651 | .v_blank_f1 = {0x65, 0x04}, | ||
652 | .h_sync_start = {0x0e, 0x02}, | ||
653 | .h_sync_end = {0x3a, 0x02}, | ||
654 | .v_sync_line_bef_2 = {0x07, 0x00}, | ||
655 | .v_sync_line_bef_1 = {0x02, 0x00}, | ||
656 | .v_sync_line_aft_2 = {0x39, 0x02}, | ||
657 | .v_sync_line_aft_1 = {0x34, 0x02}, | ||
658 | .v_sync_line_aft_pxl_2 = {0x38, 0x07}, | ||
659 | .v_sync_line_aft_pxl_1 = {0x38, 0x07}, | ||
660 | .v_blank_f2 = {0xff, 0xff}, | ||
661 | .v_blank_f3 = {0xff, 0xff}, | ||
662 | .v_blank_f4 = {0xff, 0xff}, | ||
663 | .v_blank_f5 = {0xff, 0xff}, | ||
664 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
665 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
666 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
667 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
668 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
669 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
670 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
671 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
672 | .vact_space_1 = {0xff, 0xff}, | ||
673 | .vact_space_2 = {0xff, 0xff}, | ||
674 | .vact_space_3 = {0xff, 0xff}, | ||
675 | .vact_space_4 = {0xff, 0xff}, | ||
676 | .vact_space_5 = {0xff, 0xff}, | ||
677 | .vact_space_6 = {0xff, 0xff}, | ||
678 | /* other don't care */ | ||
679 | }, | ||
680 | .tg = { | ||
681 | 0x00, /* cmd */ | ||
682 | 0x50, 0x0a, /* h_fsz */ | ||
683 | 0xd0, 0x02, 0x80, 0x07, /* hact */ | ||
684 | 0x65, 0x04, /* v_fsz */ | ||
685 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
686 | 0x16, 0x00, 0x1c, 0x02, /* vact */ | ||
687 | 0x33, 0x02, /* field_chg */ | ||
688 | 0x49, 0x02, /* vact_st2 */ | ||
689 | 0x00, 0x00, /* vact_st3 */ | ||
690 | 0x00, 0x00, /* vact_st4 */ | ||
691 | 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ | ||
692 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
693 | 0x00, /* 3d FP */ | ||
694 | }, | ||
695 | }; | ||
696 | |||
697 | static const struct hdmi_preset_conf hdmi_conf_1080i60 = { | ||
698 | .core = { | ||
699 | .h_blank = {0x18, 0x01}, | ||
700 | .v2_blank = {0x32, 0x02}, | ||
701 | .v1_blank = {0x16, 0x00}, | ||
702 | .v_line = {0x65, 0x04}, | ||
703 | .h_line = {0x98, 0x08}, | ||
704 | .hsync_pol = {0x00}, | ||
705 | .vsync_pol = {0x00}, | ||
706 | .int_pro_mode = {0x01}, | ||
707 | .v_blank_f0 = {0x49, 0x02}, | ||
708 | .v_blank_f1 = {0x65, 0x04}, | ||
709 | .h_sync_start = {0x56, 0x00}, | ||
710 | .h_sync_end = {0x82, 0x00}, | ||
711 | .v_sync_line_bef_2 = {0x07, 0x00}, | ||
712 | .v_sync_line_bef_1 = {0x02, 0x00}, | ||
713 | .v_sync_line_aft_2 = {0x39, 0x02}, | ||
714 | .v_sync_line_aft_1 = {0x34, 0x02}, | ||
715 | .v_sync_line_aft_pxl_2 = {0xa4, 0x04}, | ||
716 | .v_sync_line_aft_pxl_1 = {0xa4, 0x04}, | ||
717 | .v_blank_f2 = {0xff, 0xff}, | ||
718 | .v_blank_f3 = {0xff, 0xff}, | ||
719 | .v_blank_f4 = {0xff, 0xff}, | ||
720 | .v_blank_f5 = {0xff, 0xff}, | ||
721 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
722 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
723 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
724 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
725 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
726 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
727 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
728 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
729 | .vact_space_1 = {0xff, 0xff}, | ||
730 | .vact_space_2 = {0xff, 0xff}, | ||
731 | .vact_space_3 = {0xff, 0xff}, | ||
732 | .vact_space_4 = {0xff, 0xff}, | ||
733 | .vact_space_5 = {0xff, 0xff}, | ||
734 | .vact_space_6 = {0xff, 0xff}, | ||
735 | /* other don't care */ | ||
736 | }, | ||
737 | .tg = { | ||
738 | 0x00, /* cmd */ | ||
739 | 0x98, 0x08, /* h_fsz */ | ||
740 | 0x18, 0x01, 0x80, 0x07, /* hact */ | ||
741 | 0x65, 0x04, /* v_fsz */ | ||
742 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
743 | 0x16, 0x00, 0x1c, 0x02, /* vact */ | ||
744 | 0x33, 0x02, /* field_chg */ | ||
745 | 0x49, 0x02, /* vact_st2 */ | ||
746 | 0x00, 0x00, /* vact_st3 */ | ||
747 | 0x00, 0x00, /* vact_st4 */ | ||
748 | 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ | ||
749 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
750 | 0x00, /* 3d FP */ | ||
751 | }, | ||
752 | }; | ||
753 | |||
754 | static const struct hdmi_preset_conf hdmi_conf_1080p50 = { | ||
755 | .core = { | ||
756 | .h_blank = {0xd0, 0x02}, | ||
757 | .v2_blank = {0x65, 0x04}, | ||
758 | .v1_blank = {0x2d, 0x00}, | ||
759 | .v_line = {0x65, 0x04}, | ||
760 | .h_line = {0x50, 0x0a}, | ||
761 | .hsync_pol = {0x00}, | ||
762 | .vsync_pol = {0x00}, | ||
763 | .int_pro_mode = {0x00}, | ||
764 | .v_blank_f0 = {0xff, 0xff}, | ||
765 | .v_blank_f1 = {0xff, 0xff}, | ||
766 | .h_sync_start = {0x0e, 0x02}, | ||
767 | .h_sync_end = {0x3a, 0x02}, | ||
768 | .v_sync_line_bef_2 = {0x09, 0x00}, | ||
769 | .v_sync_line_bef_1 = {0x04, 0x00}, | ||
770 | .v_sync_line_aft_2 = {0xff, 0xff}, | ||
771 | .v_sync_line_aft_1 = {0xff, 0xff}, | ||
772 | .v_sync_line_aft_pxl_2 = {0xff, 0xff}, | ||
773 | .v_sync_line_aft_pxl_1 = {0xff, 0xff}, | ||
774 | .v_blank_f2 = {0xff, 0xff}, | ||
775 | .v_blank_f3 = {0xff, 0xff}, | ||
776 | .v_blank_f4 = {0xff, 0xff}, | ||
777 | .v_blank_f5 = {0xff, 0xff}, | ||
778 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
779 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
780 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
781 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
782 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
783 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
784 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
785 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
786 | .vact_space_1 = {0xff, 0xff}, | ||
787 | .vact_space_2 = {0xff, 0xff}, | ||
788 | .vact_space_3 = {0xff, 0xff}, | ||
789 | .vact_space_4 = {0xff, 0xff}, | ||
790 | .vact_space_5 = {0xff, 0xff}, | ||
791 | .vact_space_6 = {0xff, 0xff}, | ||
792 | /* other don't care */ | ||
793 | }, | ||
794 | .tg = { | ||
795 | 0x00, /* cmd */ | ||
796 | 0x50, 0x0a, /* h_fsz */ | ||
797 | 0xd0, 0x02, 0x80, 0x07, /* hact */ | ||
798 | 0x65, 0x04, /* v_fsz */ | ||
799 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
800 | 0x2d, 0x00, 0x38, 0x04, /* vact */ | ||
801 | 0x33, 0x02, /* field_chg */ | ||
802 | 0x48, 0x02, /* vact_st2 */ | ||
803 | 0x00, 0x00, /* vact_st3 */ | ||
804 | 0x00, 0x00, /* vact_st4 */ | ||
805 | 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ | ||
806 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
807 | 0x00, /* 3d FP */ | ||
808 | }, | ||
809 | }; | ||
810 | |||
811 | static const struct hdmi_preset_conf hdmi_conf_1080p60 = { | ||
812 | .core = { | ||
813 | .h_blank = {0x18, 0x01}, | ||
814 | .v2_blank = {0x65, 0x04}, | ||
815 | .v1_blank = {0x2d, 0x00}, | ||
816 | .v_line = {0x65, 0x04}, | ||
817 | .h_line = {0x98, 0x08}, | ||
818 | .hsync_pol = {0x00}, | ||
819 | .vsync_pol = {0x00}, | ||
820 | .int_pro_mode = {0x00}, | ||
821 | .v_blank_f0 = {0xff, 0xff}, | ||
822 | .v_blank_f1 = {0xff, 0xff}, | ||
823 | .h_sync_start = {0x56, 0x00}, | ||
824 | .h_sync_end = {0x82, 0x00}, | ||
825 | .v_sync_line_bef_2 = {0x09, 0x00}, | ||
826 | .v_sync_line_bef_1 = {0x04, 0x00}, | ||
827 | .v_sync_line_aft_2 = {0xff, 0xff}, | ||
828 | .v_sync_line_aft_1 = {0xff, 0xff}, | ||
829 | .v_sync_line_aft_pxl_2 = {0xff, 0xff}, | ||
830 | .v_sync_line_aft_pxl_1 = {0xff, 0xff}, | ||
831 | .v_blank_f2 = {0xff, 0xff}, | ||
832 | .v_blank_f3 = {0xff, 0xff}, | ||
833 | .v_blank_f4 = {0xff, 0xff}, | ||
834 | .v_blank_f5 = {0xff, 0xff}, | ||
835 | .v_sync_line_aft_3 = {0xff, 0xff}, | ||
836 | .v_sync_line_aft_4 = {0xff, 0xff}, | ||
837 | .v_sync_line_aft_5 = {0xff, 0xff}, | ||
838 | .v_sync_line_aft_6 = {0xff, 0xff}, | ||
839 | .v_sync_line_aft_pxl_3 = {0xff, 0xff}, | ||
840 | .v_sync_line_aft_pxl_4 = {0xff, 0xff}, | ||
841 | .v_sync_line_aft_pxl_5 = {0xff, 0xff}, | ||
842 | .v_sync_line_aft_pxl_6 = {0xff, 0xff}, | ||
843 | /* other don't care */ | ||
844 | }, | ||
845 | .tg = { | ||
846 | 0x00, /* cmd */ | ||
847 | 0x98, 0x08, /* h_fsz */ | ||
848 | 0x18, 0x01, 0x80, 0x07, /* hact */ | ||
849 | 0x65, 0x04, /* v_fsz */ | ||
850 | 0x01, 0x00, 0x33, 0x02, /* vsync */ | ||
851 | 0x2d, 0x00, 0x38, 0x04, /* vact */ | ||
852 | 0x33, 0x02, /* field_chg */ | ||
853 | 0x48, 0x02, /* vact_st2 */ | ||
854 | 0x00, 0x00, /* vact_st3 */ | ||
855 | 0x00, 0x00, /* vact_st4 */ | ||
856 | 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ | ||
857 | 0x01, 0x00, 0x33, 0x02, /* field top/bot */ | ||
858 | 0x00, /* 3d FP */ | ||
859 | }, | ||
860 | }; | ||
861 | |||
297 | static const struct hdmi_conf hdmi_confs[] = { | 862 | static const struct hdmi_conf hdmi_confs[] = { |
863 | { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 }, | ||
864 | { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 }, | ||
298 | { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, | 865 | { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, |
299 | { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, | ||
300 | { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p }, | ||
301 | { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, | 866 | { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, |
302 | { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 }, | ||
303 | { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, | 867 | { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, |
868 | { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 }, | ||
304 | { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, | 869 | { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, |
305 | }; | 870 | }; |
306 | 871 | ||
@@ -324,7 +889,7 @@ static inline void hdmi_reg_writemask(struct hdmi_context *hdata, | |||
324 | writel(value, hdata->regs + reg_id); | 889 | writel(value, hdata->regs + reg_id); |
325 | } | 890 | } |
326 | 891 | ||
327 | static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) | 892 | static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) |
328 | { | 893 | { |
329 | #define DUMPREG(reg_id) \ | 894 | #define DUMPREG(reg_id) \ |
330 | DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ | 895 | DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ |
@@ -333,6 +898,101 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) | |||
333 | DUMPREG(HDMI_INTC_FLAG); | 898 | DUMPREG(HDMI_INTC_FLAG); |
334 | DUMPREG(HDMI_INTC_CON); | 899 | DUMPREG(HDMI_INTC_CON); |
335 | DUMPREG(HDMI_HPD_STATUS); | 900 | DUMPREG(HDMI_HPD_STATUS); |
901 | DUMPREG(HDMI_V13_PHY_RSTOUT); | ||
902 | DUMPREG(HDMI_V13_PHY_VPLL); | ||
903 | DUMPREG(HDMI_V13_PHY_CMU); | ||
904 | DUMPREG(HDMI_V13_CORE_RSTOUT); | ||
905 | |||
906 | DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); | ||
907 | DUMPREG(HDMI_CON_0); | ||
908 | DUMPREG(HDMI_CON_1); | ||
909 | DUMPREG(HDMI_CON_2); | ||
910 | DUMPREG(HDMI_SYS_STATUS); | ||
911 | DUMPREG(HDMI_V13_PHY_STATUS); | ||
912 | DUMPREG(HDMI_STATUS_EN); | ||
913 | DUMPREG(HDMI_HPD); | ||
914 | DUMPREG(HDMI_MODE_SEL); | ||
915 | DUMPREG(HDMI_V13_HPD_GEN); | ||
916 | DUMPREG(HDMI_V13_DC_CONTROL); | ||
917 | DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); | ||
918 | |||
919 | DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); | ||
920 | DUMPREG(HDMI_H_BLANK_0); | ||
921 | DUMPREG(HDMI_H_BLANK_1); | ||
922 | DUMPREG(HDMI_V13_V_BLANK_0); | ||
923 | DUMPREG(HDMI_V13_V_BLANK_1); | ||
924 | DUMPREG(HDMI_V13_V_BLANK_2); | ||
925 | DUMPREG(HDMI_V13_H_V_LINE_0); | ||
926 | DUMPREG(HDMI_V13_H_V_LINE_1); | ||
927 | DUMPREG(HDMI_V13_H_V_LINE_2); | ||
928 | DUMPREG(HDMI_VSYNC_POL); | ||
929 | DUMPREG(HDMI_INT_PRO_MODE); | ||
930 | DUMPREG(HDMI_V13_V_BLANK_F_0); | ||
931 | DUMPREG(HDMI_V13_V_BLANK_F_1); | ||
932 | DUMPREG(HDMI_V13_V_BLANK_F_2); | ||
933 | DUMPREG(HDMI_V13_H_SYNC_GEN_0); | ||
934 | DUMPREG(HDMI_V13_H_SYNC_GEN_1); | ||
935 | DUMPREG(HDMI_V13_H_SYNC_GEN_2); | ||
936 | DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); | ||
937 | DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); | ||
938 | DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); | ||
939 | DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); | ||
940 | DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); | ||
941 | DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); | ||
942 | DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); | ||
943 | DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); | ||
944 | DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); | ||
945 | |||
946 | DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); | ||
947 | DUMPREG(HDMI_TG_CMD); | ||
948 | DUMPREG(HDMI_TG_H_FSZ_L); | ||
949 | DUMPREG(HDMI_TG_H_FSZ_H); | ||
950 | DUMPREG(HDMI_TG_HACT_ST_L); | ||
951 | DUMPREG(HDMI_TG_HACT_ST_H); | ||
952 | DUMPREG(HDMI_TG_HACT_SZ_L); | ||
953 | DUMPREG(HDMI_TG_HACT_SZ_H); | ||
954 | DUMPREG(HDMI_TG_V_FSZ_L); | ||
955 | DUMPREG(HDMI_TG_V_FSZ_H); | ||
956 | DUMPREG(HDMI_TG_VSYNC_L); | ||
957 | DUMPREG(HDMI_TG_VSYNC_H); | ||
958 | DUMPREG(HDMI_TG_VSYNC2_L); | ||
959 | DUMPREG(HDMI_TG_VSYNC2_H); | ||
960 | DUMPREG(HDMI_TG_VACT_ST_L); | ||
961 | DUMPREG(HDMI_TG_VACT_ST_H); | ||
962 | DUMPREG(HDMI_TG_VACT_SZ_L); | ||
963 | DUMPREG(HDMI_TG_VACT_SZ_H); | ||
964 | DUMPREG(HDMI_TG_FIELD_CHG_L); | ||
965 | DUMPREG(HDMI_TG_FIELD_CHG_H); | ||
966 | DUMPREG(HDMI_TG_VACT_ST2_L); | ||
967 | DUMPREG(HDMI_TG_VACT_ST2_H); | ||
968 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); | ||
969 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); | ||
970 | DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); | ||
971 | DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); | ||
972 | DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); | ||
973 | DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); | ||
974 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); | ||
975 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); | ||
976 | #undef DUMPREG | ||
977 | } | ||
978 | |||
979 | static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) | ||
980 | { | ||
981 | int i; | ||
982 | |||
983 | #define DUMPREG(reg_id) \ | ||
984 | DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ | ||
985 | readl(hdata->regs + reg_id)) | ||
986 | |||
987 | DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); | ||
988 | DUMPREG(HDMI_INTC_CON); | ||
989 | DUMPREG(HDMI_INTC_FLAG); | ||
990 | DUMPREG(HDMI_HPD_STATUS); | ||
991 | DUMPREG(HDMI_INTC_CON_1); | ||
992 | DUMPREG(HDMI_INTC_FLAG_1); | ||
993 | DUMPREG(HDMI_PHY_STATUS_0); | ||
994 | DUMPREG(HDMI_PHY_STATUS_PLL); | ||
995 | DUMPREG(HDMI_PHY_CON_0); | ||
336 | DUMPREG(HDMI_PHY_RSTOUT); | 996 | DUMPREG(HDMI_PHY_RSTOUT); |
337 | DUMPREG(HDMI_PHY_VPLL); | 997 | DUMPREG(HDMI_PHY_VPLL); |
338 | DUMPREG(HDMI_PHY_CMU); | 998 | DUMPREG(HDMI_PHY_CMU); |
@@ -343,40 +1003,93 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) | |||
343 | DUMPREG(HDMI_CON_1); | 1003 | DUMPREG(HDMI_CON_1); |
344 | DUMPREG(HDMI_CON_2); | 1004 | DUMPREG(HDMI_CON_2); |
345 | DUMPREG(HDMI_SYS_STATUS); | 1005 | DUMPREG(HDMI_SYS_STATUS); |
346 | DUMPREG(HDMI_PHY_STATUS); | 1006 | DUMPREG(HDMI_PHY_STATUS_0); |
347 | DUMPREG(HDMI_STATUS_EN); | 1007 | DUMPREG(HDMI_STATUS_EN); |
348 | DUMPREG(HDMI_HPD); | 1008 | DUMPREG(HDMI_HPD); |
349 | DUMPREG(HDMI_MODE_SEL); | 1009 | DUMPREG(HDMI_MODE_SEL); |
350 | DUMPREG(HDMI_HPD_GEN); | 1010 | DUMPREG(HDMI_ENC_EN); |
351 | DUMPREG(HDMI_DC_CONTROL); | 1011 | DUMPREG(HDMI_DC_CONTROL); |
352 | DUMPREG(HDMI_VIDEO_PATTERN_GEN); | 1012 | DUMPREG(HDMI_VIDEO_PATTERN_GEN); |
353 | 1013 | ||
354 | DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); | 1014 | DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); |
355 | DUMPREG(HDMI_H_BLANK_0); | 1015 | DUMPREG(HDMI_H_BLANK_0); |
356 | DUMPREG(HDMI_H_BLANK_1); | 1016 | DUMPREG(HDMI_H_BLANK_1); |
357 | DUMPREG(HDMI_V_BLANK_0); | 1017 | DUMPREG(HDMI_V2_BLANK_0); |
358 | DUMPREG(HDMI_V_BLANK_1); | 1018 | DUMPREG(HDMI_V2_BLANK_1); |
359 | DUMPREG(HDMI_V_BLANK_2); | 1019 | DUMPREG(HDMI_V1_BLANK_0); |
360 | DUMPREG(HDMI_H_V_LINE_0); | 1020 | DUMPREG(HDMI_V1_BLANK_1); |
361 | DUMPREG(HDMI_H_V_LINE_1); | 1021 | DUMPREG(HDMI_V_LINE_0); |
362 | DUMPREG(HDMI_H_V_LINE_2); | 1022 | DUMPREG(HDMI_V_LINE_1); |
1023 | DUMPREG(HDMI_H_LINE_0); | ||
1024 | DUMPREG(HDMI_H_LINE_1); | ||
1025 | DUMPREG(HDMI_HSYNC_POL); | ||
1026 | |||
363 | DUMPREG(HDMI_VSYNC_POL); | 1027 | DUMPREG(HDMI_VSYNC_POL); |
364 | DUMPREG(HDMI_INT_PRO_MODE); | 1028 | DUMPREG(HDMI_INT_PRO_MODE); |
365 | DUMPREG(HDMI_V_BLANK_F_0); | 1029 | DUMPREG(HDMI_V_BLANK_F0_0); |
366 | DUMPREG(HDMI_V_BLANK_F_1); | 1030 | DUMPREG(HDMI_V_BLANK_F0_1); |
367 | DUMPREG(HDMI_V_BLANK_F_2); | 1031 | DUMPREG(HDMI_V_BLANK_F1_0); |
368 | DUMPREG(HDMI_H_SYNC_GEN_0); | 1032 | DUMPREG(HDMI_V_BLANK_F1_1); |
369 | DUMPREG(HDMI_H_SYNC_GEN_1); | 1033 | |
370 | DUMPREG(HDMI_H_SYNC_GEN_2); | 1034 | DUMPREG(HDMI_H_SYNC_START_0); |
371 | DUMPREG(HDMI_V_SYNC_GEN_1_0); | 1035 | DUMPREG(HDMI_H_SYNC_START_1); |
372 | DUMPREG(HDMI_V_SYNC_GEN_1_1); | 1036 | DUMPREG(HDMI_H_SYNC_END_0); |
373 | DUMPREG(HDMI_V_SYNC_GEN_1_2); | 1037 | DUMPREG(HDMI_H_SYNC_END_1); |
374 | DUMPREG(HDMI_V_SYNC_GEN_2_0); | 1038 | |
375 | DUMPREG(HDMI_V_SYNC_GEN_2_1); | 1039 | DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); |
376 | DUMPREG(HDMI_V_SYNC_GEN_2_2); | 1040 | DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); |
377 | DUMPREG(HDMI_V_SYNC_GEN_3_0); | 1041 | DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); |
378 | DUMPREG(HDMI_V_SYNC_GEN_3_1); | 1042 | DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); |
379 | DUMPREG(HDMI_V_SYNC_GEN_3_2); | 1043 | |
1044 | DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); | ||
1045 | DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); | ||
1046 | DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); | ||
1047 | DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); | ||
1048 | |||
1049 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); | ||
1050 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); | ||
1051 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); | ||
1052 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); | ||
1053 | |||
1054 | DUMPREG(HDMI_V_BLANK_F2_0); | ||
1055 | DUMPREG(HDMI_V_BLANK_F2_1); | ||
1056 | DUMPREG(HDMI_V_BLANK_F3_0); | ||
1057 | DUMPREG(HDMI_V_BLANK_F3_1); | ||
1058 | DUMPREG(HDMI_V_BLANK_F4_0); | ||
1059 | DUMPREG(HDMI_V_BLANK_F4_1); | ||
1060 | DUMPREG(HDMI_V_BLANK_F5_0); | ||
1061 | DUMPREG(HDMI_V_BLANK_F5_1); | ||
1062 | |||
1063 | DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); | ||
1064 | DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); | ||
1065 | DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); | ||
1066 | DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); | ||
1067 | DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); | ||
1068 | DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); | ||
1069 | DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); | ||
1070 | DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); | ||
1071 | |||
1072 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); | ||
1073 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); | ||
1074 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); | ||
1075 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); | ||
1076 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); | ||
1077 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); | ||
1078 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); | ||
1079 | DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); | ||
1080 | |||
1081 | DUMPREG(HDMI_VACT_SPACE_1_0); | ||
1082 | DUMPREG(HDMI_VACT_SPACE_1_1); | ||
1083 | DUMPREG(HDMI_VACT_SPACE_2_0); | ||
1084 | DUMPREG(HDMI_VACT_SPACE_2_1); | ||
1085 | DUMPREG(HDMI_VACT_SPACE_3_0); | ||
1086 | DUMPREG(HDMI_VACT_SPACE_3_1); | ||
1087 | DUMPREG(HDMI_VACT_SPACE_4_0); | ||
1088 | DUMPREG(HDMI_VACT_SPACE_4_1); | ||
1089 | DUMPREG(HDMI_VACT_SPACE_5_0); | ||
1090 | DUMPREG(HDMI_VACT_SPACE_5_1); | ||
1091 | DUMPREG(HDMI_VACT_SPACE_6_0); | ||
1092 | DUMPREG(HDMI_VACT_SPACE_6_1); | ||
380 | 1093 | ||
381 | DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); | 1094 | DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); |
382 | DUMPREG(HDMI_TG_CMD); | 1095 | DUMPREG(HDMI_TG_CMD); |
@@ -400,6 +1113,10 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) | |||
400 | DUMPREG(HDMI_TG_FIELD_CHG_H); | 1113 | DUMPREG(HDMI_TG_FIELD_CHG_H); |
401 | DUMPREG(HDMI_TG_VACT_ST2_L); | 1114 | DUMPREG(HDMI_TG_VACT_ST2_L); |
402 | DUMPREG(HDMI_TG_VACT_ST2_H); | 1115 | DUMPREG(HDMI_TG_VACT_ST2_H); |
1116 | DUMPREG(HDMI_TG_VACT_ST3_L); | ||
1117 | DUMPREG(HDMI_TG_VACT_ST3_H); | ||
1118 | DUMPREG(HDMI_TG_VACT_ST4_L); | ||
1119 | DUMPREG(HDMI_TG_VACT_ST4_H); | ||
403 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); | 1120 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); |
404 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); | 1121 | DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); |
405 | DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); | 1122 | DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); |
@@ -408,10 +1125,49 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) | |||
408 | DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); | 1125 | DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); |
409 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); | 1126 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); |
410 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); | 1127 | DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); |
1128 | DUMPREG(HDMI_TG_3D); | ||
1129 | |||
1130 | DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); | ||
1131 | DUMPREG(HDMI_AVI_CON); | ||
1132 | DUMPREG(HDMI_AVI_HEADER0); | ||
1133 | DUMPREG(HDMI_AVI_HEADER1); | ||
1134 | DUMPREG(HDMI_AVI_HEADER2); | ||
1135 | DUMPREG(HDMI_AVI_CHECK_SUM); | ||
1136 | DUMPREG(HDMI_VSI_CON); | ||
1137 | DUMPREG(HDMI_VSI_HEADER0); | ||
1138 | DUMPREG(HDMI_VSI_HEADER1); | ||
1139 | DUMPREG(HDMI_VSI_HEADER2); | ||
1140 | for (i = 0; i < 7; ++i) | ||
1141 | DUMPREG(HDMI_VSI_DATA(i)); | ||
1142 | |||
411 | #undef DUMPREG | 1143 | #undef DUMPREG |
412 | } | 1144 | } |
413 | 1145 | ||
414 | static int hdmi_conf_index(struct drm_display_mode *mode) | 1146 | static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) |
1147 | { | ||
1148 | if (hdata->is_v13) | ||
1149 | hdmi_v13_regs_dump(hdata, prefix); | ||
1150 | else | ||
1151 | hdmi_v14_regs_dump(hdata, prefix); | ||
1152 | } | ||
1153 | |||
1154 | static int hdmi_v13_conf_index(struct drm_display_mode *mode) | ||
1155 | { | ||
1156 | int i; | ||
1157 | |||
1158 | for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) | ||
1159 | if (hdmi_v13_confs[i].width == mode->hdisplay && | ||
1160 | hdmi_v13_confs[i].height == mode->vdisplay && | ||
1161 | hdmi_v13_confs[i].vrefresh == mode->vrefresh && | ||
1162 | hdmi_v13_confs[i].interlace == | ||
1163 | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? | ||
1164 | true : false)) | ||
1165 | return i; | ||
1166 | |||
1167 | return -EINVAL; | ||
1168 | } | ||
1169 | |||
1170 | static int hdmi_v14_conf_index(struct drm_display_mode *mode) | ||
415 | { | 1171 | { |
416 | int i; | 1172 | int i; |
417 | 1173 | ||
@@ -424,7 +1180,16 @@ static int hdmi_conf_index(struct drm_display_mode *mode) | |||
424 | true : false)) | 1180 | true : false)) |
425 | return i; | 1181 | return i; |
426 | 1182 | ||
427 | return -1; | 1183 | return -EINVAL; |
1184 | } | ||
1185 | |||
1186 | static int hdmi_conf_index(struct hdmi_context *hdata, | ||
1187 | struct drm_display_mode *mode) | ||
1188 | { | ||
1189 | if (hdata->is_v13) | ||
1190 | return hdmi_v13_conf_index(mode); | ||
1191 | |||
1192 | return hdmi_v14_conf_index(mode); | ||
428 | } | 1193 | } |
429 | 1194 | ||
430 | static bool hdmi_is_connected(void *ctx) | 1195 | static bool hdmi_is_connected(void *ctx) |
@@ -462,29 +1227,69 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, | |||
462 | return 0; | 1227 | return 0; |
463 | } | 1228 | } |
464 | 1229 | ||
465 | static int hdmi_check_timing(void *ctx, void *timing) | 1230 | static int hdmi_v13_check_timing(struct fb_videomode *check_timing) |
466 | { | 1231 | { |
467 | struct fb_videomode *check_timing = timing; | ||
468 | int i; | 1232 | int i; |
469 | 1233 | ||
470 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1234 | DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", |
1235 | check_timing->xres, check_timing->yres, | ||
1236 | check_timing->refresh, (check_timing->vmode & | ||
1237 | FB_VMODE_INTERLACED) ? true : false); | ||
471 | 1238 | ||
472 | DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, | 1239 | for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) |
473 | check_timing->yres, check_timing->refresh, | 1240 | if (hdmi_v13_confs[i].width == check_timing->xres && |
474 | check_timing->vmode); | 1241 | hdmi_v13_confs[i].height == check_timing->yres && |
1242 | hdmi_v13_confs[i].vrefresh == check_timing->refresh && | ||
1243 | hdmi_v13_confs[i].interlace == | ||
1244 | ((check_timing->vmode & FB_VMODE_INTERLACED) ? | ||
1245 | true : false)) | ||
1246 | return 0; | ||
475 | 1247 | ||
476 | for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i) | 1248 | /* TODO */ |
1249 | |||
1250 | return -EINVAL; | ||
1251 | } | ||
1252 | |||
1253 | static int hdmi_v14_check_timing(struct fb_videomode *check_timing) | ||
1254 | { | ||
1255 | int i; | ||
1256 | |||
1257 | DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", | ||
1258 | check_timing->xres, check_timing->yres, | ||
1259 | check_timing->refresh, (check_timing->vmode & | ||
1260 | FB_VMODE_INTERLACED) ? true : false); | ||
1261 | |||
1262 | for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++) | ||
477 | if (hdmi_confs[i].width == check_timing->xres && | 1263 | if (hdmi_confs[i].width == check_timing->xres && |
478 | hdmi_confs[i].height == check_timing->yres && | 1264 | hdmi_confs[i].height == check_timing->yres && |
479 | hdmi_confs[i].vrefresh == check_timing->refresh && | 1265 | hdmi_confs[i].vrefresh == check_timing->refresh && |
480 | hdmi_confs[i].interlace == | 1266 | hdmi_confs[i].interlace == |
481 | ((check_timing->vmode & FB_VMODE_INTERLACED) ? | 1267 | ((check_timing->vmode & FB_VMODE_INTERLACED) ? |
482 | true : false)) | 1268 | true : false)) |
483 | return 0; | 1269 | return 0; |
1270 | |||
1271 | /* TODO */ | ||
484 | 1272 | ||
485 | return -EINVAL; | 1273 | return -EINVAL; |
486 | } | 1274 | } |
487 | 1275 | ||
1276 | static int hdmi_check_timing(void *ctx, void *timing) | ||
1277 | { | ||
1278 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | ||
1279 | struct fb_videomode *check_timing = timing; | ||
1280 | |||
1281 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | ||
1282 | |||
1283 | DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, | ||
1284 | check_timing->yres, check_timing->refresh, | ||
1285 | check_timing->vmode); | ||
1286 | |||
1287 | if (hdata->is_v13) | ||
1288 | return hdmi_v13_check_timing(check_timing); | ||
1289 | else | ||
1290 | return hdmi_v14_check_timing(check_timing); | ||
1291 | } | ||
1292 | |||
488 | static int hdmi_display_power_on(void *ctx, int mode) | 1293 | static int hdmi_display_power_on(void *ctx, int mode) |
489 | { | 1294 | { |
490 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1295 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
@@ -514,15 +1319,185 @@ static struct exynos_hdmi_display_ops display_ops = { | |||
514 | .power_on = hdmi_display_power_on, | 1319 | .power_on = hdmi_display_power_on, |
515 | }; | 1320 | }; |
516 | 1321 | ||
1322 | static void hdmi_set_acr(u32 freq, u8 *acr) | ||
1323 | { | ||
1324 | u32 n, cts; | ||
1325 | |||
1326 | switch (freq) { | ||
1327 | case 32000: | ||
1328 | n = 4096; | ||
1329 | cts = 27000; | ||
1330 | break; | ||
1331 | case 44100: | ||
1332 | n = 6272; | ||
1333 | cts = 30000; | ||
1334 | break; | ||
1335 | case 88200: | ||
1336 | n = 12544; | ||
1337 | cts = 30000; | ||
1338 | break; | ||
1339 | case 176400: | ||
1340 | n = 25088; | ||
1341 | cts = 30000; | ||
1342 | break; | ||
1343 | case 48000: | ||
1344 | n = 6144; | ||
1345 | cts = 27000; | ||
1346 | break; | ||
1347 | case 96000: | ||
1348 | n = 12288; | ||
1349 | cts = 27000; | ||
1350 | break; | ||
1351 | case 192000: | ||
1352 | n = 24576; | ||
1353 | cts = 27000; | ||
1354 | break; | ||
1355 | default: | ||
1356 | n = 0; | ||
1357 | cts = 0; | ||
1358 | break; | ||
1359 | } | ||
1360 | |||
1361 | acr[1] = cts >> 16; | ||
1362 | acr[2] = cts >> 8 & 0xff; | ||
1363 | acr[3] = cts & 0xff; | ||
1364 | |||
1365 | acr[4] = n >> 16; | ||
1366 | acr[5] = n >> 8 & 0xff; | ||
1367 | acr[6] = n & 0xff; | ||
1368 | } | ||
1369 | |||
1370 | static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr) | ||
1371 | { | ||
1372 | hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]); | ||
1373 | hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]); | ||
1374 | hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]); | ||
1375 | hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]); | ||
1376 | hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]); | ||
1377 | hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]); | ||
1378 | hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]); | ||
1379 | hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]); | ||
1380 | hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]); | ||
1381 | |||
1382 | if (hdata->is_v13) | ||
1383 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4); | ||
1384 | else | ||
1385 | hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); | ||
1386 | } | ||
1387 | |||
1388 | static void hdmi_audio_init(struct hdmi_context *hdata) | ||
1389 | { | ||
1390 | u32 sample_rate, bits_per_sample, frame_size_code; | ||
1391 | u32 data_num, bit_ch, sample_frq; | ||
1392 | u32 val; | ||
1393 | u8 acr[7]; | ||
1394 | |||
1395 | sample_rate = 44100; | ||
1396 | bits_per_sample = 16; | ||
1397 | frame_size_code = 0; | ||
1398 | |||
1399 | switch (bits_per_sample) { | ||
1400 | case 20: | ||
1401 | data_num = 2; | ||
1402 | bit_ch = 1; | ||
1403 | break; | ||
1404 | case 24: | ||
1405 | data_num = 3; | ||
1406 | bit_ch = 1; | ||
1407 | break; | ||
1408 | default: | ||
1409 | data_num = 1; | ||
1410 | bit_ch = 0; | ||
1411 | break; | ||
1412 | } | ||
1413 | |||
1414 | hdmi_set_acr(sample_rate, acr); | ||
1415 | hdmi_reg_acr(hdata, acr); | ||
1416 | |||
1417 | hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE | ||
1418 | | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE | ||
1419 | | HDMI_I2S_MUX_ENABLE); | ||
1420 | |||
1421 | hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN | ||
1422 | | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); | ||
1423 | |||
1424 | hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); | ||
1425 | |||
1426 | sample_frq = (sample_rate == 44100) ? 0 : | ||
1427 | (sample_rate == 48000) ? 2 : | ||
1428 | (sample_rate == 32000) ? 3 : | ||
1429 | (sample_rate == 96000) ? 0xa : 0x0; | ||
1430 | |||
1431 | hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); | ||
1432 | hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); | ||
1433 | |||
1434 | val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01; | ||
1435 | hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val); | ||
1436 | |||
1437 | /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */ | ||
1438 | hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5) | ||
1439 | | HDMI_I2S_SEL_LRCK(6)); | ||
1440 | hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1) | ||
1441 | | HDMI_I2S_SEL_SDATA2(4)); | ||
1442 | hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1) | ||
1443 | | HDMI_I2S_SEL_SDATA2(2)); | ||
1444 | hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0)); | ||
1445 | |||
1446 | /* I2S_CON_1 & 2 */ | ||
1447 | hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE | ||
1448 | | HDMI_I2S_L_CH_LOW_POL); | ||
1449 | hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE | ||
1450 | | HDMI_I2S_SET_BIT_CH(bit_ch) | ||
1451 | | HDMI_I2S_SET_SDATA_BIT(data_num) | ||
1452 | | HDMI_I2S_BASIC_FORMAT); | ||
1453 | |||
1454 | /* Configure register related to CUV information */ | ||
1455 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 | ||
1456 | | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH | ||
1457 | | HDMI_I2S_COPYRIGHT | ||
1458 | | HDMI_I2S_LINEAR_PCM | ||
1459 | | HDMI_I2S_CONSUMER_FORMAT); | ||
1460 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER); | ||
1461 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0)); | ||
1462 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2 | ||
1463 | | HDMI_I2S_SET_SMP_FREQ(sample_frq)); | ||
1464 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4, | ||
1465 | HDMI_I2S_ORG_SMP_FREQ_44_1 | ||
1466 | | HDMI_I2S_WORD_LEN_MAX24_24BITS | ||
1467 | | HDMI_I2S_WORD_LEN_MAX_24BITS); | ||
1468 | |||
1469 | hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); | ||
1470 | } | ||
1471 | |||
1472 | static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) | ||
1473 | { | ||
1474 | u32 mod; | ||
1475 | |||
1476 | mod = hdmi_reg_read(hdata, HDMI_MODE_SEL); | ||
1477 | if (mod & HDMI_DVI_MODE_EN) | ||
1478 | return; | ||
1479 | |||
1480 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); | ||
1481 | hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? | ||
1482 | HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); | ||
1483 | } | ||
1484 | |||
517 | static void hdmi_conf_reset(struct hdmi_context *hdata) | 1485 | static void hdmi_conf_reset(struct hdmi_context *hdata) |
518 | { | 1486 | { |
1487 | u32 reg; | ||
1488 | |||
519 | /* disable hpd handle for drm */ | 1489 | /* disable hpd handle for drm */ |
520 | hdata->hpd_handle = false; | 1490 | hdata->hpd_handle = false; |
521 | 1491 | ||
1492 | if (hdata->is_v13) | ||
1493 | reg = HDMI_V13_CORE_RSTOUT; | ||
1494 | else | ||
1495 | reg = HDMI_CORE_RSTOUT; | ||
1496 | |||
522 | /* resetting HDMI core */ | 1497 | /* resetting HDMI core */ |
523 | hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, HDMI_CORE_SW_RSTOUT); | 1498 | hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); |
524 | mdelay(10); | 1499 | mdelay(10); |
525 | hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, HDMI_CORE_SW_RSTOUT); | 1500 | hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); |
526 | mdelay(10); | 1501 | mdelay(10); |
527 | 1502 | ||
528 | /* enable hpd handle for drm */ | 1503 | /* enable hpd handle for drm */ |
@@ -546,27 +1521,126 @@ static void hdmi_conf_init(struct hdmi_context *hdata) | |||
546 | HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); | 1521 | HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); |
547 | /* disable bluescreen */ | 1522 | /* disable bluescreen */ |
548 | hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); | 1523 | hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); |
549 | /* choose bluescreen (fecal) color */ | 1524 | |
550 | hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_0, 0x12); | 1525 | if (hdata->is_v13) { |
551 | hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_1, 0x34); | 1526 | /* choose bluescreen (fecal) color */ |
552 | hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_2, 0x56); | 1527 | hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12); |
553 | /* enable AVI packet every vsync, fixes purple line problem */ | 1528 | hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34); |
554 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02); | 1529 | hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56); |
555 | /* force RGB, look to CEA-861-D, table 7 for more detail */ | 1530 | |
556 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(0), 0 << 5); | 1531 | /* enable AVI packet every vsync, fixes purple line problem */ |
557 | hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); | 1532 | hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02); |
558 | 1533 | /* force RGB, look to CEA-861-D, table 7 for more detail */ | |
559 | hdmi_reg_writeb(hdata, HDMI_SPD_CON, 0x02); | 1534 | hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5); |
560 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); | 1535 | hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); |
561 | hdmi_reg_writeb(hdata, HDMI_ACR_CON, 0x04); | 1536 | |
1537 | hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02); | ||
1538 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); | ||
1539 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); | ||
1540 | } else { | ||
1541 | /* enable AVI packet every vsync, fixes purple line problem */ | ||
1542 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02); | ||
1543 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5); | ||
1544 | hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); | ||
1545 | } | ||
562 | 1546 | ||
563 | /* enable hpd handle for drm */ | 1547 | /* enable hpd handle for drm */ |
564 | hdata->hpd_handle = true; | 1548 | hdata->hpd_handle = true; |
565 | } | 1549 | } |
566 | 1550 | ||
567 | static void hdmi_timing_apply(struct hdmi_context *hdata, | 1551 | static void hdmi_v13_timing_apply(struct hdmi_context *hdata) |
568 | const struct hdmi_preset_conf *conf) | ||
569 | { | 1552 | { |
1553 | const struct hdmi_v13_preset_conf *conf = | ||
1554 | hdmi_v13_confs[hdata->cur_conf].conf; | ||
1555 | const struct hdmi_v13_core_regs *core = &conf->core; | ||
1556 | const struct hdmi_v13_tg_regs *tg = &conf->tg; | ||
1557 | int tries; | ||
1558 | |||
1559 | /* setting core registers */ | ||
1560 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); | ||
1561 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); | ||
1562 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]); | ||
1563 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]); | ||
1564 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]); | ||
1565 | hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]); | ||
1566 | hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]); | ||
1567 | hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]); | ||
1568 | hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); | ||
1569 | hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); | ||
1570 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]); | ||
1571 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]); | ||
1572 | hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]); | ||
1573 | hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]); | ||
1574 | hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]); | ||
1575 | hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]); | ||
1576 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); | ||
1577 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); | ||
1578 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); | ||
1579 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); | ||
1580 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); | ||
1581 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); | ||
1582 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); | ||
1583 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); | ||
1584 | hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); | ||
1585 | /* Timing generator registers */ | ||
1586 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); | ||
1587 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); | ||
1588 | hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); | ||
1589 | hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); | ||
1590 | hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); | ||
1591 | hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); | ||
1592 | hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); | ||
1593 | hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); | ||
1594 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); | ||
1595 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); | ||
1596 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); | ||
1597 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); | ||
1598 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); | ||
1599 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); | ||
1600 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); | ||
1601 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); | ||
1602 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); | ||
1603 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); | ||
1604 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); | ||
1605 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); | ||
1606 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); | ||
1607 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); | ||
1608 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); | ||
1609 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); | ||
1610 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); | ||
1611 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); | ||
1612 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); | ||
1613 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); | ||
1614 | |||
1615 | /* waiting for HDMIPHY's PLL to get to steady state */ | ||
1616 | for (tries = 100; tries; --tries) { | ||
1617 | u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS); | ||
1618 | if (val & HDMI_PHY_STATUS_READY) | ||
1619 | break; | ||
1620 | mdelay(1); | ||
1621 | } | ||
1622 | /* steady state not achieved */ | ||
1623 | if (tries == 0) { | ||
1624 | DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); | ||
1625 | hdmi_regs_dump(hdata, "timing apply"); | ||
1626 | } | ||
1627 | |||
1628 | clk_disable(hdata->res.sclk_hdmi); | ||
1629 | clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); | ||
1630 | clk_enable(hdata->res.sclk_hdmi); | ||
1631 | |||
1632 | /* enable HDMI and timing generator */ | ||
1633 | hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); | ||
1634 | if (core->int_pro_mode[0]) | ||
1635 | hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | | ||
1636 | HDMI_FIELD_EN); | ||
1637 | else | ||
1638 | hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); | ||
1639 | } | ||
1640 | |||
1641 | static void hdmi_v14_timing_apply(struct hdmi_context *hdata) | ||
1642 | { | ||
1643 | const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf; | ||
570 | const struct hdmi_core_regs *core = &conf->core; | 1644 | const struct hdmi_core_regs *core = &conf->core; |
571 | const struct hdmi_tg_regs *tg = &conf->tg; | 1645 | const struct hdmi_tg_regs *tg = &conf->tg; |
572 | int tries; | 1646 | int tries; |
@@ -574,29 +1648,102 @@ static void hdmi_timing_apply(struct hdmi_context *hdata, | |||
574 | /* setting core registers */ | 1648 | /* setting core registers */ |
575 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); | 1649 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); |
576 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); | 1650 | hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); |
577 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_0, core->v_blank[0]); | 1651 | hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]); |
578 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_1, core->v_blank[1]); | 1652 | hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]); |
579 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_2, core->v_blank[2]); | 1653 | hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]); |
580 | hdmi_reg_writeb(hdata, HDMI_H_V_LINE_0, core->h_v_line[0]); | 1654 | hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]); |
581 | hdmi_reg_writeb(hdata, HDMI_H_V_LINE_1, core->h_v_line[1]); | 1655 | hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]); |
582 | hdmi_reg_writeb(hdata, HDMI_H_V_LINE_2, core->h_v_line[2]); | 1656 | hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]); |
1657 | hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]); | ||
1658 | hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]); | ||
1659 | hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]); | ||
583 | hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); | 1660 | hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); |
584 | hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); | 1661 | hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); |
585 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_0, core->v_blank_f[0]); | 1662 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]); |
586 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_1, core->v_blank_f[1]); | 1663 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]); |
587 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_2, core->v_blank_f[2]); | 1664 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]); |
588 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_0, core->h_sync_gen[0]); | 1665 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]); |
589 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_1, core->h_sync_gen[1]); | 1666 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]); |
590 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_2, core->h_sync_gen[2]); | 1667 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]); |
591 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); | 1668 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]); |
592 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); | 1669 | hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]); |
593 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); | 1670 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0, |
594 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); | 1671 | core->v_sync_line_bef_2[0]); |
595 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); | 1672 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1, |
596 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); | 1673 | core->v_sync_line_bef_2[1]); |
597 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); | 1674 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0, |
598 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); | 1675 | core->v_sync_line_bef_1[0]); |
599 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); | 1676 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1, |
1677 | core->v_sync_line_bef_1[1]); | ||
1678 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0, | ||
1679 | core->v_sync_line_aft_2[0]); | ||
1680 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1, | ||
1681 | core->v_sync_line_aft_2[1]); | ||
1682 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0, | ||
1683 | core->v_sync_line_aft_1[0]); | ||
1684 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1, | ||
1685 | core->v_sync_line_aft_1[1]); | ||
1686 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, | ||
1687 | core->v_sync_line_aft_pxl_2[0]); | ||
1688 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1, | ||
1689 | core->v_sync_line_aft_pxl_2[1]); | ||
1690 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, | ||
1691 | core->v_sync_line_aft_pxl_1[0]); | ||
1692 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1, | ||
1693 | core->v_sync_line_aft_pxl_1[1]); | ||
1694 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]); | ||
1695 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]); | ||
1696 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]); | ||
1697 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]); | ||
1698 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]); | ||
1699 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]); | ||
1700 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]); | ||
1701 | hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]); | ||
1702 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0, | ||
1703 | core->v_sync_line_aft_3[0]); | ||
1704 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1, | ||
1705 | core->v_sync_line_aft_3[1]); | ||
1706 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0, | ||
1707 | core->v_sync_line_aft_4[0]); | ||
1708 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1, | ||
1709 | core->v_sync_line_aft_4[1]); | ||
1710 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0, | ||
1711 | core->v_sync_line_aft_5[0]); | ||
1712 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1, | ||
1713 | core->v_sync_line_aft_5[1]); | ||
1714 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0, | ||
1715 | core->v_sync_line_aft_6[0]); | ||
1716 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1, | ||
1717 | core->v_sync_line_aft_6[1]); | ||
1718 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, | ||
1719 | core->v_sync_line_aft_pxl_3[0]); | ||
1720 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1, | ||
1721 | core->v_sync_line_aft_pxl_3[1]); | ||
1722 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, | ||
1723 | core->v_sync_line_aft_pxl_4[0]); | ||
1724 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1, | ||
1725 | core->v_sync_line_aft_pxl_4[1]); | ||
1726 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, | ||
1727 | core->v_sync_line_aft_pxl_5[0]); | ||
1728 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1, | ||
1729 | core->v_sync_line_aft_pxl_5[1]); | ||
1730 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, | ||
1731 | core->v_sync_line_aft_pxl_6[0]); | ||
1732 | hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1, | ||
1733 | core->v_sync_line_aft_pxl_6[1]); | ||
1734 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]); | ||
1735 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]); | ||
1736 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]); | ||
1737 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]); | ||
1738 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]); | ||
1739 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]); | ||
1740 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]); | ||
1741 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]); | ||
1742 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]); | ||
1743 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]); | ||
1744 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]); | ||
1745 | hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]); | ||
1746 | |||
600 | /* Timing generator registers */ | 1747 | /* Timing generator registers */ |
601 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); | 1748 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); |
602 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); | 1749 | hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); |
@@ -618,6 +1765,10 @@ static void hdmi_timing_apply(struct hdmi_context *hdata, | |||
618 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); | 1765 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); |
619 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); | 1766 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); |
620 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); | 1767 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); |
1768 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l); | ||
1769 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h); | ||
1770 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l); | ||
1771 | hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h); | ||
621 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); | 1772 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); |
622 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); | 1773 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); |
623 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); | 1774 | hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); |
@@ -626,10 +1777,11 @@ static void hdmi_timing_apply(struct hdmi_context *hdata, | |||
626 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); | 1777 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); |
627 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); | 1778 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); |
628 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); | 1779 | hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); |
1780 | hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d); | ||
629 | 1781 | ||
630 | /* waiting for HDMIPHY's PLL to get to steady state */ | 1782 | /* waiting for HDMIPHY's PLL to get to steady state */ |
631 | for (tries = 100; tries; --tries) { | 1783 | for (tries = 100; tries; --tries) { |
632 | u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS); | 1784 | u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0); |
633 | if (val & HDMI_PHY_STATUS_READY) | 1785 | if (val & HDMI_PHY_STATUS_READY) |
634 | break; | 1786 | break; |
635 | mdelay(1); | 1787 | mdelay(1); |
@@ -653,9 +1805,18 @@ static void hdmi_timing_apply(struct hdmi_context *hdata, | |||
653 | hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); | 1805 | hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); |
654 | } | 1806 | } |
655 | 1807 | ||
1808 | static void hdmi_timing_apply(struct hdmi_context *hdata) | ||
1809 | { | ||
1810 | if (hdata->is_v13) | ||
1811 | hdmi_v13_timing_apply(hdata); | ||
1812 | else | ||
1813 | hdmi_v14_timing_apply(hdata); | ||
1814 | } | ||
1815 | |||
656 | static void hdmiphy_conf_reset(struct hdmi_context *hdata) | 1816 | static void hdmiphy_conf_reset(struct hdmi_context *hdata) |
657 | { | 1817 | { |
658 | u8 buffer[2]; | 1818 | u8 buffer[2]; |
1819 | u32 reg; | ||
659 | 1820 | ||
660 | clk_disable(hdata->res.sclk_hdmi); | 1821 | clk_disable(hdata->res.sclk_hdmi); |
661 | clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); | 1822 | clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); |
@@ -668,15 +1829,21 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) | |||
668 | if (hdata->hdmiphy_port) | 1829 | if (hdata->hdmiphy_port) |
669 | i2c_master_send(hdata->hdmiphy_port, buffer, 2); | 1830 | i2c_master_send(hdata->hdmiphy_port, buffer, 2); |
670 | 1831 | ||
1832 | if (hdata->is_v13) | ||
1833 | reg = HDMI_V13_PHY_RSTOUT; | ||
1834 | else | ||
1835 | reg = HDMI_PHY_RSTOUT; | ||
1836 | |||
671 | /* reset hdmiphy */ | 1837 | /* reset hdmiphy */ |
672 | hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); | 1838 | hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); |
673 | mdelay(10); | 1839 | mdelay(10); |
674 | hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); | 1840 | hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT); |
675 | mdelay(10); | 1841 | mdelay(10); |
676 | } | 1842 | } |
677 | 1843 | ||
678 | static void hdmiphy_conf_apply(struct hdmi_context *hdata) | 1844 | static void hdmiphy_conf_apply(struct hdmi_context *hdata) |
679 | { | 1845 | { |
1846 | const u8 *hdmiphy_data; | ||
680 | u8 buffer[32]; | 1847 | u8 buffer[32]; |
681 | u8 operation[2]; | 1848 | u8 operation[2]; |
682 | u8 read_buffer[32] = {0, }; | 1849 | u8 read_buffer[32] = {0, }; |
@@ -689,7 +1856,12 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) | |||
689 | } | 1856 | } |
690 | 1857 | ||
691 | /* pixel clock */ | 1858 | /* pixel clock */ |
692 | memcpy(buffer, hdmi_confs[hdata->cur_conf].hdmiphy_data, 32); | 1859 | if (hdata->is_v13) |
1860 | hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; | ||
1861 | else | ||
1862 | hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; | ||
1863 | |||
1864 | memcpy(buffer, hdmiphy_data, 32); | ||
693 | ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); | 1865 | ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); |
694 | if (ret != 32) { | 1866 | if (ret != 32) { |
695 | DRM_ERROR("failed to configure HDMIPHY via I2C\n"); | 1867 | DRM_ERROR("failed to configure HDMIPHY via I2C\n"); |
@@ -721,9 +1893,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) | |||
721 | 1893 | ||
722 | static void hdmi_conf_apply(struct hdmi_context *hdata) | 1894 | static void hdmi_conf_apply(struct hdmi_context *hdata) |
723 | { | 1895 | { |
724 | const struct hdmi_preset_conf *conf = | ||
725 | hdmi_confs[hdata->cur_conf].conf; | ||
726 | |||
727 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1896 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
728 | 1897 | ||
729 | hdmiphy_conf_reset(hdata); | 1898 | hdmiphy_conf_reset(hdata); |
@@ -731,13 +1900,55 @@ static void hdmi_conf_apply(struct hdmi_context *hdata) | |||
731 | 1900 | ||
732 | hdmi_conf_reset(hdata); | 1901 | hdmi_conf_reset(hdata); |
733 | hdmi_conf_init(hdata); | 1902 | hdmi_conf_init(hdata); |
1903 | hdmi_audio_init(hdata); | ||
734 | 1904 | ||
735 | /* setting core registers */ | 1905 | /* setting core registers */ |
736 | hdmi_timing_apply(hdata, conf); | 1906 | hdmi_timing_apply(hdata); |
1907 | hdmi_audio_control(hdata, true); | ||
737 | 1908 | ||
738 | hdmi_regs_dump(hdata, "start"); | 1909 | hdmi_regs_dump(hdata, "start"); |
739 | } | 1910 | } |
740 | 1911 | ||
1912 | static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | ||
1913 | struct drm_display_mode *mode, | ||
1914 | struct drm_display_mode *adjusted_mode) | ||
1915 | { | ||
1916 | struct drm_display_mode *m; | ||
1917 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | ||
1918 | int index; | ||
1919 | |||
1920 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | ||
1921 | |||
1922 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1923 | |||
1924 | if (hdata->is_v13) | ||
1925 | index = hdmi_v13_conf_index(adjusted_mode); | ||
1926 | else | ||
1927 | index = hdmi_v14_conf_index(adjusted_mode); | ||
1928 | |||
1929 | /* just return if user desired mode exists. */ | ||
1930 | if (index >= 0) | ||
1931 | return; | ||
1932 | |||
1933 | /* | ||
1934 | * otherwise, find the most suitable mode among modes and change it | ||
1935 | * to adjusted_mode. | ||
1936 | */ | ||
1937 | list_for_each_entry(m, &connector->modes, head) { | ||
1938 | if (hdata->is_v13) | ||
1939 | index = hdmi_v13_conf_index(m); | ||
1940 | else | ||
1941 | index = hdmi_v14_conf_index(m); | ||
1942 | |||
1943 | if (index >= 0) { | ||
1944 | DRM_INFO("desired mode doesn't exist so\n"); | ||
1945 | DRM_INFO("use the most suitable mode among modes.\n"); | ||
1946 | memcpy(adjusted_mode, m, sizeof(*m)); | ||
1947 | break; | ||
1948 | } | ||
1949 | } | ||
1950 | } | ||
1951 | |||
741 | static void hdmi_mode_set(void *ctx, void *mode) | 1952 | static void hdmi_mode_set(void *ctx, void *mode) |
742 | { | 1953 | { |
743 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1954 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; |
@@ -745,13 +1956,22 @@ static void hdmi_mode_set(void *ctx, void *mode) | |||
745 | 1956 | ||
746 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1957 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
747 | 1958 | ||
748 | conf_idx = hdmi_conf_index(mode); | 1959 | conf_idx = hdmi_conf_index(hdata, mode); |
749 | if (conf_idx >= 0 && conf_idx < ARRAY_SIZE(hdmi_confs)) | 1960 | if (conf_idx >= 0) |
750 | hdata->cur_conf = conf_idx; | 1961 | hdata->cur_conf = conf_idx; |
751 | else | 1962 | else |
752 | DRM_DEBUG_KMS("not supported mode\n"); | 1963 | DRM_DEBUG_KMS("not supported mode\n"); |
753 | } | 1964 | } |
754 | 1965 | ||
1966 | static void hdmi_get_max_resol(void *ctx, unsigned int *width, | ||
1967 | unsigned int *height) | ||
1968 | { | ||
1969 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | ||
1970 | |||
1971 | *width = MAX_WIDTH; | ||
1972 | *height = MAX_HEIGHT; | ||
1973 | } | ||
1974 | |||
755 | static void hdmi_commit(void *ctx) | 1975 | static void hdmi_commit(void *ctx) |
756 | { | 1976 | { |
757 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1977 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; |
@@ -770,13 +1990,16 @@ static void hdmi_disable(void *ctx) | |||
770 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1990 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
771 | 1991 | ||
772 | if (hdata->enabled) { | 1992 | if (hdata->enabled) { |
1993 | hdmi_audio_control(hdata, false); | ||
773 | hdmiphy_conf_reset(hdata); | 1994 | hdmiphy_conf_reset(hdata); |
774 | hdmi_conf_reset(hdata); | 1995 | hdmi_conf_reset(hdata); |
775 | } | 1996 | } |
776 | } | 1997 | } |
777 | 1998 | ||
778 | static struct exynos_hdmi_manager_ops manager_ops = { | 1999 | static struct exynos_hdmi_manager_ops manager_ops = { |
2000 | .mode_fixup = hdmi_mode_fixup, | ||
779 | .mode_set = hdmi_mode_set, | 2001 | .mode_set = hdmi_mode_set, |
2002 | .get_max_resol = hdmi_get_max_resol, | ||
780 | .commit = hdmi_commit, | 2003 | .commit = hdmi_commit, |
781 | .disable = hdmi_disable, | 2004 | .disable = hdmi_disable, |
782 | }; | 2005 | }; |
@@ -926,7 +2149,7 @@ static void hdmi_resource_poweron(struct hdmi_context *hdata) | |||
926 | hdmiphy_conf_reset(hdata); | 2149 | hdmiphy_conf_reset(hdata); |
927 | hdmi_conf_reset(hdata); | 2150 | hdmi_conf_reset(hdata); |
928 | hdmi_conf_init(hdata); | 2151 | hdmi_conf_init(hdata); |
929 | 2152 | hdmi_audio_init(hdata); | |
930 | } | 2153 | } |
931 | 2154 | ||
932 | static void hdmi_resource_poweroff(struct hdmi_context *hdata) | 2155 | static void hdmi_resource_poweroff(struct hdmi_context *hdata) |
@@ -978,14 +2201,12 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc) | |||
978 | if (ddc) | 2201 | if (ddc) |
979 | hdmi_ddc = ddc; | 2202 | hdmi_ddc = ddc; |
980 | } | 2203 | } |
981 | EXPORT_SYMBOL(hdmi_attach_ddc_client); | ||
982 | 2204 | ||
983 | void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) | 2205 | void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) |
984 | { | 2206 | { |
985 | if (hdmiphy) | 2207 | if (hdmiphy) |
986 | hdmi_hdmiphy = hdmiphy; | 2208 | hdmi_hdmiphy = hdmiphy; |
987 | } | 2209 | } |
988 | EXPORT_SYMBOL(hdmi_attach_hdmiphy_client); | ||
989 | 2210 | ||
990 | static int __devinit hdmi_probe(struct platform_device *pdev) | 2211 | static int __devinit hdmi_probe(struct platform_device *pdev) |
991 | { | 2212 | { |
@@ -1022,6 +2243,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
1022 | 2243 | ||
1023 | platform_set_drvdata(pdev, drm_hdmi_ctx); | 2244 | platform_set_drvdata(pdev, drm_hdmi_ctx); |
1024 | 2245 | ||
2246 | hdata->is_v13 = pdata->is_v13; | ||
1025 | hdata->default_win = pdata->default_win; | 2247 | hdata->default_win = pdata->default_win; |
1026 | hdata->default_timing = &pdata->timing; | 2248 | hdata->default_timing = &pdata->timing; |
1027 | hdata->default_bpp = pdata->bpp; | 2249 | hdata->default_bpp = pdata->bpp; |
@@ -1167,10 +2389,3 @@ struct platform_driver hdmi_driver = { | |||
1167 | .pm = &hdmi_pm_ops, | 2389 | .pm = &hdmi_pm_ops, |
1168 | }, | 2390 | }, |
1169 | }; | 2391 | }; |
1170 | EXPORT_SYMBOL(hdmi_driver); | ||
1171 | |||
1172 | MODULE_AUTHOR("Seung-Woo Kim, <sw0312.kim@samsung.com>"); | ||
1173 | MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); | ||
1174 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1175 | MODULE_DESCRIPTION("Samsung DRM HDMI core Driver"); | ||
1176 | MODULE_LICENSE("GPL"); | ||