Thu Sep 9 01:22:11 2010 UTC ()
add backlight control via PMF
TODO: support wsconsctl


(macallan)
diff -r1.10 -r1.11 src/sys/dev/pci/r128fb.c
diff -r1.1 -r1.2 src/sys/dev/pci/r128fbreg.h

cvs diff -r1.10 -r1.11 src/sys/dev/pci/r128fb.c (expand / switch to unified diff)

--- src/sys/dev/pci/r128fb.c 2009/10/01 19:02:27 1.10
+++ src/sys/dev/pci/r128fb.c 2010/09/09 01:22:11 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: r128fb.c,v 1.10 2009/10/01 19:02:27 jmmv Exp $ */ 1/* $NetBSD: r128fb.c,v 1.11 2010/09/09 01:22:11 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Michael Lorenz 4 * Copyright (c) 2007 Michael Lorenz
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/* 28/*
29 * A console driver for ATI Rage 128 graphics controllers 29 * A console driver for ATI Rage 128 graphics controllers
30 * tested on macppc only so far 30 * tested on macppc only so far
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.10 2009/10/01 19:02:27 jmmv Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.11 2010/09/09 01:22:11 macallan Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/malloc.h> 40#include <sys/malloc.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/kauth.h> 42#include <sys/kauth.h>
43 43
44#include <uvm/uvm_extern.h> 44#include <uvm/uvm_extern.h>
45 45
46#include <dev/videomode/videomode.h> 46#include <dev/videomode/videomode.h>
47 47
@@ -49,42 +49,50 @@ __KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1 @@ -49,42 +49,50 @@ __KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1
49#include <dev/pci/pcireg.h> 49#include <dev/pci/pcireg.h>
50#include <dev/pci/pcidevs.h> 50#include <dev/pci/pcidevs.h>
51#include <dev/pci/pciio.h> 51#include <dev/pci/pciio.h>
52#include <dev/pci/r128fbreg.h> 52#include <dev/pci/r128fbreg.h>
53 53
54#include <dev/wscons/wsdisplayvar.h> 54#include <dev/wscons/wsdisplayvar.h>
55#include <dev/wscons/wsconsio.h> 55#include <dev/wscons/wsconsio.h>
56#include <dev/wsfont/wsfont.h> 56#include <dev/wsfont/wsfont.h>
57#include <dev/rasops/rasops.h> 57#include <dev/rasops/rasops.h>
58#include <dev/wscons/wsdisplay_vconsvar.h> 58#include <dev/wscons/wsdisplay_vconsvar.h>
59 59
60#include <dev/i2c/i2cvar.h> 60#include <dev/i2c/i2cvar.h>
61 61
 62#include "opt_r128fb.h"
 63
 64#ifdef R128FB_DEBUG
 65#define DPRINTF printf
 66#else
 67#define DPRINTF while(0) printf
 68#endif
 69
62struct r128fb_softc { 70struct r128fb_softc {
63 device_t sc_dev; 71 device_t sc_dev;
64 72
65 pci_chipset_tag_t sc_pc; 73 pci_chipset_tag_t sc_pc;
66 pcitag_t sc_pcitag; 74 pcitag_t sc_pcitag;
67 75
68 bus_space_tag_t sc_memt; 76 bus_space_tag_t sc_memt;
69 bus_space_tag_t sc_iot; 77 bus_space_tag_t sc_iot;
70 78
71 bus_space_handle_t sc_fbh; 79 bus_space_handle_t sc_fbh;
72 bus_space_handle_t sc_regh; 80 bus_space_handle_t sc_regh;
73 bus_addr_t sc_fb, sc_reg; 81 bus_addr_t sc_fb, sc_reg;
74 bus_size_t sc_fbsize, sc_regsize; 82 bus_size_t sc_fbsize, sc_regsize;
75 83
76 int sc_width, sc_height, sc_depth, sc_stride; 84 int sc_width, sc_height, sc_depth, sc_stride;
77 int sc_locked; 85 int sc_locked, sc_have_backlight, sc_bl_level;
78 void *sc_fbaddr; 86 void *sc_fbaddr;
79 struct vcons_screen sc_console_screen; 87 struct vcons_screen sc_console_screen;
80 struct wsscreen_descr sc_defaultscreen_descr; 88 struct wsscreen_descr sc_defaultscreen_descr;
81 const struct wsscreen_descr *sc_screens[1]; 89 const struct wsscreen_descr *sc_screens[1];
82 struct wsscreen_list sc_screenlist; 90 struct wsscreen_list sc_screenlist;
83 struct vcons_data vd; 91 struct vcons_data vd;
84 int sc_mode; 92 int sc_mode;
85 u_char sc_cmap_red[256]; 93 u_char sc_cmap_red[256];
86 u_char sc_cmap_green[256]; 94 u_char sc_cmap_green[256];
87 u_char sc_cmap_blue[256]; 95 u_char sc_cmap_blue[256];
88 /* engine stuff */ 96 /* engine stuff */
89 uint32_t sc_master_cntl; 97 uint32_t sc_master_cntl;
90}; 98};
@@ -114,26 +122,30 @@ static void r128fb_rectfill(struct r128f @@ -114,26 +122,30 @@ static void r128fb_rectfill(struct r128f
114 uint32_t); 122 uint32_t);
115static void r128fb_bitblt(struct r128fb_softc *, int, int, int, int, int, 123static void r128fb_bitblt(struct r128fb_softc *, int, int, int, int, int,
116 int, int); 124 int, int);
117 125
118static void r128fb_cursor(void *, int, int, int); 126static void r128fb_cursor(void *, int, int, int);
119#if 0 127#if 0
120static void r128fb_putchar(void *, int, int, u_int, long); 128static void r128fb_putchar(void *, int, int, u_int, long);
121#endif 129#endif
122static void r128fb_copycols(void *, int, int, int, int); 130static void r128fb_copycols(void *, int, int, int, int);
123static void r128fb_erasecols(void *, int, int, int, long); 131static void r128fb_erasecols(void *, int, int, int, long);
124static void r128fb_copyrows(void *, int, int, int); 132static void r128fb_copyrows(void *, int, int, int);
125static void r128fb_eraserows(void *, int, int, long); 133static void r128fb_eraserows(void *, int, int, long);
126 134
 135static void r128fb_brightness_up(device_t);
 136static void r128fb_brightness_down(device_t);
 137static void r128fb_set_backlight(struct r128fb_softc *, int);
 138
