diff options
author | Damian <dhobsong@igel.co.jp> | 2011-05-18 07:10:08 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-05-23 03:06:26 -0400 |
commit | 3fedd2ac7662a10ab2973d3b6f11cdce87b7171a (patch) | |
tree | 07640424b8ed5b4342376886023beb8907fedfea /drivers/video | |
parent | 7caa4342ca5b37d2d178b464c16badd4228b3b7b (diff) |
sh_mobile_meram: Add support for NV24 framebuffers
Since the NV24 framebuffer has a CbCr plane that is twice as wide
as the Y plane, it needs to be handled as a special case.
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 10 | ||||
-rw-r--r-- | drivers/video/sh_mobile_meram.c | 24 |
2 files changed, 26 insertions, 8 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 3a2cbd18f91b..1c652da348ea 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -627,10 +627,14 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
627 | 627 | ||
628 | ch->meram_enabled = 0; | 628 | ch->meram_enabled = 0; |
629 | 629 | ||
630 | if (ch->info->var.nonstd) | 630 | if (ch->info->var.nonstd) { |
631 | pf = SH_MOBILE_MERAM_PF_NV; | 631 | if (ch->info->var.bits_per_pixel == 24) |
632 | else | 632 | pf = SH_MOBILE_MERAM_PF_NV24; |
633 | else | ||
634 | pf = SH_MOBILE_MERAM_PF_NV; | ||
635 | } else { | ||
633 | pf = SH_MOBILE_MERAM_PF_RGB; | 636 | pf = SH_MOBILE_MERAM_PF_RGB; |
637 | } | ||
634 | 638 | ||
635 | ret = mdev->ops->meram_register(mdev, cfg, pitch, | 639 | ret = mdev->ops->meram_register(mdev, cfg, pitch, |
636 | ch->info->var.yres, | 640 | ch->info->var.yres, |
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c index bd68f3d43ab5..9170c82b495c 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/sh_mobile_meram.c | |||
@@ -164,6 +164,16 @@ static inline void meram_unmark(struct sh_mobile_meram_priv *priv, | |||
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
167 | /* | ||
168 | * is this a YCbCr(NV12, NV16 or NV24) colorspace | ||
169 | */ | ||
170 | static inline int is_nvcolor(int cspace) | ||
171 | { | ||
172 | if (cspace == SH_MOBILE_MERAM_PF_NV || | ||
173 | cspace == SH_MOBILE_MERAM_PF_NV24) | ||
174 | return 1; | ||
175 | return 0; | ||
176 | } | ||
167 | 177 | ||
168 | /* | 178 | /* |
169 | * set the next address to fetch | 179 | * set the next address to fetch |
@@ -184,7 +194,7 @@ static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv, | |||
184 | meram_write_icb(priv->base, cfg->icb[0].marker_icb, target, | 194 | meram_write_icb(priv->base, cfg->icb[0].marker_icb, target, |
185 | base_addr_y + cfg->icb[0].cache_unit); | 195 | base_addr_y + cfg->icb[0].cache_unit); |
186 | 196 | ||
187 | if (cfg->pixelformat == SH_MOBILE_MERAM_PF_NV) { | 197 | if (is_nvcolor(cfg->pixelformat)) { |
188 | meram_write_icb(priv->base, cfg->icb[1].cache_icb, target, | 198 | meram_write_icb(priv->base, cfg->icb[1].cache_icb, target, |
189 | base_addr_c); | 199 | base_addr_c); |
190 | meram_write_icb(priv->base, cfg->icb[1].marker_icb, target, | 200 | meram_write_icb(priv->base, cfg->icb[1].marker_icb, target, |
@@ -208,7 +218,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata, | |||
208 | icb_offset = 0xc0000000 | (cfg->current_reg << 23); | 218 | icb_offset = 0xc0000000 | (cfg->current_reg << 23); |
209 | 219 | ||
210 | *icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24); | 220 | *icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24); |
211 | if ((*icb_addr_c) && cfg->pixelformat == SH_MOBILE_MERAM_PF_NV) | 221 | if ((*icb_addr_c) && is_nvcolor(cfg->pixelformat)) |
212 | *icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24); | 222 | *icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24); |
213 | } | 223 | } |
214 | 224 | ||
@@ -316,6 +326,7 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, | |||
316 | return -EINVAL; | 326 | return -EINVAL; |
317 | 327 | ||
318 | if (pixelformat != SH_MOBILE_MERAM_PF_NV && | 328 | if (pixelformat != SH_MOBILE_MERAM_PF_NV && |
329 | pixelformat != SH_MOBILE_MERAM_PF_NV24 && | ||
319 | pixelformat != SH_MOBILE_MERAM_PF_RGB) | 330 | pixelformat != SH_MOBILE_MERAM_PF_RGB) |
320 | return -EINVAL; | 331 | return -EINVAL; |
321 | 332 | ||
@@ -366,7 +377,7 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, | |||
366 | n = 2; | 377 | n = 2; |
367 | } | 378 | } |
368 | 379 | ||
369 | if (pixelformat == SH_MOBILE_MERAM_PF_NV && n != 2) { | 380 | if (is_nvcolor(pixelformat) && n != 2) { |
370 | dev_err(&pdev->dev, "requires two ICB sets for planar Y/C."); | 381 | dev_err(&pdev->dev, "requires two ICB sets for planar Y/C."); |
371 | error = -EINVAL; | 382 | error = -EINVAL; |
372 | goto err; | 383 | goto err; |
@@ -375,7 +386,7 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, | |||
375 | /* we now register the ICB */ | 386 | /* we now register the ICB */ |
376 | cfg->pixelformat = pixelformat; | 387 | cfg->pixelformat = pixelformat; |
377 | meram_mark(priv, &cfg->icb[0]); | 388 | meram_mark(priv, &cfg->icb[0]); |
378 | if (pixelformat == SH_MOBILE_MERAM_PF_NV) | 389 | if (is_nvcolor(pixelformat)) |
379 | meram_mark(priv, &cfg->icb[1]); | 390 | meram_mark(priv, &cfg->icb[1]); |
380 | 391 | ||
381 | /* initialize MERAM */ | 392 | /* initialize MERAM */ |
@@ -384,6 +395,9 @@ static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, | |||
384 | if (pixelformat == SH_MOBILE_MERAM_PF_NV) | 395 | if (pixelformat == SH_MOBILE_MERAM_PF_NV) |
385 | meram_init(priv, &cfg->icb[1], xres, (yres + 1) / 2, | 396 | meram_init(priv, &cfg->icb[1], xres, (yres + 1) / 2, |
386 | &out_pitch); | 397 | &out_pitch); |
398 | else if (pixelformat == SH_MOBILE_MERAM_PF_NV24) | ||
399 | meram_init(priv, &cfg->icb[1], 2 * xres, (yres + 1) / 2, | ||
400 | &out_pitch); | ||
387 | 401 | ||
388 | cfg->current_reg = 1; | 402 | cfg->current_reg = 1; |
389 | meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c); | 403 | meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c); |
@@ -410,7 +424,7 @@ static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, | |||
410 | mutex_lock(&priv->lock); | 424 | mutex_lock(&priv->lock); |
411 | 425 | ||
412 | /* deinit & unmark */ | 426 | /* deinit & unmark */ |
413 | if (cfg->pixelformat == SH_MOBILE_MERAM_PF_NV) { | 427 | if (is_nvcolor(cfg->pixelformat)) { |
414 | meram_deinit(priv, &cfg->icb[1]); | 428 | meram_deinit(priv, &cfg->icb[1]); |
415 | meram_unmark(priv, &cfg->icb[1]); | 429 | meram_unmark(priv, &cfg->icb[1]); |
416 | } | 430 | } |