mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
drm/fb: add setcmap and fix 8-bit support.
This adds support for the setcmap api and fixes the 8bpp support at least on radeon hardware. It adds a new load_lut hook which can be called once the color map is setup. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
dfee5614e4
commit
068143d388
8 changed files with 63 additions and 8 deletions
|
@ -454,6 +454,48 @@ out_free:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
|
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
|
||||||
|
|
||||||
|
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct drm_fb_helper *fb_helper = info->par;
|
||||||
|
struct drm_device *dev = fb_helper->dev;
|
||||||
|
u16 *red, *green, *blue, *transp;
|
||||||
|
struct drm_crtc *crtc;
|
||||||
|
int i, rc = 0;
|
||||||
|
int start;
|
||||||
|
|
||||||
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||||
|
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||||
|
for (i = 0; i < fb_helper->crtc_count; i++) {
|
||||||
|
if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == fb_helper->crtc_count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
red = cmap->red;
|
||||||
|
green = cmap->green;
|
||||||
|
blue = cmap->blue;
|
||||||
|
transp = cmap->transp;
|
||||||
|
start = cmap->start;
|
||||||
|
|
||||||
|
for (i = 0; i < cmap->len; i++) {
|
||||||
|
u16 hred, hgreen, hblue, htransp = 0xffff;
|
||||||
|
|
||||||
|
hred = *red++;
|
||||||
|
hgreen = *green++;
|
||||||
|
hblue = *blue++;
|
||||||
|
|
||||||
|
if (transp)
|
||||||
|
htransp = *transp++;
|
||||||
|
|
||||||
|
fb_helper->funcs->gamma_set(crtc, hred, hgreen, hblue, start++);
|
||||||
|
}
|
||||||
|
crtc_funcs->load_lut(crtc);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_fb_helper_setcmap);
|
||||||
|
|
||||||
int drm_fb_helper_setcolreg(unsigned regno,
|
int drm_fb_helper_setcolreg(unsigned regno,
|
||||||
unsigned red,
|
unsigned red,
|
||||||
unsigned green,
|
unsigned green,
|
||||||
|
@ -485,20 +527,21 @@ int drm_fb_helper_setcolreg(unsigned regno,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regno < 16) {
|
if (regno < 16) {
|
||||||
|
u32 *pal = fb->pseudo_palette;
|
||||||
switch (fb->depth) {
|
switch (fb->depth) {
|
||||||
case 15:
|
case 15:
|
||||||
fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
|
pal[regno] = ((red & 0xf800) >> 1) |
|
||||||
((green & 0xf800) >> 6) |
|
((green & 0xf800) >> 6) |
|
||||||
((blue & 0xf800) >> 11);
|
((blue & 0xf800) >> 11);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
fb->pseudo_palette[regno] = (red & 0xf800) |
|
pal[regno] = (red & 0xf800) |
|
||||||
((green & 0xfc00) >> 5) |
|
((green & 0xfc00) >> 5) |
|
||||||
((blue & 0xf800) >> 11);
|
((blue & 0xf800) >> 11);
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
case 32:
|
case 32:
|
||||||
fb->pseudo_palette[regno] =
|
pal[regno] =
|
||||||
(((red >> 8) & 0xff) << info->var.red.offset) |
|
(((red >> 8) & 0xff) << info->var.red.offset) |
|
||||||
(((green >> 8) & 0xff) << info->var.green.offset) |
|
(((green >> 8) & 0xff) << info->var.green.offset) |
|
||||||
(((blue >> 8) & 0xff) << info->var.blue.offset);
|
(((blue >> 8) & 0xff) << info->var.blue.offset);
|
||||||
|
@ -851,10 +894,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_fb_helper_free);
|
EXPORT_SYMBOL(drm_fb_helper_free);
|
||||||
|
|
||||||
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
|
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
|
||||||
|
uint32_t depth)
|
||||||
{
|
{
|
||||||
info->fix.type = FB_TYPE_PACKED_PIXELS;
|
info->fix.type = FB_TYPE_PACKED_PIXELS;
|
||||||
info->fix.visual = FB_VISUAL_TRUECOLOR;
|
info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
|
||||||
|
FB_VISUAL_TRUECOLOR;
|
||||||
info->fix.type_aux = 0;
|
info->fix.type_aux = 0;
|
||||||
info->fix.xpanstep = 1; /* doing it in hw */
|
info->fix.xpanstep = 1; /* doing it in hw */
|
||||||
info->fix.ypanstep = 1; /* doing it in hw */
|
info->fix.ypanstep = 1; /* doing it in hw */
|
||||||
|
|
|
@ -3513,6 +3513,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
|
||||||
.mode_set_base = intel_pipe_set_base,
|
.mode_set_base = intel_pipe_set_base,
|
||||||
.prepare = intel_crtc_prepare,
|
.prepare = intel_crtc_prepare,
|
||||||
.commit = intel_crtc_commit,
|
.commit = intel_crtc_commit,
|
||||||
|
.load_lut = intel_crtc_load_lut,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct drm_crtc_funcs intel_crtc_funcs = {
|
static const struct drm_crtc_funcs intel_crtc_funcs = {
|
||||||
|
|
|
@ -60,6 +60,7 @@ static struct fb_ops intelfb_ops = {
|
||||||
.fb_imageblit = cfb_imageblit,
|
.fb_imageblit = cfb_imageblit,
|
||||||
.fb_pan_display = drm_fb_helper_pan_display,
|
.fb_pan_display = drm_fb_helper_pan_display,
|
||||||
.fb_blank = drm_fb_helper_blank,
|
.fb_blank = drm_fb_helper_blank,
|
||||||
|
.fb_setcmap = drm_fb_helper_setcmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
||||||
|
@ -206,7 +207,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
|
||||||
|
|
||||||
// memset(info->screen_base, 0, size);
|
// memset(info->screen_base, 0, size);
|
||||||
|
|
||||||
drm_fb_helper_fill_fix(info, fb->pitch);
|
drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
|
||||||
drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
|
drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
|
||||||
|
|
||||||
/* FIXME: we really shouldn't expose mmio space at all */
|
/* FIXME: we really shouldn't expose mmio space at all */
|
||||||
|
|
|
@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
|
||||||
.mode_set_base = atombios_crtc_set_base,
|
.mode_set_base = atombios_crtc_set_base,
|
||||||
.prepare = atombios_crtc_prepare,
|
.prepare = atombios_crtc_prepare,
|
||||||
.commit = atombios_crtc_commit,
|
.commit = atombios_crtc_commit,
|
||||||
|
.load_lut = radeon_crtc_load_lut,
|
||||||
};
|
};
|
||||||
|
|
||||||
void radeon_atombios_init_crtc(struct drm_device *dev,
|
void radeon_atombios_init_crtc(struct drm_device *dev,
|
||||||
|
|
|
@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = {
|
||||||
.fb_imageblit = cfb_imageblit,
|
.fb_imageblit = cfb_imageblit,
|
||||||
.fb_pan_display = drm_fb_helper_pan_display,
|
.fb_pan_display = drm_fb_helper_pan_display,
|
||||||
.fb_blank = drm_fb_helper_blank,
|
.fb_blank = drm_fb_helper_blank,
|
||||||
|
.fb_setcmap = drm_fb_helper_setcmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -239,7 +240,7 @@ int radeonfb_create(struct drm_device *dev,
|
||||||
|
|
||||||
strcpy(info->fix.id, "radeondrmfb");
|
strcpy(info->fix.id, "radeondrmfb");
|
||||||
|
|
||||||
drm_fb_helper_fill_fix(info, fb->pitch);
|
drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
|
||||||
|
|
||||||
info->flags = FBINFO_DEFAULT;
|
info->flags = FBINFO_DEFAULT;
|
||||||
info->fbops = &radeonfb_ops;
|
info->fbops = &radeonfb_ops;
|
||||||
|
|
|
@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
|
||||||
.mode_set_base = radeon_crtc_set_base,
|
.mode_set_base = radeon_crtc_set_base,
|
||||||
.prepare = radeon_crtc_prepare,
|
.prepare = radeon_crtc_prepare,
|
||||||
.commit = radeon_crtc_commit,
|
.commit = radeon_crtc_commit,
|
||||||
|
.load_lut = radeon_crtc_load_lut,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@ struct drm_crtc_helper_funcs {
|
||||||
/* Move the crtc on the current fb to the given position *optional* */
|
/* Move the crtc on the current fb to the given position *optional* */
|
||||||
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
|
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
|
||||||
struct drm_framebuffer *old_fb);
|
struct drm_framebuffer *old_fb);
|
||||||
|
|
||||||
|
/* reload the current crtc LUT */
|
||||||
|
void (*load_lut)(struct drm_crtc *crtc);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drm_encoder_helper_funcs {
|
struct drm_encoder_helper_funcs {
|
||||||
|
|
|
@ -98,9 +98,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
|
||||||
void drm_fb_helper_restore(void);
|
void drm_fb_helper_restore(void);
|
||||||
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
|
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
|
||||||
uint32_t fb_width, uint32_t fb_height);
|
uint32_t fb_width, uint32_t fb_height);
|
||||||
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch);
|
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
|
||||||
|
uint32_t depth);
|
||||||
|
|
||||||
int drm_fb_helper_add_connector(struct drm_connector *connector);
|
int drm_fb_helper_add_connector(struct drm_connector *connector);
|
||||||
int drm_fb_helper_parse_command_line(struct drm_device *dev);
|
int drm_fb_helper_parse_command_line(struct drm_device *dev);
|
||||||
|
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue