diff options
author | InKi Dae <daeinki@gmail.com> | 2009-07-05 12:08:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-06 13:57:03 -0700 |
commit | 600ce1a0faafeed1ce6bcfd421bc040b941cbbc1 (patch) | |
tree | 7d89a174453e5ef97ce4188f2e4d2d679c99af05 /drivers/video/s3c-fb.c | |
parent | 5bfd7560979062ad75c9805c1719cec990b5db29 (diff) | |
download | lwn-600ce1a0faafeed1ce6bcfd421bc040b941cbbc1.tar.gz lwn-600ce1a0faafeed1ce6bcfd421bc040b941cbbc1.zip |
drivers/video/s3c-fb.c: fix clock setting for Samsung SoC Framebuffer
Correct the CLKVAL_F field value of VIDEO MAIN CONTROLLER 0 REGITSTER.
Frame Rate is 1 / [ { (VSPW+1) + (VBPD+1) + (LIINEVAL + 1) + (VFPD+1)
} x {(HSPW+1) + (HBPD +1)
+ (HFPD+1) + (HOZVAL + 1) } x { ( CLKVAL+1 ) / ( Frequency of Clock
source ) } ] and VCLK = Video Clock Source / (CLKVAL +1).
therefore CLKVAL_F should be "CLKVAL_F = Frequency of Clock source / pixel
clock * refresh".
for this, I added refresh value in platform data like below.
static struct s3c_fb_pd_win xxx_fb_win0 = {
/* this is to ensure we use win0 */
.win_mode = {
.refresh = 60,
.pixclock = (66+4+2+480)*(15+5+3+800),
.left_margin = 66,
.right_margin = 2,
.upper_margin = 15,
.lower_margin = 3,
.hsync_len = 4,
.vsync_len = 5,
.xres = 480,
.yres = 800,
},
.max_bpp = 32,
.default_bpp = 24,
};
static struct s3c_fb_platdata xxx_lcd_pdata __initdata = {
.win[0] = &xxx_fb_win0,
.vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
.vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC
| VIDCON1_INV_VCLK | VIDCON1_INV_VDEN,
.setup_gpio = s5pc1xx_fb_gpio_setup_24bpp,
};
xxx_machine_init()
{
.
.
.
s3c_fb_set_platdata(&xxx_lcd_pdata);
}
platform data defined in machine code should be setting using
s3c_fb_set_platdata().
Signed-off-by: InKi Dae <inki.dae@samsung.com>
Cc: Kyungmin Park <kmpark@infradead.org>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r-- | drivers/video/s3c-fb.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 43680e545427..bb63c07e13de 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -211,23 +211,21 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, /** * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. + * @id: window id. * @sfb: The hardware state. * @pixclock: The pixel clock wanted, in picoseconds. * * Given the specified pixel clock, work out the necessary divider to get * close to the output frequency. */ -static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) +static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk) { + struct s3c_fb_pd_win *win = sfb->pdata->win[id]; unsigned long clk = clk_get_rate(sfb->bus_clk); - unsigned long long tmp; unsigned int result; - tmp = (unsigned long long)clk; - tmp *= pixclk; - - do_div(tmp, 1000000000UL); - result = (unsigned int)tmp / 1000; + pixclk *= win->win_mode.refresh; + result = clk / pixclk; dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", pixclk, clk, result, clk / result); @@ -267,6 +265,7 @@ static int s3c_fb_set_par(struct fb_info *info) struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; int win_no = win->index; + u32 osdc_data = 0; u32 data; u32 pagewidth; int clkdiv; @@ -302,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info) /* use window 0 as the basis for the lcd output timings */ if (win_no == 0) { - clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); + clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock); data = sfb->pdata->vidcon0; data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); @@ -359,8 +358,6 @@ static int s3c_fb_set_par(struct fb_info *info) data = var->xres * var->yres; - u32 osdc_data = 0; - osdc_data = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); |