127struct wsdisplay_accessops r128fb_accessops = { 139struct wsdisplay_accessops r128fb_accessops = {
128 r128fb_ioctl, 140 r128fb_ioctl,
129 r128fb_mmap, 141 r128fb_mmap,
130 NULL, /* alloc_screen */ 142 NULL, /* alloc_screen */
131 NULL, /* free_screen */ 143 NULL, /* free_screen */
132 NULL, /* show_screen */ 144 NULL, /* show_screen */
133 NULL, /* load_font */ 145 NULL, /* load_font */
134 NULL, /* pollc */ 146 NULL, /* pollc */
135 NULL /* scroll */ 147 NULL /* scroll */
136}; 148};
137 149
138static inline void 150static inline void
139r128fb_wait(struct r128fb_softc *sc, int slots) 151r128fb_wait(struct r128fb_softc *sc, int slots)
@@ -181,26 +193,27 @@ r128fb_match(device_t parent, cfdata_t m @@ -181,26 +193,27 @@ r128fb_match(device_t parent, cfdata_t m
181 193
182static void 194static void
183r128fb_attach(device_t parent, device_t self, void *aux) 195r128fb_attach(device_t parent, device_t self, void *aux)
184{ 196{
185 struct r128fb_softc *sc = device_private(self); 197 struct r128fb_softc *sc = device_private(self);
186 struct pci_attach_args *pa = aux; 198 struct pci_attach_args *pa = aux;
187 struct rasops_info *ri; 199 struct rasops_info *ri;
188 char devinfo[256]; 200 char devinfo[256];
189 struct wsemuldisplaydev_attach_args aa; 201 struct wsemuldisplaydev_attach_args aa;
190 prop_dictionary_t dict; 202 prop_dictionary_t dict;
191 unsigned long defattr; 203 unsigned long defattr;
192 bool is_console; 204 bool is_console;
193 int i, j; 205 int i, j;
 206 uint32_t reg;
194 207
195 sc->sc_pc = pa->pa_pc; 208 sc->sc_pc = pa->pa_pc;
196 sc->sc_pcitag = pa->pa_tag; 209 sc->sc_pcitag = pa->pa_tag;
197 sc->sc_memt = pa->pa_memt; 210 sc->sc_memt = pa->pa_memt;
198 sc->sc_iot = pa->pa_iot; 211 sc->sc_iot = pa->pa_iot;
199 sc->sc_dev = self; 212 sc->sc_dev = self;
200 213
201 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 214 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
202 aprint_normal(": %s\n", devinfo); 215 aprint_normal(": %s\n", devinfo);
203 216
204 /* fill in parameters from properties */ 217 /* fill in parameters from properties */
205 dict = device_properties(self); 218 dict = device_properties(self);
206 if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) { 219 if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
@@ -295,27 +308,41 @@ r128fb_attach(device_t parent, device_t  @@ -295,27 +308,41 @@ r128fb_attach(device_t parent, device_t
295 /* 308 /*
296 * since we're not the console we can postpone the rest 309 * since we're not the console we can postpone the rest
297 * until someone actually allocates a screen for us 310 * until someone actually allocates a screen for us
298 */ 311 */
299 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); 312 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
300 } 313 }
301 314
302 aa.console = is_console; 315 aa.console = is_console;
303 aa.scrdata = &sc->sc_screenlist; 316 aa.scrdata = &sc->sc_screenlist;
304 aa.accessops = &r128fb_accessops; 317 aa.accessops = &r128fb_accessops;
305 aa.accesscookie = &sc->vd; 318 aa.accesscookie = &sc->vd;
306 319
307 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); 320 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
308  321
 322 /* no suspend/resume support yet */
 323 pmf_device_register(sc->sc_dev, NULL, NULL);
 324 reg = bus_space_read_4(sc->sc_memt, sc->sc_regh, R128_LVDS_GEN_CNTL);
 325 DPRINTF("reg: %08x\n", reg);
 326 if (reg & R128_LVDS_ON) {
 327 sc->sc_have_backlight = 1;
 328 sc->sc_bl_level = 255 -
 329 ((reg & R128_LEVEL_MASK) >> R128_LEVEL_SHIFT);
 330 pmf_event_register(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_UP,
 331 r128fb_brightness_up, TRUE);
 332 pmf_event_register(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_DOWN,
 333 r128fb_brightness_down, TRUE);
 334 } else
 335 sc->sc_have_backlight = 0;
309} 336}
310 337
311static int 338static int
312r128fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 339r128fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
313 struct lwp *l) 340 struct lwp *l)
314{ 341{
315 struct vcons_data *vd = v; 342 struct vcons_data *vd = v;
316 struct r128fb_softc *sc = vd->cookie; 343 struct r128fb_softc *sc = vd->cookie;
317 struct wsdisplay_fbinfo *wdf; 344 struct wsdisplay_fbinfo *wdf;
318 struct vcons_screen *ms = vd->active; 345 struct vcons_screen *ms = vd->active;
319 346
320 switch (cmd) { 347 switch (cmd) {
321 348
@@ -777,13 +804,47 @@ r128fb_eraserows(void *cookie, int row,  @@ -777,13 +804,47 @@ r128fb_eraserows(void *cookie, int row,
777 int32_t x, y, width, height, fg, bg, ul; 804 int32_t x, y, width, height, fg, bg, ul;
778  805
779 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 806 if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
780 x = ri->ri_xorigin; 807 x = ri->ri_xorigin;
781 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 808 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
782 width = ri->ri_emuwidth; 809 width = ri->ri_emuwidth;
783 height = ri->ri_font->fontheight * nrows; 810 height = ri->ri_font->fontheight * nrows;
784 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 811 rasops_unpack_attr(fillattr, &fg, &bg, &ul);
785 812
786 r128fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 813 r128fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
787 } 814 }
788} 815}
789 816
 817static void
 818r128fb_set_backlight(struct r128fb_softc *sc, int level)
 819{
 820 uint32_t reg;
 821
 822 if (level > 255) level = 255;
 823 if (level < 0) level = 0;
 824 if (level == sc->sc_bl_level)
 825 return;
 826 sc->sc_bl_level = level;
 827 level = 255 - level;
 828 reg = bus_space_read_4(sc->sc_memt, sc->sc_regh, R128_LVDS_GEN_CNTL);
 829 reg &= ~R128_LEVEL_MASK;
 830 reg |= level << R128_LEVEL_SHIFT;
 831 bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_LVDS_GEN_CNTL, reg);
 832 DPRINTF("level: %d reg %08x\n", level, reg);
 833}
 834
 835
 836static void
 837r128fb_brightness_up(device_t dev)
 838{
 839 struct r128fb_softc *sc = device_private(dev);
 840
 841 r128fb_set_backlight(sc, sc->sc_bl_level + 8);
 842}
 843
 844static void
 845r128fb_brightness_down(device_t dev)
 846{
 847 struct r128fb_softc *sc = device_private(dev);
 848
 849 r128fb_set_backlight(sc, sc->sc_bl_level - 8);
 850}

cvs diff -r1.1 -r1.2 src/sys/dev/pci/r128fbreg.h (expand / switch to unified diff)

--- src/sys/dev/pci/r128fbreg.h 2007/11/07 19:09:09 1.1
+++ src/sys/dev/pci/r128fbreg.h 2010/09/09 01:22:10 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: r128fbreg.h,v 1.1 2007/11/07 19:09:09 macallan Exp $ */ 1/* $NetBSD: r128fbreg.h,v 1.2 2010/09/09 01:22:10 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, 4 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 * Precision Insight, Inc., Cedar Park, Texas, and 5 * Precision Insight, Inc., Cedar Park, Texas, and
6 * VA Linux Systems Inc., Fremont, California. 6 * VA Linux Systems Inc., Fremont, California.
7 * 7 *
8 * All Rights Reserved. 8 * All Rights Reserved.
9 * 9 *
10 * Permission is hereby granted, free of charge, to any person obtaining 10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the 11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including 12 * "Software"), to deal in the Software without restriction, including
13 * without limitation on the rights to use, copy, modify, merge, 13 * without limitation on the rights to use, copy, modify, merge,
14 * publish, distribute, sublicense, and/or sell copies of the Software, 14 * publish, distribute, sublicense, and/or sell copies of the Software,
@@ -45,29 +45,55 @@ @@ -45,29 +45,55 @@
45 * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. 45 * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
46 * 46 *
47 */ 47 */
48 48
49/* 49/*
50 * register definitions for ATI Rage 128 graphics controllers 50 * register definitions for ATI Rage 128 graphics controllers
51 * mostly from XFree86's ati driver 51 * mostly from XFree86's ati driver
52 */ 52 */
53  53
54 54
55#ifndef R128FB_REG_H 55#ifndef R128FB_REG_H
56#define R128FB_REG_H 56#define R128FB_REG_H
57 57
58#define R128_PALETTE_DATA 0x00b4 58/* RAMDAC */
59#define R128_PALETTE_INDEX 0x00b0 59#define R128_PALETTE_DATA 0x00b4
 60#define R128_PALETTE_INDEX 0x00b0
 61
 62/* flat panel registers */
 63#define R128_FP_PANEL_CNTL 0x0288
 64 #define FPCNT_DIGON 0x00000001 /* FP dig. voltage */
 65 #define FPCNT_BACKLIGHT_ON 0x00000002
 66 #define FPCNT_BL_MODULATION_ON 0x00000004
 67 #define FPCNT_BL_CLK_SEL 0x00000008 /* 1 - divide by 3 */
 68 #define FPCNT_MONID_EN 0x00000010 /* use MONID pins for
 69 backlight control */
 70 #define FPCNT_FPENABLE_POL 0x00000020 /* 1 - active low */
 71 #define FPCNT_LEVEL_MASK 0x0000ff00
 72 #define FPCNT_LEVEL_SHIFT 8
 73
 74#define R128_LVDS_GEN_CNTL 0x02d0
 75# define R128_LVDS_ON (1 << 0)
 76# define R128_LVDS_DISPLAY_DIS (1 << 1)
 77# define R128_LVDS_EN (1 << 7)
 78# define R128_LVDS_DIGON (1 << 18)
 79# define R128_LVDS_BLON (1 << 19)
 80# define R128_LVDS_SEL_CRTC2 (1 << 23)
 81# define R128_HSYNC_DELAY_SHIFT 28
 82# define R128_HSYNC_DELAY_MASK (0xf << 28)
 83# define R128_LEVEL_MASK 0x0000ff00
 84# define R128_LEVEL_SHIFT 8
60 85
 86/* drawing engine */
61#define R128_PC_NGUI_CTLSTAT 0x0184 87#define R128_PC_NGUI_CTLSTAT 0x0184
62# define R128_PC_FLUSH_GUI (3 << 0) 88# define R128_PC_FLUSH_GUI (3 << 0)
63# define R128_PC_RI_GUI (1 << 2) 89# define R128_PC_RI_GUI (1 << 2)
64# define R128_PC_FLUSH_ALL 0x00ff 90# define R128_PC_FLUSH_ALL 0x00ff
65# define R128_PC_BUSY (1 << 31) 91# define R128_PC_BUSY (1 << 31)
66 92
67#define R128_CRTC_OFFSET 0x0224 93#define R128_CRTC_OFFSET 0x0224
68 94
69#define R128_DST_OFFSET 0x1404 95#define R128_DST_OFFSET 0x1404
70#define R128_DST_PITCH 0x1408 96#define R128_DST_PITCH 0x1408
71 97
72#define R128_DP_GUI_MASTER_CNTL 0x146c 98#define R128_DP_GUI_MASTER_CNTL 0x146c
73# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) 99# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)