|
@@ -495,7 +495,6 @@ static int s3c_fb_set_par(struct fb_info *info)
|
|
|
u32 alpha = 0;
|
|
|
u32 data;
|
|
|
u32 pagewidth;
|
|
|
- int clkdiv;
|
|
|
|
|
|
dev_dbg(sfb->dev, "setting framebuffer parameters\n");
|
|
|
|
|
@@ -532,48 +531,9 @@ static int s3c_fb_set_par(struct fb_info *info)
|
|
|
/* disable the window whilst we update it */
|
|
|
writel(0, regs + WINCON(win_no));
|
|
|
|
|
|
- /* use platform specified window as the basis for the lcd timings */
|
|
|
-
|
|
|
- if (win_no == sfb->pdata->default_win) {
|
|
|
- clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
|
|
|
-
|
|
|
- data = sfb->pdata->vidcon0;
|
|
|
- data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
|
|
|
-
|
|
|
- if (clkdiv > 1)
|
|
|
- data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR;
|
|
|
- else
|
|
|
- data &= ~VIDCON0_CLKDIR; /* 1:1 clock */
|
|
|
-
|
|
|
- /* write the timing data to the panel */
|
|
|
-
|
|
|
- if (sfb->variant.is_2443)
|
|
|
- data |= (1 << 5);
|
|
|
-
|
|
|
- writel(data, regs + VIDCON0);
|
|
|
-
|
|
|
+ if (win_no == sfb->pdata->default_win)
|
|
|
s3c_fb_enable(sfb, 1);
|
|
|
|
|
|
- data = VIDTCON0_VBPD(var->upper_margin - 1) |
|
|
|
- VIDTCON0_VFPD(var->lower_margin - 1) |
|
|
|
- VIDTCON0_VSPW(var->vsync_len - 1);
|
|
|
-
|
|
|
- writel(data, regs + sfb->variant.vidtcon);
|
|
|
-
|
|
|
- data = VIDTCON1_HBPD(var->left_margin - 1) |
|
|
|
- VIDTCON1_HFPD(var->right_margin - 1) |
|
|
|
- VIDTCON1_HSPW(var->hsync_len - 1);
|
|
|
-
|
|
|
- /* VIDTCON1 */
|
|
|
- writel(data, regs + sfb->variant.vidtcon + 4);
|
|
|
-
|
|
|
- data = VIDTCON2_LINEVAL(var->yres - 1) |
|
|
|
- VIDTCON2_HOZVAL(var->xres - 1) |
|
|
|
- VIDTCON2_LINEVAL_E(var->yres - 1) |
|
|
|
- VIDTCON2_HOZVAL_E(var->xres - 1);
|
|
|
- writel(data, regs + sfb->variant.vidtcon + 8);
|
|
|
- }
|
|
|
-
|
|
|
/* write the buffer address */
|
|
|
|
|
|
/* start and end registers stride is 8 */
|
|
@@ -1144,11 +1104,11 @@ static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb,
|
|
|
|
|
|
dev_dbg(sfb->dev, "allocating memory for display\n");
|
|
|
|
|
|
- real_size = windata->win_mode.xres * windata->win_mode.yres;
|
|
|
+ real_size = windata->xres * windata->yres;
|
|
|
virt_size = windata->virtual_x * windata->virtual_y;
|
|
|
|
|
|
dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n",
|
|
|
- real_size, windata->win_mode.xres, windata->win_mode.yres,
|
|
|
+ real_size, windata->xres, windata->yres,
|
|
|
virt_size, windata->virtual_x, windata->virtual_y);
|
|
|
|
|
|
size = (real_size > virt_size) ? real_size : virt_size;
|
|
@@ -1230,7 +1190,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
|
|
|
struct s3c_fb_win **res)
|
|
|
{
|
|
|
struct fb_var_screeninfo *var;
|
|
|
- struct fb_videomode *initmode;
|
|
|
+ struct fb_videomode initmode;
|
|
|
struct s3c_fb_pd_win *windata;
|
|
|
struct s3c_fb_win *win;
|
|
|
struct fb_info *fbinfo;
|
|
@@ -1251,11 +1211,11 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
|
|
|
}
|
|
|
|
|
|
windata = sfb->pdata->win[win_no];
|
|
|
- initmode = &windata->win_mode;
|
|
|
+ initmode = *sfb->pdata->vtiming;
|
|
|
|
|
|
WARN_ON(windata->max_bpp == 0);
|
|
|
- WARN_ON(windata->win_mode.xres == 0);
|
|
|
- WARN_ON(windata->win_mode.yres == 0);
|
|
|
+ WARN_ON(windata->xres == 0);
|
|
|
+ WARN_ON(windata->yres == 0);
|
|
|
|
|
|
win = fbinfo->par;
|
|
|
*res = win;
|
|
@@ -1294,7 +1254,9 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
|
|
|
}
|
|
|
|
|
|
/* setup the initial video mode from the window */
|
|
|
- fb_videomode_to_var(&fbinfo->var, initmode);
|
|
|
+ initmode.xres = windata->xres;
|
|
|
+ initmode.yres = windata->yres;
|
|
|
+ fb_videomode_to_var(&fbinfo->var, &initmode);
|
|
|
|
|
|
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
|
|
|
fbinfo->fix.accel = FB_ACCEL_NONE;
|
|
@@ -1338,6 +1300,53 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * s3c_fb_set_rgb_timing() - set video timing for rgb interface.
|
|
|
+ * @sfb: The base resources for the hardware.
|
|
|
+ *
|
|
|
+ * Set horizontal and vertical lcd rgb interface timing.
|
|
|
+ */
|
|
|
+static void s3c_fb_set_rgb_timing(struct s3c_fb *sfb)
|
|
|
+{
|
|
|
+ struct fb_videomode *vmode = sfb->pdata->vtiming;
|
|
|
+ void __iomem *regs = sfb->regs;
|
|
|
+ int clkdiv;
|
|
|
+ u32 data;
|
|
|
+
|
|
|
+ if (!vmode->pixclock)
|
|
|
+ s3c_fb_missing_pixclock(vmode);
|
|
|
+
|
|
|
+ clkdiv = s3c_fb_calc_pixclk(sfb, vmode->pixclock);
|
|
|
+
|
|
|
+ data = sfb->pdata->vidcon0;
|
|
|
+ data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
|
|
|
+
|
|
|
+ if (clkdiv > 1)
|
|
|
+ data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR;
|
|
|
+ else
|
|
|
+ data &= ~VIDCON0_CLKDIR; /* 1:1 clock */
|
|
|
+
|
|
|
+ if (sfb->variant.is_2443)
|
|
|
+ data |= (1 << 5);
|
|
|
+ writel(data, regs + VIDCON0);
|
|
|
+
|
|
|
+ data = VIDTCON0_VBPD(vmode->upper_margin - 1) |
|
|
|
+ VIDTCON0_VFPD(vmode->lower_margin - 1) |
|
|
|
+ VIDTCON0_VSPW(vmode->vsync_len - 1);
|
|
|
+ writel(data, regs + sfb->variant.vidtcon);
|
|
|
+
|
|
|
+ data = VIDTCON1_HBPD(vmode->left_margin - 1) |
|
|
|
+ VIDTCON1_HFPD(vmode->right_margin - 1) |
|
|
|
+ VIDTCON1_HSPW(vmode->hsync_len - 1);
|
|
|
+ writel(data, regs + sfb->variant.vidtcon + 4);
|
|
|
+
|
|
|
+ data = VIDTCON2_LINEVAL(vmode->yres - 1) |
|
|
|
+ VIDTCON2_HOZVAL(vmode->xres - 1) |
|
|
|
+ VIDTCON2_LINEVAL_E(vmode->yres - 1) |
|
|
|
+ VIDTCON2_HOZVAL_E(vmode->xres - 1);
|
|
|
+ writel(data, regs + sfb->variant.vidtcon + 8);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* s3c_fb_clear_win() - clear hardware window registers.
|
|
|
* @sfb: The base resources for the hardware.
|
|
@@ -1481,15 +1490,14 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
|
|
|
writel(0xffffff, regs + WKEYCON1);
|
|
|
}
|
|
|
|
|
|
+ s3c_fb_set_rgb_timing(sfb);
|
|
|
+
|
|
|
/* we have the register setup, start allocating framebuffers */
|
|
|
|
|
|
for (win = 0; win < fbdrv->variant.nr_windows; win++) {
|
|
|
if (!pd->win[win])
|
|
|
continue;
|
|
|
|
|
|
- if (!pd->win[win]->win_mode.pixclock)
|
|
|
- s3c_fb_missing_pixclock(&pd->win[win]->win_mode);
|
|
|
-
|
|
|
ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win],
|
|
|
&sfb->windows[win]);
|
|
|
if (ret < 0) {
|
|
@@ -1623,6 +1631,8 @@ static int s3c_fb_resume(struct device *dev)
|
|
|
shadow_protect_win(win, 0);
|
|
|
}
|
|
|
|
|
|
+ s3c_fb_set_rgb_timing(sfb);
|
|
|
+
|
|
|
/* restore framebuffers */
|
|
|
for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
|
|
|
win = sfb->windows[win_no];
|