summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/radeon_ms_fb.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c
index b629b9eb..fc9e99ec 100644
--- a/linux-core/radeon_ms_fb.c
+++ b/linux-core/radeon_ms_fb.c
@@ -52,12 +52,35 @@ static int radeonfb_setcolreg(unsigned regno, unsigned red,
unsigned transp, struct fb_info *info)
{
struct radeonfb_par *par = info->par;
+ struct drm_framebuffer *fb = par->crtc->fb;
struct drm_crtc *crtc = par->crtc;
- if (regno > 255)
+ if (regno > 255) {
return 1;
- if (crtc->funcs->gamma_set)
+ }
+ if (crtc->funcs->gamma_set) {
crtc->funcs->gamma_set(crtc, red, green, blue, regno);
+ }
+ if (regno < 16) {
+ switch (fb->depth) {
+ case 15:
+ fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
+ ((green & 0xf800) >> 6) |
+ ((blue & 0xf800) >> 11);
+ break;
+ case 16:
+ fb->pseudo_palette[regno] = (red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+ break;
+ case 24:
+ case 32:
+ fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
+ (green & 0xff00) |
+ ((blue & 0xff00) >> 8);
+ break;
+ }
+ }
return 0;
}
HE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Keith Whitwell <keith@tungstengraphics.com> * Eric Anholt <anholt@FreeBSD.org> */ #include "drmP.h" #include "drm.h" #include "r128_drm.h" #include "r128_drv.h" irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; int status; status = R128_READ(R128_GEN_INT_STATUS); /* VBLANK interrupt */ if (status & R128_CRTC_VBLANK_INT) { R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); return IRQ_HANDLED; } return IRQ_NONE; } int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) { unsigned int cur_vblank; int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using vertical blanks... */ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; } void r128_driver_irq_preinstall(drm_device_t * dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; /* Disable *all* interrupts */ R128_WRITE(R128_GEN_INT_CNTL, 0); /* Clear vblank bit if it's already high */ R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); } void r128_driver_irq_postinstall(drm_device_t * dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; /* Turn on VBL interrupt */ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); } void r128_driver_irq_uninstall(drm_device_t * dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; if (!dev_priv) return; /* Disable *all* interrupts */ R128_WRITE(R128_GEN_INT_CNTL, 0); }