Skip to content

Commit

Permalink
drm/fb: add setcmap and fix 8-bit support.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dave Airlie committed Oct 5, 2009
1 parent dfee561 commit 068143d
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 8 deletions.
55 changes: 50 additions & 5 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,48 @@ int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int 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,
unsigned red,
unsigned green,
Expand Down Expand Up @@ -485,20 +527,21 @@ int drm_fb_helper_setcolreg(unsigned regno,
}

if (regno < 16) {
u32 *pal = fb->pseudo_palette;
switch (fb->depth) {
case 15:
fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
pal[regno] = ((red & 0xf800) >> 1) |
((green & 0xf800) >> 6) |
((blue & 0xf800) >> 11);
break;
case 16:
fb->pseudo_palette[regno] = (red & 0xf800) |
pal[regno] = (red & 0xf800) |
((green & 0xfc00) >> 5) |
((blue & 0xf800) >> 11);
break;
case 24:
case 32:
fb->pseudo_palette[regno] =
pal[regno] =
(((red >> 8) & 0xff) << info->var.red.offset) |
(((green >> 8) & 0xff) << info->var.green.offset) |
(((blue >> 8) & 0xff) << info->var.blue.offset);
Expand Down Expand Up @@ -851,10 +894,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
}
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.visual = FB_VISUAL_TRUECOLOR;
info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
FB_VISUAL_TRUECOLOR;
info->fix.type_aux = 0;
info->fix.xpanstep = 1; /* doing it in hw */
info->fix.ypanstep = 1; /* doing it in hw */
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3513,6 +3513,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_set_base = intel_pipe_set_base,
.prepare = intel_crtc_prepare,
.commit = intel_crtc_commit,
.load_lut = intel_crtc_load_lut,
};

static const struct drm_crtc_funcs intel_crtc_funcs = {
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/intel_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static struct fb_ops intelfb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
};

static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
Expand Down Expand Up @@ -206,7 +207,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,

// 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);

/* FIXME: we really shouldn't expose mmio space at all */
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
.mode_set_base = atombios_crtc_set_base,
.prepare = atombios_crtc_prepare,
.commit = atombios_crtc_commit,
.load_lut = radeon_crtc_load_lut,
};

void radeon_atombios_init_crtc(struct drm_device *dev,
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/radeon/radeon_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
};

/**
Expand Down Expand Up @@ -239,7 +240,7 @@ int radeonfb_create(struct drm_device *dev,

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->fbops = &radeonfb_ops;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/radeon_legacy_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.mode_set_base = radeon_crtc_set_base,
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
.load_lut = radeon_crtc_load_lut,
};


Expand Down
3 changes: 3 additions & 0 deletions include/drm/drm_crtc_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ struct drm_crtc_helper_funcs {
/* Move the crtc on the current fb to the given position *optional* */
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);

/* reload the current crtc LUT */
void (*load_lut)(struct drm_crtc *crtc);
};

struct drm_encoder_helper_funcs {
Expand Down
4 changes: 3 additions & 1 deletion include/drm/drm_fb_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
void drm_fb_helper_restore(void);
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
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_parse_command_line(struct drm_device *dev);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);

#endif

0 comments on commit 068143d

Please sign in to comment.