aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorTomasz Stanislawski <t.stanislaws@samsung.com>2012-02-03 12:02:17 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-20 08:01:56 -0400
commit3f468accf2ae2951dacebc04f186a08f495ce92a (patch)
treeb1fa7d5316949ff60c1252ec060e538cb8997581 /drivers/media
parent2470ea3f7f14283efa2f427884efc6634e39f243 (diff)
[media] v4l: s5p-tv: hdmi: parametrize DV timings
This patch fixes timings configuration in HDMI register. It adds support for numerous new presets including interlaced ones. Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c460
-rw-r--r--drivers/media/video/s5p-tv/regs-hdmi.h1
2 files changed, 207 insertions, 254 deletions
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
index 4865d25a0e57..eefb903313c3 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -42,7 +42,23 @@ MODULE_DESCRIPTION("Samsung HDMI");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43 43
44/* default preset configured on probe */ 44/* default preset configured on probe */
45#define HDMI_DEFAULT_PRESET V4L2_DV_1080P60 45#define HDMI_DEFAULT_PRESET V4L2_DV_480P59_94
46
47struct hdmi_pulse {
48 u32 beg;
49 u32 end;
50};
51
52struct hdmi_timings {
53 struct hdmi_pulse hact;
54 u32 hsyn_pol; /* 0 - high, 1 - low */
55 struct hdmi_pulse hsyn;
56 u32 interlaced;
57 struct hdmi_pulse vact[2];
58 u32 vsyn_pol; /* 0 - high, 1 - low */
59 u32 vsyn_off;
60 struct hdmi_pulse vsyn[2];
61};
46 62
47struct hdmi_resources { 63struct hdmi_resources {
48 struct clk *hdmi; 64 struct clk *hdmi;
@@ -70,64 +86,13 @@ struct hdmi_device {
70 /** subdev of MHL interface */ 86 /** subdev of MHL interface */
71 struct v4l2_subdev *mhl_sd; 87 struct v4l2_subdev *mhl_sd;
72 /** configuration of current graphic mode */ 88 /** configuration of current graphic mode */
73 const struct hdmi_preset_conf *cur_conf; 89 const struct hdmi_timings *cur_conf;
74 /** current preset */ 90 /** current preset */
75 u32 cur_preset; 91 u32 cur_preset;
76 /** other resources */ 92 /** other resources */
77 struct hdmi_resources res; 93 struct hdmi_resources res;
78}; 94};
79 95
80struct hdmi_tg_regs {
81 u8 cmd;
82 u8 h_fsz_l;
83 u8 h_fsz_h;
84 u8 hact_st_l;
85 u8 hact_st_h;
86 u8 hact_sz_l;
87 u8 hact_sz_h;
88 u8 v_fsz_l;
89 u8 v_fsz_h;
90 u8 vsync_l;
91 u8 vsync_h;
92 u8 vsync2_l;
93 u8 vsync2_h;
94 u8 vact_st_l;
95 u8 vact_st_h;
96 u8 vact_sz_l;
97 u8 vact_sz_h;
98 u8 field_chg_l;
99 u8 field_chg_h;
100 u8 vact_st2_l;
101 u8 vact_st2_h;
102 u8 vsync_top_hdmi_l;
103 u8 vsync_top_hdmi_h;
104 u8 vsync_bot_hdmi_l;
105 u8 vsync_bot_hdmi_h;
106 u8 field_top_hdmi_l;
107 u8 field_top_hdmi_h;
108 u8 field_bot_hdmi_l;
109 u8 field_bot_hdmi_h;
110};
111
112struct hdmi_core_regs {
113 u8 h_blank[2];
114 u8 v_blank[3];
115 u8 h_v_line[3];
116 u8 vsync_pol[1];
117 u8 int_pro_mode[1];
118 u8 v_blank_f[3];
119 u8 h_sync_gen[3];
120 u8 v_sync_gen1[3];
121 u8 v_sync_gen2[3];
122 u8 v_sync_gen3[3];
123};
124
125struct hdmi_preset_conf {
126 struct hdmi_core_regs core;
127 struct hdmi_tg_regs tg;
128 struct v4l2_mbus_framefmt mbus_fmt;
129};
130
131static struct platform_device_id hdmi_driver_types[] = { 96static struct platform_device_id hdmi_driver_types[] = {
132 { 97 {
133 .name = "s5pv210-hdmi", 98 .name = "s5pv210-hdmi",
@@ -165,6 +130,21 @@ void hdmi_writeb(struct hdmi_device *hdev, u32 reg_id, u8 value)
165 writeb(value, hdev->regs + reg_id); 130 writeb(value, hdev->regs + reg_id);
166} 131}
167 132
133static inline
134void hdmi_writebn(struct hdmi_device *hdev, u32 reg_id, int n, u32 value)
135{
136 switch (n) {
137 default:
138 writeb(value >> 24, hdev->regs + reg_id + 12);
139 case 3:
140 writeb(value >> 16, hdev->regs + reg_id + 8);
141 case 2:
142 writeb(value >> 8, hdev->regs + reg_id + 4);
143 case 1:
144 writeb(value >> 0, hdev->regs + reg_id + 0);
145 }
146}
147
168static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id) 148static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id)
169{ 149{
170 return readl(hdev->regs + reg_id); 150 return readl(hdev->regs + reg_id);
@@ -211,72 +191,63 @@ static void hdmi_reg_init(struct hdmi_device *hdev)
211} 191}
212 192
213static void hdmi_timing_apply(struct hdmi_device *hdev, 193static void hdmi_timing_apply(struct hdmi_device *hdev,
214 const struct hdmi_preset_conf *conf) 194 const struct hdmi_timings *t)
215{ 195{
216 const struct hdmi_core_regs *core = &conf->core;
217 const struct hdmi_tg_regs *tg = &conf->tg;
218
219 /* setting core registers */ 196 /* setting core registers */
220 hdmi_writeb(hdev, HDMI_H_BLANK_0, core->h_blank[0]); 197 hdmi_writebn(hdev, HDMI_H_BLANK_0, 2, t->hact.beg);
221 hdmi_writeb(hdev, HDMI_H_BLANK_1, core->h_blank[1]); 198 hdmi_writebn(hdev, HDMI_H_SYNC_GEN_0, 3,
222 hdmi_writeb(hdev, HDMI_V_BLANK_0, core->v_blank[0]); 199 (t->hsyn_pol << 20) | (t->hsyn.end << 10) | t->hsyn.beg);
223 hdmi_writeb(hdev, HDMI_V_BLANK_1, core->v_blank[1]); 200 hdmi_writeb(hdev, HDMI_VSYNC_POL, t->vsyn_pol);
224 hdmi_writeb(hdev, HDMI_V_BLANK_2, core->v_blank[2]); 201 hdmi_writebn(hdev, HDMI_V_BLANK_0, 3,
225 hdmi_writeb(hdev, HDMI_H_V_LINE_0, core->h_v_line[0]); 202 (t->vact[0].beg << 11) | t->vact[0].end);
226 hdmi_writeb(hdev, HDMI_H_V_LINE_1, core->h_v_line[1]); 203 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_1_0, 3,
227 hdmi_writeb(hdev, HDMI_H_V_LINE_2, core->h_v_line[2]); 204 (t->vsyn[0].beg << 12) | t->vsyn[0].end);
228 hdmi_writeb(hdev, HDMI_VSYNC_POL, core->vsync_pol[0]); 205 if (t->interlaced) {
229 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); 206 u32 vsyn_trans = t->hsyn.beg + t->vsyn_off;
230 hdmi_writeb(hdev, HDMI_V_BLANK_F_0, core->v_blank_f[0]); 207
231 hdmi_writeb(hdev, HDMI_V_BLANK_F_1, core->v_blank_f[1]); 208 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 1);
232 hdmi_writeb(hdev, HDMI_V_BLANK_F_2, core->v_blank_f[2]); 209 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
233 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_0, core->h_sync_gen[0]); 210 (t->hact.end << 12) | t->vact[1].end);
234 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_1, core->h_sync_gen[1]); 211 hdmi_writebn(hdev, HDMI_V_BLANK_F_0, 3,
235 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_2, core->h_sync_gen[2]); 212 (t->vact[1].end << 11) | t->vact[1].beg);
236 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); 213 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_2_0, 3,
237 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); 214 (t->vsyn[1].beg << 12) | t->vsyn[1].end);
238 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); 215 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_3_0, 3,
239 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); 216 (vsyn_trans << 12) | vsyn_trans);
240 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); 217 } else {
241 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); 218 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 0);
242 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); 219 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
243 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); 220 (t->hact.end << 12) | t->vact[0].end);
244 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); 221 }
222
245 /* Timing generator registers */ 223 /* Timing generator registers */
246 hdmi_writeb(hdev, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 224 hdmi_writebn(hdev, HDMI_TG_H_FSZ_L, 2, t->hact.end);
247 hdmi_writeb(hdev, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 225 hdmi_writebn(hdev, HDMI_TG_HACT_ST_L, 2, t->hact.beg);
248 hdmi_writeb(hdev, HDMI_TG_HACT_ST_L, tg->hact_st_l); 226 hdmi_writebn(hdev, HDMI_TG_HACT_SZ_L, 2, t->hact.end - t->hact.beg);
249 hdmi_writeb(hdev, HDMI_TG_HACT_ST_H, tg->hact_st_h); 227 hdmi_writebn(hdev, HDMI_TG_VSYNC_L, 2, t->vsyn[0].beg);
250 hdmi_writeb(hdev, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); 228 hdmi_writebn(hdev, HDMI_TG_VACT_ST_L, 2, t->vact[0].beg);
251 hdmi_writeb(hdev, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); 229 hdmi_writebn(hdev, HDMI_TG_VACT_SZ_L, 2,
252 hdmi_writeb(hdev, HDMI_TG_V_FSZ_L, tg->v_fsz_l); 230 t->vact[0].end - t->vact[0].beg);
253 hdmi_writeb(hdev, HDMI_TG_V_FSZ_H, tg->v_fsz_h); 231 hdmi_writebn(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, 2, t->vsyn[0].beg);
254 hdmi_writeb(hdev, HDMI_TG_VSYNC_L, tg->vsync_l); 232 hdmi_writebn(hdev, HDMI_TG_FIELD_TOP_HDMI_L, 2, t->vsyn[0].beg);
255 hdmi_writeb(hdev, HDMI_TG_VSYNC_H, tg->vsync_h); 233 if (t->interlaced) {
256 hdmi_writeb(hdev, HDMI_TG_VSYNC2_L, tg->vsync2_l); 234 hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_FIELD_EN);
257 hdmi_writeb(hdev, HDMI_TG_VSYNC2_H, tg->vsync2_h); 235 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[1].end);
258 hdmi_writeb(hdev, HDMI_TG_VACT_ST_L, tg->vact_st_l); 236 hdmi_writebn(hdev, HDMI_TG_VSYNC2_L, 2, t->vsyn[1].beg);
259 hdmi_writeb(hdev, HDMI_TG_VACT_ST_H, tg->vact_st_h); 237 hdmi_writebn(hdev, HDMI_TG_FIELD_CHG_L, 2, t->vact[0].end);
260 hdmi_writeb(hdev, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); 238 hdmi_writebn(hdev, HDMI_TG_VACT_ST2_L, 2, t->vact[1].beg);
261 hdmi_writeb(hdev, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); 239 hdmi_writebn(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, 2, t->vsyn[1].beg);
262 hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); 240 hdmi_writebn(hdev, HDMI_TG_FIELD_BOT_HDMI_L, 2, t->vsyn[1].beg);
263 hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 241 } else {
264 hdmi_writeb(hdev, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 242 hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_FIELD_EN);
265 hdmi_writeb(hdev, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 243 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[0].end);
266 hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 244 }
267 hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
268 hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
269 hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
270 hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
271 hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
272 hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
273 hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
274} 245}
275 246
276static int hdmi_conf_apply(struct hdmi_device *hdmi_dev) 247static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
277{ 248{
278 struct device *dev = hdmi_dev->dev; 249 struct device *dev = hdmi_dev->dev;
279 const struct hdmi_preset_conf *conf = hdmi_dev->cur_conf; 250 const struct hdmi_timings *conf = hdmi_dev->cur_conf;
280 struct v4l2_dv_preset preset; 251 struct v4l2_dv_preset preset;
281 int ret; 252 int ret;
282 253
@@ -398,156 +369,126 @@ static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix)
398#undef DUMPREG 369#undef DUMPREG
399} 370}
400 371
401static const struct hdmi_preset_conf hdmi_conf_480p = { 372static const struct hdmi_timings hdmi_timings_480p = {
402 .core = { 373 .hact = { .beg = 138, .end = 858 },
403 .h_blank = {0x8a, 0x00}, 374 .hsyn_pol = 1,
404 .v_blank = {0x0d, 0x6a, 0x01}, 375 .hsyn = { .beg = 16, .end = 16 + 62 },
405 .h_v_line = {0x0d, 0xa2, 0x35}, 376 .interlaced = 0,
406 .vsync_pol = {0x01}, 377 .vact[0] = { .beg = 42 + 3, .end = 522 + 3 },
407 .int_pro_mode = {0x00}, 378 .vsyn_pol = 1,
408 .v_blank_f = {0x00, 0x00, 0x00}, 379 .vsyn[0] = { .beg = 6 + 3, .end = 12 + 3},
409 .h_sync_gen = {0x0e, 0x30, 0x11}, 380};
410 .v_sync_gen1 = {0x0f, 0x90, 0x00}, 381
411 /* other don't care */ 382static const struct hdmi_timings hdmi_timings_576p50 = {
412 }, 383 .hact = { .beg = 144, .end = 864 },
413 .tg = { 384 .hsyn_pol = 1,
414 0x00, /* cmd */ 385 .hsyn = { .beg = 12, .end = 12 + 64 },
415 0x5a, 0x03, /* h_fsz */ 386 .interlaced = 0,
416 0x8a, 0x00, 0xd0, 0x02, /* hact */ 387 .vact[0] = { .beg = 44 + 5, .end = 620 + 5 },
417 0x0d, 0x02, /* v_fsz */ 388 .vsyn_pol = 1,
418 0x01, 0x00, 0x33, 0x02, /* vsync */ 389 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
419 0x2d, 0x00, 0xe0, 0x01, /* vact */ 390};
420 0x33, 0x02, /* field_chg */ 391
421 0x49, 0x02, /* vact_st2 */ 392static const struct hdmi_timings hdmi_timings_720p60 = {
422 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ 393 .hact = { .beg = 370, .end = 1650 },
423 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 394 .hsyn_pol = 0,
424 }, 395 .hsyn = { .beg = 110, .end = 110 + 40 },
425 .mbus_fmt = { 396 .interlaced = 0,
426 .width = 720, 397 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
427 .height = 480, 398 .vsyn_pol = 0,
428 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */ 399 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
429 .field = V4L2_FIELD_NONE, 400};
430 .colorspace = V4L2_COLORSPACE_SRGB, 401
431 }, 402static const struct hdmi_timings hdmi_timings_720p50 = {
403 .hact = { .beg = 700, .end = 1980 },
404 .hsyn_pol = 0,
405 .hsyn = { .beg = 440, .end = 440 + 40 },
406 .interlaced = 0,
407 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
408 .vsyn_pol = 0,
409 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
410};
411
412static const struct hdmi_timings hdmi_timings_1080p24 = {
413 .hact = { .beg = 830, .end = 2750 },
414 .hsyn_pol = 0,
415 .hsyn = { .beg = 638, .end = 638 + 44 },
416 .interlaced = 0,
417 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
418 .vsyn_pol = 0,
419 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
420};
421
422static const struct hdmi_timings hdmi_timings_1080p60 = {
423 .hact = { .beg = 280, .end = 2200 },
424 .hsyn_pol = 0,
425 .hsyn = { .beg = 88, .end = 88 + 44 },
426 .interlaced = 0,
427 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
428 .vsyn_pol = 0,
429 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
432}; 430};
433 431
434static const struct hdmi_preset_conf hdmi_conf_720p60 = { 432static const struct hdmi_timings hdmi_timings_1080i60 = {
435 .core = { 433 .hact = { .beg = 280, .end = 2200 },
436 .h_blank = {0x72, 0x01}, 434 .hsyn_pol = 0,
437 .v_blank = {0xee, 0xf2, 0x00}, 435 .hsyn = { .beg = 88, .end = 88 + 44 },
438 .h_v_line = {0xee, 0x22, 0x67}, 436 .interlaced = 1,
439 .vsync_pol = {0x00}, 437 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
440 .int_pro_mode = {0x00}, 438 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
441 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 439 .vsyn_pol = 0,
442 .h_sync_gen = {0x6c, 0x50, 0x02}, 440 .vsyn_off = 1100,
443 .v_sync_gen1 = {0x0a, 0x50, 0x00}, 441 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
444 /* other don't care */ 442 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
445 },
446 .tg = {
447 0x00, /* cmd */
448 0x72, 0x06, /* h_fsz */
449 0x72, 0x01, 0x00, 0x05, /* hact */
450 0xee, 0x02, /* v_fsz */
451 0x01, 0x00, 0x33, 0x02, /* vsync */
452 0x1e, 0x00, 0xd0, 0x02, /* vact */
453 0x33, 0x02, /* field_chg */
454 0x49, 0x02, /* vact_st2 */
455 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
456 0x01, 0x00, 0x33, 0x02, /* field top/bot */
457 },
458 .mbus_fmt = {
459 .width = 1280,
460 .height = 720,
461 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
462 .field = V4L2_FIELD_NONE,
463 .colorspace = V4L2_COLORSPACE_SRGB,
464 },
465}; 443};
466 444
467static const struct hdmi_preset_conf hdmi_conf_1080p50 = { 445static const struct hdmi_timings hdmi_timings_1080i50 = {
468 .core = { 446 .hact = { .beg = 720, .end = 2640 },
469 .h_blank = {0xd0, 0x02}, 447 .hsyn_pol = 0,
470 .v_blank = {0x65, 0x6c, 0x01}, 448 .hsyn = { .beg = 528, .end = 528 + 44 },
471 .h_v_line = {0x65, 0x04, 0xa5}, 449 .interlaced = 1,
472 .vsync_pol = {0x00}, 450 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
473 .int_pro_mode = {0x00}, 451 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
474 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 452 .vsyn_pol = 0,
475 .h_sync_gen = {0x0e, 0xea, 0x08}, 453 .vsyn_off = 1320,
476 .v_sync_gen1 = {0x09, 0x40, 0x00}, 454 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
477 /* other don't care */ 455 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
478 },
479 .tg = {
480 0x00, /* cmd */
481 0x98, 0x08, /* h_fsz */
482 0x18, 0x01, 0x80, 0x07, /* hact */
483 0x65, 0x04, /* v_fsz */
484 0x01, 0x00, 0x33, 0x02, /* vsync */
485 0x2d, 0x00, 0x38, 0x04, /* vact */
486 0x33, 0x02, /* field_chg */
487 0x49, 0x02, /* vact_st2 */
488 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
489 0x01, 0x00, 0x33, 0x02, /* field top/bot */
490 },
491 .mbus_fmt = {
492 .width = 1920,
493 .height = 1080,
494 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
495 .field = V4L2_FIELD_NONE,
496 .colorspace = V4L2_COLORSPACE_SRGB,
497 },
498}; 456};
499 457
500static const struct hdmi_preset_conf hdmi_conf_1080p60 = { 458static const struct hdmi_timings hdmi_timings_1080p50 = {
501 .core = { 459 .hact = { .beg = 720, .end = 2640 },
502 .h_blank = {0x18, 0x01}, 460 .hsyn_pol = 0,
503 .v_blank = {0x65, 0x6c, 0x01}, 461 .hsyn = { .beg = 528, .end = 528 + 44 },
504 .h_v_line = {0x65, 0x84, 0x89}, 462 .interlaced = 0,
505 .vsync_pol = {0x00}, 463 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
506 .int_pro_mode = {0x00}, 464 .vsyn_pol = 0,
507 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 465 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
508 .h_sync_gen = {0x56, 0x08, 0x02},
509 .v_sync_gen1 = {0x09, 0x40, 0x00},
510 /* other don't care */
511 },
512 .tg = {
513 0x00, /* cmd */
514 0x98, 0x08, /* h_fsz */
515 0x18, 0x01, 0x80, 0x07, /* hact */
516 0x65, 0x04, /* v_fsz */
517 0x01, 0x00, 0x33, 0x02, /* vsync */
518 0x2d, 0x00, 0x38, 0x04, /* vact */
519 0x33, 0x02, /* field_chg */
520 0x48, 0x02, /* vact_st2 */
521 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
522 0x01, 0x00, 0x33, 0x02, /* field top/bot */
523 },
524 .mbus_fmt = {
525 .width = 1920,
526 .height = 1080,
527 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
528 .field = V4L2_FIELD_NONE,
529 .colorspace = V4L2_COLORSPACE_SRGB,
530 },
531}; 466};
532 467
533static const struct { 468static const struct {
534 u32 preset; 469 u32 preset;
535 const struct hdmi_preset_conf *conf; 470 const struct hdmi_timings *timings;
536} hdmi_conf[] = { 471} hdmi_timings[] = {
537 { V4L2_DV_480P59_94, &hdmi_conf_480p }, 472 { V4L2_DV_480P59_94, &hdmi_timings_480p },
538 { V4L2_DV_720P59_94, &hdmi_conf_720p60 }, 473 { V4L2_DV_576P50, &hdmi_timings_576p50 },
539 { V4L2_DV_1080P50, &hdmi_conf_1080p50 }, 474 { V4L2_DV_720P50, &hdmi_timings_720p50 },
540 { V4L2_DV_1080P30, &hdmi_conf_1080p60 }, 475 { V4L2_DV_720P59_94, &hdmi_timings_720p60 },
541 { V4L2_DV_1080P60, &hdmi_conf_1080p60 }, 476 { V4L2_DV_720P60, &hdmi_timings_720p60 },
477 { V4L2_DV_1080P24, &hdmi_timings_1080p24 },
478 { V4L2_DV_1080P30, &hdmi_timings_1080p60 },
479 { V4L2_DV_1080P50, &hdmi_timings_1080p50 },
480 { V4L2_DV_1080I50, &hdmi_timings_1080i50 },
481 { V4L2_DV_1080I60, &hdmi_timings_1080i60 },
482 { V4L2_DV_1080P60, &hdmi_timings_1080p60 },
542}; 483};
543 484
544static const struct hdmi_preset_conf *hdmi_preset2conf(u32 preset) 485static const struct hdmi_timings *hdmi_preset2timings(u32 preset)
545{ 486{
546 int i; 487 int i;
547 488
548 for (i = 0; i < ARRAY_SIZE(hdmi_conf); ++i) 489 for (i = 0; i < ARRAY_SIZE(hdmi_timings); ++i)
549 if (hdmi_conf[i].preset == preset) 490 if (hdmi_timings[i].preset == preset)
550 return hdmi_conf[i].conf; 491 return hdmi_timings[i].timings;
551 return NULL; 492 return NULL;
552} 493}
553 494
@@ -671,9 +612,9 @@ static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
671{ 612{
672 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 613 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
673 struct device *dev = hdev->dev; 614 struct device *dev = hdev->dev;
674 const struct hdmi_preset_conf *conf; 615 const struct hdmi_timings *conf;
675 616
676 conf = hdmi_preset2conf(preset->preset); 617 conf = hdmi_preset2timings(preset->preset);
677 if (conf == NULL) { 618 if (conf == NULL) {
678 dev_err(dev, "preset (%u) not supported\n", preset->preset); 619 dev_err(dev, "preset (%u) not supported\n", preset->preset);
679 return -EINVAL; 620 return -EINVAL;
@@ -695,21 +636,32 @@ static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
695 struct v4l2_mbus_framefmt *fmt) 636 struct v4l2_mbus_framefmt *fmt)
696{ 637{
697 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 638 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
698 struct device *dev = hdev->dev; 639 const struct hdmi_timings *t = hdev->cur_conf;
699 640
700 dev_dbg(dev, "%s\n", __func__); 641 dev_dbg(hdev->dev, "%s\n", __func__);
701 if (!hdev->cur_conf) 642 if (!hdev->cur_conf)
702 return -EINVAL; 643 return -EINVAL;
703 *fmt = hdev->cur_conf->mbus_fmt; 644 memset(fmt, 0, sizeof *fmt);
645 fmt->width = t->hact.end - t->hact.beg;
646 fmt->height = t->vact[0].end - t->vact[0].beg;
647 fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */
648 fmt->colorspace = V4L2_COLORSPACE_SRGB;
649 if (t->interlaced) {
650 fmt->field = V4L2_FIELD_INTERLACED;
651 fmt->height *= 2;
652 } else {
653 fmt->field = V4L2_FIELD_NONE;
654 }
704 return 0; 655 return 0;
705} 656}
706 657
707static int hdmi_enum_dv_presets(struct v4l2_subdev *sd, 658static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
708 struct v4l2_dv_enum_preset *preset) 659 struct v4l2_dv_enum_preset *preset)
709{ 660{
710 if (preset->index >= ARRAY_SIZE(hdmi_conf)) 661 if (preset->index >= ARRAY_SIZE(hdmi_timings))
711 return -EINVAL; 662 return -EINVAL;
712 return v4l_fill_dv_preset_info(hdmi_conf[preset->index].preset, preset); 663 return v4l_fill_dv_preset_info(hdmi_timings[preset->index].preset,
664 preset);
713} 665}
714 666
715static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = { 667static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = {
@@ -993,7 +945,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
993 strlcpy(sd->name, "s5p-hdmi", sizeof sd->name); 945 strlcpy(sd->name, "s5p-hdmi", sizeof sd->name);
994 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; 946 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
995 /* FIXME: missing fail preset is not supported */ 947 /* FIXME: missing fail preset is not supported */
996 hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset); 948 hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
997 949
998 /* storing subdev for call that have only access to struct device */ 950 /* storing subdev for call that have only access to struct device */
999 dev_set_drvdata(dev, sd); 951 dev_set_drvdata(dev, sd);
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/video/s5p-tv/regs-hdmi.h
index 33247d13e4c0..a889d1f57f28 100644
--- a/drivers/media/video/s5p-tv/regs-hdmi.h
+++ b/drivers/media/video/s5p-tv/regs-hdmi.h
@@ -140,6 +140,7 @@
140#define HDMI_MODE_MASK (3 << 0) 140#define HDMI_MODE_MASK (3 << 0)
141 141
142/* HDMI_TG_CMD */ 142/* HDMI_TG_CMD */
143#define HDMI_TG_FIELD_EN (1 << 1)
143#define HDMI_TG_EN (1 << 0) 144#define HDMI_TG_EN (1 << 0)
144 145
145#endif /* SAMSUNG_REGS_HDMI_H */ 146#endif /* SAMSUNG_REGS_HDMI_H */