aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorDamian <dhobsong@igel.co.jp>2011-05-18 07:10:08 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-05-23 03:06:26 -0400
commit3fedd2ac7662a10ab2973d3b6f11cdce87b7171a (patch)
tree07640424b8ed5b4342376886023beb8907fedfea /drivers/video
parent7caa4342ca5b37d2d178b464c16badd4228b3b7b (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.c10
-rw-r--r--drivers/video/sh_mobile_meram.c24
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 */
170static 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 }