diff options
author | InKi Dae <daeinki@gmail.com> | 2009-07-05 15:08:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-06 16:57:03 -0400 |
commit | 600ce1a0faafeed1ce6bcfd421bc040b941cbbc1 (patch) | |
tree | 7d89a174453e5ef97ce4188f2e4d2d679c99af05 | |
parent | 5bfd7560979062ad75c9805c1719cec990b5db29 (diff) |
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>
-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, | |||
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. | 213 | * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. |
214 | * @id: window id. | ||
214 | * @sfb: The hardware state. | 215 | * @sfb: The hardware state. |
215 | * @pixclock: The pixel clock wanted, in picoseconds. | 216 | * @pixclock: The pixel clock wanted, in picoseconds. |
216 | * | 217 | * |
217 | * Given the specified pixel clock, work out the necessary divider to get | 218 | * Given the specified pixel clock, work out the necessary divider to get |
218 | * close to the output frequency. | 219 | * close to the output frequency. |
219 | */ | 220 | */ |
220 | static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) | 221 | static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk) |
221 | { | 222 | { |
223 | struct s3c_fb_pd_win *win = sfb->pdata->win[id]; | ||
222 | unsigned long clk = clk_get_rate(sfb->bus_clk); | 224 | unsigned long clk = clk_get_rate(sfb->bus_clk); |
223 | unsigned long long tmp; | ||
224 | unsigned int result; | 225 | unsigned int result; |
225 | 226 | ||
226 | tmp = (unsigned long long)clk; | 227 | pixclk *= win->win_mode.refresh; |
227 | tmp *= pixclk; | 228 | result = clk / pixclk; |
228 | |||
229 | do_div(tmp, 1000000000UL); | ||
230 | result = (unsigned int)tmp / 1000; | ||
231 | 229 | ||
232 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", | 230 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", |
233 | pixclk, clk, result, clk / result); | 231 | pixclk, clk, result, clk / result); |
@@ -267,6 +265,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
267 | struct s3c_fb *sfb = win->parent; | 265 | struct s3c_fb *sfb = win->parent; |
268 | void __iomem *regs = sfb->regs; | 266 | void __iomem *regs = sfb->regs; |
269 | int win_no = win->index; | 267 | int win_no = win->index; |
268 | u32 osdc_data = 0; | ||
270 | u32 data; | 269 | u32 data; |
271 | u32 pagewidth; | 270 | u32 pagewidth; |
272 | int clkdiv; | 271 | int clkdiv; |
@@ -302,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
302 | /* use window 0 as the basis for the lcd output timings */ | 301 | /* use window 0 as the basis for the lcd output timings */ |
303 | 302 | ||
304 | if (win_no == 0) { | 303 | if (win_no == 0) { |
305 | clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); | 304 | clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock); |
306 | 305 | ||
307 | data = sfb->pdata->vidcon0; | 306 | data = sfb->pdata->vidcon0; |
308 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); | 307 | data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); |
@@ -359,8 +358,6 @@ static int s3c_fb_set_par(struct fb_info *info) | |||
359 | 358 | ||
360 | data = var->xres * var->yres; | 359 | data = var->xres * var->yres; |
361 | 360 | ||
362 | u32 osdc_data = 0; | ||
363 | |||
364 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | | 361 | osdc_data = VIDISD14C_ALPHA1_R(0xf) | |
365 | VIDISD14C_ALPHA1_G(0xf) | | 362 | VIDISD14C_ALPHA1_G(0xf) | |
366 | VIDISD14C_ALPHA1_B(0xf); | 363 | VIDISD14C_ALPHA1_B(0xf); |