static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
- unsigned offset;
- int rot;
-
- rot = ofbi->rotation;
-
- offset = omapfb_get_vrfb_offset(ofbi, rot);
-
- return ofbi->region.vrfb.paddr[rot] + offset;
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ return ofbi->region.vrfb.paddr[ofbi->rotation]
+ + omapfb_get_vrfb_offset(ofbi, ofbi->rotation);
} else {
return ofbi->region.paddr;
}
u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return ofbi->region.vrfb.paddr[0];
else
return ofbi->region.paddr;
void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return ofbi->region.vrfb.vaddr[0];
else
return ofbi->region.vaddr;
return -EINVAL;
}
+static int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+ struct fb_var_screeninfo *var)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+ struct omapfb_colormode *mode = &omapfb_colormodes[i];
+ if (dssmode == mode->dssmode) {
+ assign_colormode_to_var(var, mode);
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
void set_fb_fix(struct fb_info *fbi)
{
struct fb_fix_screeninfo *fix = &fbi->fix;
fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
/* used by mmap in fbmem.c */
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
- fix->line_length =
- (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
- else
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ switch (var->nonstd) {
+ case OMAPFB_COLOR_YUV422:
+ case OMAPFB_COLOR_YUY422:
+ fix->line_length =
+ (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2;
+ break;
+ default:
+ fix->line_length =
+ (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
+ break;
+ }
+ } else
fix->line_length =
(var->xres_virtual * var->bits_per_pixel) >> 3;
fix->smem_start = omapfb_get_region_paddr(ofbi);
fix->xpanstep = 1;
fix->ypanstep = 1;
- if (rg->size) {
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
- omap_vrfb_setup(&rg->vrfb, rg->paddr,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel >> 3);
+ if (rg->size && ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ enum omap_color_mode mode = 0;
+ mode = fb_mode_to_dss_mode(var);
+
+ omap_vrfb_setup(&rg->vrfb, rg->paddr,
+ var->xres_virtual,
+ var->yres_virtual,
+ mode);
}
}
if (var->yres > var->yres_virtual)
var->yres = var->yres_virtual;
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
line_size = OMAP_VRFB_LINE_LEN * bytespp;
else
line_size = var->xres_virtual * bytespp;
if (line_size * var->yres_virtual > max_frame_size) {
DBG("can't fit FB into memory, reducing x\n");
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return -EINVAL;
var->xres_virtual = max_frame_size / var->yres_virtual /
struct omap_overlay_info info;
int xres, yres;
int screen_width;
- int rot, mirror;
+ int mirror;
DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id,
posx, posy, outw, outh);
offset = ((var->yoffset * var->xres_virtual +
var->xoffset) * var->bits_per_pixel) >> 3;
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
data_start_p = omapfb_get_region_rot_paddr(ofbi);
data_start_v = NULL;
} else {
goto err;
}
- screen_width = fix->line_length / (var->bits_per_pixel >> 3);
+ switch (var->nonstd) {
+ case OMAPFB_COLOR_YUV422:
+ case OMAPFB_COLOR_YUY422:
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ screen_width = fix->line_length
+ / (var->bits_per_pixel >> 2);
+ break;
+ }
+ default:
+ screen_width = fix->line_length / (var->bits_per_pixel >> 3);
+ break;
+ }
ovl->get_overlay_info(ovl, &info);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
- rot = 0;
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
mirror = 0;
- } else {
- rot = ofbi->rotation;
+ else
mirror = ofbi->mirror;
- }
info.paddr = data_start_p;
info.vaddr = data_start_v;
info.width = xres;
info.height = yres;
info.color_mode = mode;
- info.rotation = rot;
+ info.rotation_type = ofbi->rotation_type;
+ info.rotation = ofbi->rotation;
info.mirror = mirror;
info.pos_x = posx;
if (rg->vaddr)
iounmap(rg->vaddr);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
/* unmap the 0 angle rotation */
if (rg->vrfb.vaddr[0]) {
iounmap(rg->vrfb.vaddr[0]);
struct omapfb2_mem_region *rg;
void __iomem *vaddr;
int r;
- int clear = 0;
rg = &ofbi->region;
memset(rg, 0, sizeof(*rg));
if (!paddr) {
DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
r = omap_vram_alloc(OMAPFB_MEMTYPE_SDRAM, size, &paddr);
- clear = 1;
} else {
DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
ofbi->id);
return -ENOMEM;
}
- if (ofbi->rotation_type != OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
vaddr = ioremap_wc(paddr, size);
if (!vaddr) {
}
DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
-
- if (clear)
- memset_io(vaddr, 0, size);
} else {
void __iomem *va;
if(!va) {
printk(KERN_ERR "vrfb: ioremap failed\n");
+ omap_vrfb_release_ctx(&rg->vrfb);
return -ENOMEM;
}
rg->vrfb.vaddr[0] = va;
vaddr = NULL;
-
- if (clear)
- memset_io(va, 0, size);
}
rg->paddr = paddr;
display->get_resolution(display, &w, &h);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+#ifdef DEBUG
int oldw = w, oldh = h;
+#endif
omap_vrfb_adjust_size(&w, &h, bytespp);
return omapfb_alloc_fbmem(fbi, size, paddr);
}
+static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format format)
+{
+ enum omap_color_mode mode;
+
+ switch (format) {
+ case OMAPFB_COLOR_RGB565:
+ mode = OMAP_DSS_COLOR_RGB16;
+ break;
+ case OMAPFB_COLOR_YUV422:
+ mode = OMAP_DSS_COLOR_YUV2;
+ break;
+ case OMAPFB_COLOR_CLUT_8BPP:
+ mode = OMAP_DSS_COLOR_CLUT8;
+ break;
+ case OMAPFB_COLOR_CLUT_4BPP:
+ mode = OMAP_DSS_COLOR_CLUT4;
+ break;
+ case OMAPFB_COLOR_CLUT_2BPP:
+ mode = OMAP_DSS_COLOR_CLUT2;
+ break;
+ case OMAPFB_COLOR_CLUT_1BPP:
+ mode = OMAP_DSS_COLOR_CLUT1;
+ break;
+ case OMAPFB_COLOR_RGB444:
+ mode = OMAP_DSS_COLOR_RGB12U;
+ break;
+ case OMAPFB_COLOR_YUY422:
+ mode = OMAP_DSS_COLOR_UYVY;
+ break;
+ case OMAPFB_COLOR_ARGB16:
+ mode = OMAP_DSS_COLOR_ARGB16;
+ break;
+ case OMAPFB_COLOR_RGB24U:
+ mode = OMAP_DSS_COLOR_RGB24U;
+ break;
+ case OMAPFB_COLOR_RGB24P:
+ mode = OMAP_DSS_COLOR_RGB24P;
+ break;
+ case OMAPFB_COLOR_ARGB32:
+ mode = OMAP_DSS_COLOR_ARGB32;
+ break;
+ case OMAPFB_COLOR_RGBA32:
+ mode = OMAP_DSS_COLOR_RGBA32;
+ break;
+ case OMAPFB_COLOR_RGBX32:
+ mode = OMAP_DSS_COLOR_RGBX32;
+ break;
+ default:
+ mode = -EINVAL;
+ }
+
+ return mode;
+}
+
static int omapfb_parse_vram_param(const char *param, int max_entries,
unsigned long *sizes, unsigned long *paddrs)
{
}
var->nonstd = 0;
+ var->bits_per_pixel = 0;
var->rotate = ofbi->rotation;
+ /*
+ * Check if there is a default color format set in the board file,
+ * and use this format instead the default deducted from the
+ * display bpp.
+ */
+ if (fbdev->dev->platform_data) {
+ struct omapfb_platform_data *opd;
+ int id = ofbi->id;
+
+ opd = fbdev->dev->platform_data;
+ if (opd->mem_desc.region[id].format_used) {
+ enum omap_color_mode mode;
+ enum omapfb_color_format format;
+
+ format = opd->mem_desc.region[id].format;
+ mode = fb_format_to_dss_mode(format);
+ if (mode < 0) {
+ r = mode;
+ goto err;
+ }
+ r = dss_mode_to_fb_mode(mode, var);
+ if (r < 0)
+ goto err;
+ }
+ }
+
if (display) {
u16 w, h;
display->get_resolution(display, &w, &h);
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
- switch (display->get_recommended_bpp(display)) {
- case 16:
- var->bits_per_pixel = 16;
- break;
- case 24:
- var->bits_per_pixel = 32;
- break;
- default:
- dev_err(fbdev->dev, "illegal display bpp\n");
- return -EINVAL;
+ if (!var->bits_per_pixel) {
+ switch (display->get_recommended_bpp(display)) {
+ case 16:
+ var->bits_per_pixel = 16;
+ break;
+ case 24:
+ var->bits_per_pixel = 32;
+ break;
+ default:
+ dev_err(fbdev->dev, "illegal display bpp\n");
+ return -EINVAL;
+ }
}
} else {
/* if there's no display, let's just guess some basic values */
var->yres = 240;
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
- var->bits_per_pixel = 16;
+ if (!var->bits_per_pixel)
+ var->bits_per_pixel = 16;
}
r = check_fb_var(fbi, var);
goto err;
set_fb_fix(fbi);
+
+ r = fb_alloc_cmap(&fbi->cmap, 256, 0);
+ if (r)
+ dev_err(fbdev->dev, "unable to allocate color map memory\n");
+
err:
return r;
}
ofbi->id = i;
/* assign these early, so that fb alloc can use them */
- ofbi->rotation_type = def_vrfb ? OMAPFB_ROT_VRFB :
- OMAPFB_ROT_DMA;
+ ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
+ OMAP_DSS_ROT_DMA;
ofbi->rotation = def_rotate;
ofbi->mirror = def_mirror;