Commit 1c120deb authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Paul Mundt

fbdev: sh_mobile_lcdcfb: separate display variable data from framebuffer data

This is a preparation for a patch, that shall allow displaying of a smaller
framebuffer on a bigger display and of a part of a bigger framebuffer on a
smaller display.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 6de9edd5
...@@ -732,6 +732,7 @@ static void hdmi_display_on(void *arg, struct fb_info *info) ...@@ -732,6 +732,7 @@ static void hdmi_display_on(void *arg, struct fb_info *info)
*/ */
struct sh_hdmi *hdmi = arg; struct sh_hdmi *hdmi = arg;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
struct sh_mobile_lcdc_chan *ch = info->par;
pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state); pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
...@@ -747,7 +748,7 @@ static void hdmi_display_on(void *arg, struct fb_info *info) ...@@ -747,7 +748,7 @@ static void hdmi_display_on(void *arg, struct fb_info *info)
case HDMI_HOTPLUG_DISCONNECTED: case HDMI_HOTPLUG_DISCONNECTED:
info->state = FBINFO_STATE_SUSPENDED; info->state = FBINFO_STATE_SUSPENDED;
default: default:
hdmi->var = info->var; hdmi->var = ch->display_var;
} }
} }
...@@ -767,6 +768,7 @@ static void edid_work_fn(struct work_struct *work) ...@@ -767,6 +768,7 @@ static void edid_work_fn(struct work_struct *work)
{ {
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work); struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
struct sh_mobile_lcdc_chan *ch;
pr_debug("%s(%p): begin, hotplug status %d\n", __func__, pr_debug("%s(%p): begin, hotplug status %d\n", __func__,
pdata->lcd_dev, hdmi->hp_state); pdata->lcd_dev, hdmi->hp_state);
...@@ -788,10 +790,12 @@ static void edid_work_fn(struct work_struct *work) ...@@ -788,10 +790,12 @@ static void edid_work_fn(struct work_struct *work)
if (!hdmi->info) if (!hdmi->info)
goto out; goto out;
ch = hdmi->info->par;
acquire_console_sem(); acquire_console_sem();
/* HDMI plug in */ /* HDMI plug in */
hdmi->info->var = hdmi->var; ch->display_var = hdmi->var;
if (hdmi->info->state != FBINFO_STATE_RUNNING) { if (hdmi->info->state != FBINFO_STATE_RUNNING) {
fb_set_suspend(hdmi->info, 0); fb_set_suspend(hdmi->info, 0);
} else { } else {
......
...@@ -384,8 +384,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, ...@@ -384,8 +384,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
{ {
struct fb_var_screeninfo *var = &ch->info->var; struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
unsigned long h_total, hsync_pos; unsigned long h_total, hsync_pos, display_h_total;
u32 tmp; u32 tmp;
tmp = ch->ldmt1r_value; tmp = ch->ldmt1r_value;
...@@ -403,31 +403,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) ...@@ -403,31 +403,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
/* horizontal configuration */ /* horizontal configuration */
h_total = var->xres + var->hsync_len + h_total = display_var->xres + display_var->hsync_len +
var->left_margin + var->right_margin; display_var->left_margin + display_var->right_margin;
tmp = h_total / 8; /* HTCN */ tmp = h_total / 8; /* HTCN */
tmp |= (var->xres / 8) << 16; /* HDCN */ tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
lcdc_write_chan(ch, LDHCNR, tmp); lcdc_write_chan(ch, LDHCNR, tmp);
hsync_pos = var->xres + var->right_margin; hsync_pos = display_var->xres + display_var->right_margin;
tmp = hsync_pos / 8; /* HSYNP */ tmp = hsync_pos / 8; /* HSYNP */
tmp |= (var->hsync_len / 8) << 16; /* HSYNW */ tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
lcdc_write_chan(ch, LDHSYNR, tmp); lcdc_write_chan(ch, LDHSYNR, tmp);
/* vertical configuration */ /* vertical configuration */
tmp = var->yres + var->vsync_len + tmp = display_var->yres + display_var->vsync_len +
var->upper_margin + var->lower_margin; /* VTLN */ display_var->upper_margin + display_var->lower_margin; /* VTLN */
tmp |= var->yres << 16; /* VDLN */ tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
lcdc_write_chan(ch, LDVLNR, tmp); lcdc_write_chan(ch, LDVLNR, tmp);
tmp = var->yres + var->lower_margin; /* VSYNP */ tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
tmp |= var->vsync_len << 16; /* VSYNW */ tmp |= display_var->vsync_len << 16; /* VSYNW */
lcdc_write_chan(ch, LDVSYNR, tmp); lcdc_write_chan(ch, LDVSYNR, tmp);
/* Adjust horizontal synchronisation for HDMI */ /* Adjust horizontal synchronisation for HDMI */
tmp = ((var->xres & 7) << 24) | display_h_total = display_var->xres + display_var->hsync_len +
((h_total & 7) << 16) | display_var->left_margin + display_var->right_margin;
((var->hsync_len & 7) << 8) | tmp = ((display_var->xres & 7) << 24) |
((display_h_total & 7) << 16) |
((display_var->hsync_len & 7) << 8) |
hsync_pos; hsync_pos;
lcdc_write_chan(ch, LDHAJR, tmp); lcdc_write_chan(ch, LDHAJR, tmp);
} }
...@@ -477,7 +479,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) ...@@ -477,7 +479,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
m = 1 << 6; m = 1 << 6;
tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000); lcdc_write_chan(ch, LDDCKPAT1R, 0);
lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
} }
...@@ -520,7 +522,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) ...@@ -520,7 +522,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* set bpp format in PKF[4:0] */ /* set bpp format in PKF[4:0] */
tmp = lcdc_read_chan(ch, LDDFR); tmp = lcdc_read_chan(ch, LDDFR);
tmp &= ~(0x0001001f); tmp &= ~0x0001001f;
tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
lcdc_write_chan(ch, LDDFR, tmp); lcdc_write_chan(ch, LDDFR, tmp);
...@@ -1153,6 +1155,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) ...@@ -1153,6 +1155,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
info->screen_base = buf; info->screen_base = buf;
info->device = &pdev->dev; info->device = &pdev->dev;
info->par = ch; info->par = ch;
ch->display_var = *var;
} }
if (error) if (error)
......
...@@ -32,6 +32,7 @@ struct sh_mobile_lcdc_chan { ...@@ -32,6 +32,7 @@ struct sh_mobile_lcdc_chan {
unsigned long pan_offset; unsigned long pan_offset;
wait_queue_head_t frame_end_wait; wait_queue_head_t frame_end_wait;
struct completion vsync_completion; struct completion vsync_completion;
struct fb_var_screeninfo display_var;
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment