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
					
				| @ -454,6 +454,48 @@ out_free: | ||||
| } | ||||
| 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, | ||||
| @ -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); | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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 = { | ||||
|  | ||||
| @ -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 = { | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
| @ -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; | ||||
|  | ||||
| @ -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, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user