diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-11-28 19:05:47 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-03-12 17:40:53 -0400 |
commit | e0c8601a18969229eb63065e5c3176319c785288 (patch) | |
tree | 7481ec5e0b4b2b8ca2454af71093682f4d8c48db /drivers/video/sh_mobile_hdmi.c | |
parent | 7295752fd7ec86feca6e3ccb407c1cbabf59e1d3 (diff) |
fbdev: sh_mobile_lcdc: Pass a video mode to the notify callback
Pass pointers to struct fb_videomode and struct fb_monspecs instead of
struct fb_var_screeninfo to the notify callback.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/video/sh_mobile_hdmi.c')
-rw-r--r-- | drivers/video/sh_mobile_hdmi.c | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index 055cd92b85cf..261760949718 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c | |||
@@ -220,7 +220,7 @@ struct sh_hdmi { | |||
220 | struct clk *hdmi_clk; | 220 | struct clk *hdmi_clk; |
221 | struct device *dev; | 221 | struct device *dev; |
222 | struct delayed_work edid_work; | 222 | struct delayed_work edid_work; |
223 | struct fb_var_screeninfo var; | 223 | struct fb_videomode mode; |
224 | struct fb_monspecs monspec; | 224 | struct fb_monspecs monspec; |
225 | }; | 225 | }; |
226 | 226 | ||
@@ -291,24 +291,24 @@ static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = { | |||
291 | /* External video parameter settings */ | 291 | /* External video parameter settings */ |
292 | static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) | 292 | static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) |
293 | { | 293 | { |
294 | struct fb_var_screeninfo *var = &hdmi->var; | 294 | struct fb_videomode *mode = &hdmi->mode; |
295 | u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; | 295 | u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; |
296 | u8 sync = 0; | 296 | u8 sync = 0; |
297 | 297 | ||
298 | htotal = var->xres + var->right_margin + var->left_margin + var->hsync_len; | 298 | htotal = mode->xres + mode->right_margin + mode->left_margin |
299 | 299 | + mode->hsync_len; | |
300 | hdelay = var->hsync_len + var->left_margin; | 300 | hdelay = mode->hsync_len + mode->left_margin; |
301 | hblank = var->right_margin + hdelay; | 301 | hblank = mode->right_margin + hdelay; |
302 | 302 | ||
303 | /* | 303 | /* |
304 | * Vertical timing looks a bit different in Figure 18, | 304 | * Vertical timing looks a bit different in Figure 18, |
305 | * but let's try the same first by setting offset = 0 | 305 | * but let's try the same first by setting offset = 0 |
306 | */ | 306 | */ |
307 | vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; | 307 | vtotal = mode->yres + mode->upper_margin + mode->lower_margin |
308 | 308 | + mode->vsync_len; | |
309 | vdelay = var->vsync_len + var->upper_margin; | 309 | vdelay = mode->vsync_len + mode->upper_margin; |
310 | vblank = var->lower_margin + vdelay; | 310 | vblank = mode->lower_margin + vdelay; |
311 | voffset = min(var->upper_margin / 2, 6U); | 311 | voffset = min(mode->upper_margin / 2, 6U); |
312 | 312 | ||
313 | /* | 313 | /* |
314 | * [3]: VSYNC polarity: Positive | 314 | * [3]: VSYNC polarity: Positive |
@@ -316,14 +316,14 @@ static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) | |||
316 | * [1]: Interlace/Progressive: Progressive | 316 | * [1]: Interlace/Progressive: Progressive |
317 | * [0]: External video settings enable: used. | 317 | * [0]: External video settings enable: used. |
318 | */ | 318 | */ |
319 | if (var->sync & FB_SYNC_HOR_HIGH_ACT) | 319 | if (mode->sync & FB_SYNC_HOR_HIGH_ACT) |
320 | sync |= 4; | 320 | sync |= 4; |
321 | if (var->sync & FB_SYNC_VERT_HIGH_ACT) | 321 | if (mode->sync & FB_SYNC_VERT_HIGH_ACT) |
322 | sync |= 8; | 322 | sync |= 8; |
323 | 323 | ||
324 | dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", | 324 | dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", |
325 | htotal, hblank, hdelay, var->hsync_len, | 325 | htotal, hblank, hdelay, mode->hsync_len, |
326 | vtotal, vblank, vdelay, var->vsync_len, sync); | 326 | vtotal, vblank, vdelay, mode->vsync_len, sync); |
327 | 327 | ||
328 | hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); | 328 | hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); |
329 | 329 | ||
@@ -336,8 +336,8 @@ static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) | |||
336 | hdmi_write(hdmi, hdelay, HDMI_EXTERNAL_H_DELAY_7_0); | 336 | hdmi_write(hdmi, hdelay, HDMI_EXTERNAL_H_DELAY_7_0); |
337 | hdmi_write(hdmi, hdelay >> 8, HDMI_EXTERNAL_H_DELAY_9_8); | 337 | hdmi_write(hdmi, hdelay >> 8, HDMI_EXTERNAL_H_DELAY_9_8); |
338 | 338 | ||
339 | hdmi_write(hdmi, var->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0); | 339 | hdmi_write(hdmi, mode->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0); |
340 | hdmi_write(hdmi, var->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8); | 340 | hdmi_write(hdmi, mode->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8); |
341 | 341 | ||
342 | hdmi_write(hdmi, vtotal, HDMI_EXTERNAL_V_TOTAL_7_0); | 342 | hdmi_write(hdmi, vtotal, HDMI_EXTERNAL_V_TOTAL_7_0); |
343 | hdmi_write(hdmi, vtotal >> 8, HDMI_EXTERNAL_V_TOTAL_9_8); | 343 | hdmi_write(hdmi, vtotal >> 8, HDMI_EXTERNAL_V_TOTAL_9_8); |
@@ -346,7 +346,7 @@ static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) | |||
346 | 346 | ||
347 | hdmi_write(hdmi, vdelay, HDMI_EXTERNAL_V_DELAY); | 347 | hdmi_write(hdmi, vdelay, HDMI_EXTERNAL_V_DELAY); |
348 | 348 | ||
349 | hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); | 349 | hdmi_write(hdmi, mode->vsync_len, HDMI_EXTERNAL_V_DURATION); |
350 | 350 | ||
351 | /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ | 351 | /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ |
352 | if (!hdmi->preprogrammed_vic) | 352 | if (!hdmi->preprogrammed_vic) |
@@ -473,7 +473,7 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) | |||
473 | */ | 473 | */ |
474 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) | 474 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) |
475 | { | 475 | { |
476 | if (hdmi->var.pixclock < 10000) { | 476 | if (hdmi->mode.pixclock < 10000) { |
477 | /* for 1080p8bit 148MHz */ | 477 | /* for 1080p8bit 148MHz */ |
478 | hdmi_write(hdmi, 0x1d, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); | 478 | hdmi_write(hdmi, 0x1d, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); |
479 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); | 479 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); |
@@ -484,7 +484,7 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) | |||
484 | hdmi_write(hdmi, 0x0e, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); | 484 | hdmi_write(hdmi, 0x0e, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); |
485 | hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); | 485 | hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); |
486 | hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); | 486 | hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); |
487 | } else if (hdmi->var.pixclock < 30000) { | 487 | } else if (hdmi->mode.pixclock < 30000) { |
488 | /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ | 488 | /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ |
489 | /* | 489 | /* |
490 | * [1:0] Speed_A | 490 | * [1:0] Speed_A |
@@ -735,7 +735,6 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, | |||
735 | { | 735 | { |
736 | struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc; | 736 | struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc; |
737 | struct fb_info *info = ch ? ch->info : NULL; | 737 | struct fb_info *info = ch ? ch->info : NULL; |
738 | struct fb_var_screeninfo var; | ||
739 | const struct fb_videomode *mode, *found = NULL; | 738 | const struct fb_videomode *mode, *found = NULL; |
740 | const struct fb_modelist *modelist = NULL; | 739 | const struct fb_modelist *modelist = NULL; |
741 | unsigned int f_width = 0, f_height = 0, f_refresh = 0; | 740 | unsigned int f_width = 0, f_height = 0, f_refresh = 0; |
@@ -855,10 +854,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, | |||
855 | } | 854 | } |
856 | 855 | ||
857 | /* Check if supported: sufficient fb memory, supported clock-rate */ | 856 | /* Check if supported: sufficient fb memory, supported clock-rate */ |
858 | fb_videomode_to_var(&var, mode); | ||
859 | |||
860 | if (ch && ch->notify && | 857 | if (ch && ch->notify && |
861 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_MODE, &var)) { | 858 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_MODE, mode, |
859 | NULL)) { | ||
862 | scanning = true; | 860 | scanning = true; |
863 | preferred_bad = true; | 861 | preferred_bad = true; |
864 | continue; | 862 | continue; |
@@ -868,9 +866,6 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, | |||
868 | found_rate_error = rate_error; | 866 | found_rate_error = rate_error; |
869 | } | 867 | } |
870 | 868 | ||
871 | hdmi->var.width = hdmi->monspec.max_x * 10; | ||
872 | hdmi->var.height = hdmi->monspec.max_y * 10; | ||
873 | |||
874 | /* | 869 | /* |
875 | * TODO 1: if no ->info is present, postpone running the config until | 870 | * TODO 1: if no ->info is present, postpone running the config until |
876 | * after ->info first gets registered. | 871 | * after ->info first gets registered. |
@@ -916,7 +911,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, | |||
916 | found->xres, found->yres, found->refresh, | 911 | found->xres, found->yres, found->refresh, |
917 | PICOS2KHZ(found->pixclock) * 1000, found_rate_error); | 912 | PICOS2KHZ(found->pixclock) * 1000, found_rate_error); |
918 | 913 | ||
919 | fb_videomode_to_var(&hdmi->var, found); | 914 | hdmi->mode = *found; |
920 | sh_hdmi_external_video_param(hdmi); | 915 | sh_hdmi_external_video_param(hdmi); |
921 | 916 | ||
922 | return 0; | 917 | return 0; |
@@ -1017,9 +1012,9 @@ static int sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity) | |||
1017 | hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); | 1012 | hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); |
1018 | dev_dbg(hdmi->dev, "HDMI running\n"); | 1013 | dev_dbg(hdmi->dev, "HDMI running\n"); |
1019 | break; | 1014 | break; |
1020 | case HDMI_HOTPLUG_DISCONNECTED: | ||
1021 | default: | 1015 | default: |
1022 | hdmi->var = ch->display_var; | 1016 | fb_var_to_videomode(&hdmi->mode, &ch->display_var); |
1017 | break; | ||
1023 | } | 1018 | } |
1024 | 1019 | ||
1025 | return hdmi->hp_state == HDMI_HOTPLUG_DISCONNECTED | 1020 | return hdmi->hp_state == HDMI_HOTPLUG_DISCONNECTED |
@@ -1107,7 +1102,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
1107 | 1102 | ||
1108 | if (ch && ch->notify) | 1103 | if (ch && ch->notify) |
1109 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT, | 1104 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT, |
1110 | &hdmi->var); | 1105 | &hdmi->mode, &hdmi->monspec); |
1111 | } else { | 1106 | } else { |
1112 | hdmi->monspec.modedb_len = 0; | 1107 | hdmi->monspec.modedb_len = 0; |
1113 | fb_destroy_modedb(hdmi->monspec.modedb); | 1108 | fb_destroy_modedb(hdmi->monspec.modedb); |
@@ -1115,7 +1110,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
1115 | 1110 | ||
1116 | if (ch && ch->notify) | 1111 | if (ch && ch->notify) |
1117 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT, | 1112 | ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT, |
1118 | NULL); | 1113 | NULL, NULL); |
1119 | 1114 | ||
1120 | ret = 0; | 1115 | ret = 0; |
1121 | } | 1116 | } |