From 6d6f0874490f7e7ed16408e5396f655d386edf29 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 27 Aug 2010 10:15:44 +0000 Subject: fbdev: sh-mobile_hdmi: remove un-necessity settings Current gamut, acp, isrc1, isrc2 settings are wrong, and not necessary for now. Tested-by: Takanari Hayama Signed-off-by: Kuninori Morimoto Tested-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 106 ----------------------------------------- 1 file changed, 106 deletions(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index 2fde08cc66bf..afebe809975e 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -518,100 +518,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi) hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10); } -/** - * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET - */ -static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi) -{ - int i; - - /* Gamut Metadata Packet */ - hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX); - - /* Packet Type = 0x0A */ - hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0); - /* Gamut Packet is not used, so default value */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); - /* Gamut Packet is not used, so default value */ - hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2); - - /* GBD bytes 0 through 27 */ - for (i = 0; i <= 27; i++) - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); -} - -/** - * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP) - */ -static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi) -{ - int i; - - /* Audio Content Protection Packet (ACP) */ - hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX); - - /* Packet Type = 0x04 */ - hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0); - /* ACP_Type */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); - /* Reserved (0) */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); - - /* GBD bytes 0 through 27 */ - for (i = 0; i <= 27; i++) - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); -} - -/** - * sh_hdmi_isrc1_setup() - ISRC1 Packet - */ -static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi) -{ - int i; - - /* ISRC1 Packet */ - hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX); - - /* Packet Type = 0x05 */ - hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0); - /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); - /* Reserved (0) */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); - - /* PB0 UPC_EAN_ISRC_0-15 */ - /* Bytes PB16-PB27 shall be set to a value of 0. */ - for (i = 0; i <= 27; i++) - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); -} - -/** - * sh_hdmi_isrc2_setup() - ISRC2 Packet - */ -static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi) -{ - int i; - - /* ISRC2 Packet */ - hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX); - - /* HB0 Packet Type = 0x06 */ - hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0); - /* Reserved (0) */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); - /* Reserved (0) */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); - - /* PB0 UPC_EAN_ISRC_16-31 */ - /* Bytes PB16-PB27 shall be set to a value of 0. */ - for (i = 0; i <= 27; i++) - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); -} - /** * sh_hdmi_configure() - Initialise HDMI for output */ @@ -632,18 +538,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi) /* Audio InfoFrame */ sh_hdmi_audio_infoframe_setup(hdmi); - /* Gamut Metadata packet */ - sh_hdmi_gamut_metadata_setup(hdmi); - - /* Audio Content Protection (ACP) Packet */ - sh_hdmi_acp_setup(hdmi); - - /* ISRC1 Packet */ - sh_hdmi_isrc1_setup(hdmi); - - /* ISRC2 Packet */ - sh_hdmi_isrc2_setup(hdmi); - /* * Control packet auto send with VSYNC control: auto send * General control, Gamut metadata, ISRC, and ACP packets -- cgit v1.2.2 From 6ee4845270d9b1e7ea348f9e3b6347f54f986abb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Sep 2010 07:19:53 +0000 Subject: fbdev: sh_mobile_hdmi: simplify the EDID reading procedure The present SH-Mobile HDMI driver reads and parses the EDID block into a variable screeninfo object, but since it is still unable to dynamically reconfigure the framebuffer, it overwrites the EDID information with preset values again. This patch just uses a temporary variable to store the EDID timing information instead. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index afebe809975e..a8117c33e75f 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -557,10 +557,9 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi) static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) { - struct fb_var_screeninfo *var = &hdmi->var; - struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; - struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg; - unsigned long height = var->height, width = var->width; + struct fb_var_screeninfo tmpvar; + /* TODO: When we are ready to use EDID, use this to fill &hdmi->var */ + struct fb_var_screeninfo *var = &tmpvar; int i; u8 edid[128]; @@ -586,22 +585,6 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) var->upper_margin, var->yres, var->lower_margin, var->vsync_len, PICOS2KHZ(var->pixclock)); - /* FIXME: Use user-provided configuration instead of EDID */ - var->width = width; - var->xres = lcd_cfg->xres; - var->xres_virtual = lcd_cfg->xres; - var->left_margin = lcd_cfg->left_margin; - var->right_margin = lcd_cfg->right_margin; - var->hsync_len = lcd_cfg->hsync_len; - var->height = height; - var->yres = lcd_cfg->yres; - var->yres_virtual = lcd_cfg->yres * 2; - var->upper_margin = lcd_cfg->upper_margin; - var->lower_margin = lcd_cfg->lower_margin; - var->vsync_len = lcd_cfg->vsync_len; - var->sync = lcd_cfg->sync; - var->pixclock = lcd_cfg->pixclock; - hdmi_external_video_param(hdmi); } -- cgit v1.2.2 From 44432407d9f5e4b2e56c7eccb65d98cad4bba191 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Sep 2010 07:20:04 +0000 Subject: fbdev: sh_mobile_lcdcfb: Support multiple video modes in platform data This is a preparation for HDMI hotplug support. This patch just moves all platform defined video modes for the sh_mobile_lcdcfb driver to separate arrays and switches all users to use element 0 of that array, so, this patch doesn't introduce any functional changes and as such should not cause any regressions. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index a8117c33e75f..6608429c0fbb 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -777,7 +777,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) goto egetclk; } - rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000; + /* TODO: reconfigure the clock on monitor plug in */ + rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg[0].pixclock) * 1000; rate = clk_round_rate(hdmi->hdmi_clk, rate); if (rate < 0) { -- cgit v1.2.2 From 6e45746c36d5ab4c3486760e45a555263a0b9fac Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Sep 2010 07:20:16 +0000 Subject: fbdev: sh_mobile_hdmi: add initial support for modes, other than 720p To support standard video modes, other than 720p, the HDMI PHY configuration has to be adjusted and the VIC has to be sent to the display. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 82 +++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 20 deletions(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index 6608429c0fbb..27d76bcf8e07 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -381,21 +381,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) } /** - * sh_hdmi_phy_config() + * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode */ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) { - /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ - hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); - hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); - hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); - /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ - hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); - hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); - hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); - hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); - hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); - hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); + if (hdmi->var.yres > 480) { + /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ + /* + * [1:0] Speed_A + * [3:2] Speed_B + * [4] PLLA_Bypass + * [6] DRV_TEST_EN + * [7] DRV_TEST_IN + */ + hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); + /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */ + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); + /* + * [2:0] BGR_I_OFFSET + * [6:4] BGR_V_OFFSET + */ + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); + /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ + hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); + /* + * PLLA_CONFIG[15:8]: regulator voltage[0], CP current, + * LPF capacitance, LPF resistance[1] + */ + hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); + /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */ + hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); + /* + * PLLB_CONFIG[15:8]: regulator voltage[0], CP current, + * LPF capacitance, LPF resistance[1] + */ + hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); + /* DRV_CONFIG, PE_CONFIG */ + hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); + /* + * [2:0] AMON_SEL (4 == LPF voltage) + * [4] PLLA_CONFIG[16] + * [5] PLLB_CONFIG[16] + */ + hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); + } else { + /* for 480p8bit 27MHz */ + hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); + hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); + hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); + hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); + hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); + hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); + hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); + } } /** @@ -403,6 +443,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) */ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) { + u8 vic; + /* AVI InfoFrame */ hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX); @@ -443,9 +485,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) /* * VIC = 1280 x 720p: ignored if external config is used - * Send 2 for 720 x 480p, 16 for 1080p + * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode */ - hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4); + if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920) + vic = 16; + else if (hdmi->var.yres == 480 && hdmi->var.xres == 720) + vic = 2; + else + vic = 4; + hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4); /* PR = No Repetition */ hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); @@ -666,12 +714,6 @@ static void hdmi_display_on(void *arg, struct fb_info *info) struct sh_hdmi *hdmi = arg; struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; - if (info->var.xres != 1280 || info->var.yres != 720) { - dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n", - info->var.xres, info->var.yres); - return; - } - pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state); /* * FIXME: not a good place to store fb_info. And we cannot nullify it -- cgit v1.2.2 From 89712699d7bc9cc93602407e0e9bc2490b771400 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Sep 2010 07:20:20 +0000 Subject: fbdev: sh_mobile_hdmi: enable "external" mode The SH-Mobile HDMI controller supports two configuration modes: using pre-programmed VICs and the "external" mode - specifying video parameters explicitly. The driver already contains code, necessary to configure HDMI manually, this patch actually enables it. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index 27d76bcf8e07..a8cf9a510f30 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -205,6 +205,7 @@ enum hotplug_state { struct sh_hdmi { void __iomem *base; enum hotplug_state hp_state; + bool preprogrammed_mode; /* use a pre-programmed VIC or the external mode */ struct clk *hdmi_clk; struct device *dev; struct fb_info *info; @@ -282,7 +283,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi) hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); - /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */ + /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ + if (!hdmi->preprogrammed_mode) + hdmi_write(hdmi, sync | 1 | (voffset << 4), + HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); } /** @@ -633,6 +637,13 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) var->upper_margin, var->yres, var->lower_margin, var->vsync_len, PICOS2KHZ(var->pixclock)); + if ((hdmi->var.xres == 720 && hdmi->var.yres == 480) || + (hdmi->var.xres == 1280 && hdmi->var.yres == 720) || + (hdmi->var.xres == 1920 && hdmi->var.yres == 1080)) + hdmi->preprogrammed_mode = true; + else + hdmi->preprogrammed_mode = false; + hdmi_external_video_param(hdmi); } -- cgit v1.2.2 From 6de9edd5bde0cdfea12e9948690e53ec669c3018 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 3 Sep 2010 07:20:23 +0000 Subject: fbdev: sh_mobile_hdmi: implement locking The SH-Mobile HDMI driver runs in several contexts: ISR, delayed work-queue, task context, when called from the sh_mobile_lcdc framebuffer driver. This creates ample race possibilities. Even though most these races are purely theoretical, it is better to close them. To trace fb_info validity we install a notification callback in the HDMI driver, and the only way for it to get to driver internal data is by using struct sh_mobile_lcdc_chan, therefore it had to be extracted into a separate common header. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_hdmi.c | 103 ++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 16 deletions(-) (limited to 'drivers/video/sh_mobile_hdmi.c') diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index a8cf9a510f30..56e44fd0a3af 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -26,6 +26,8 @@ #include