Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] DEC PMAG BA frame buffer update

Rewrite PMAG BA frame buffer driver for 2.6.

Acked-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Ralf Baechle and committed by
Linus Torvalds
af690a94 61838ffe

+204 -120
+182 -101
drivers/video/pmag-ba-fb.c
··· 1 1 /* 2 - * linux/drivers/video/pmag-ba-fb.c 2 + * linux/drivers/video/pmag-ba-fb.c 3 3 * 4 - * PMAG-BA TurboChannel framebuffer card support ... derived from: 4 + * PMAG-BA TURBOchannel Color Frame Buffer (CFB) card support, 5 + * derived from: 5 6 * "HP300 Topcat framebuffer support (derived from macfb of all things) 6 7 * Phil Blundell <philb@gnu.org> 1998", the original code can be 7 - * found in the file hpfb.c in the same directory. 8 + * found in the file hpfb.c in the same directory. 8 9 * 9 10 * Based on digital document: 10 11 * "PMAG-BA TURBOchannel Color Frame Buffer 11 12 * Functional Specification", Revision 1.2, August 27, 1990 12 13 * 13 - * DECstation related code Copyright (C) 1999, 2000, 2001 by 14 - * Michael Engel <engel@unix-ag.org>, 15 - * Karsten Merker <merker@linuxtag.org> and 14 + * DECstation related code Copyright (C) 1999, 2000, 2001 by 15 + * Michael Engel <engel@unix-ag.org>, 16 + * Karsten Merker <merker@linuxtag.org> and 16 17 * Harald Koerfgen. 17 - * This file is subject to the terms and conditions of the GNU General 18 - * Public License. See the file COPYING in the main directory of this 19 - * archive for more details. 18 + * Copyright (c) 2005 Maciej W. Rozycki 20 19 * 20 + * This file is subject to the terms and conditions of the GNU General 21 + * Public License. See the file COPYING in the main directory of this 22 + * archive for more details. 21 23 */ 22 - #include <linux/module.h> 23 - #include <linux/kernel.h> 24 - #include <linux/sched.h> 24 + 25 + #include <linux/compiler.h> 25 26 #include <linux/errno.h> 26 - #include <linux/string.h> 27 - #include <linux/timer.h> 28 - #include <linux/mm.h> 29 - #include <linux/tty.h> 30 - #include <linux/slab.h> 31 - #include <linux/delay.h> 32 - #include <linux/init.h> 33 27 #include <linux/fb.h> 34 - #include <asm/bootinfo.h> 35 - #include <asm/dec/machtype.h> 28 + #include <linux/init.h> 29 + #include <linux/kernel.h> 30 + #include <linux/module.h> 31 + #include <linux/types.h> 32 + 33 + #include <asm/bug.h> 34 + #include <asm/io.h> 35 + #include <asm/system.h> 36 + 36 37 #include <asm/dec/tc.h> 38 + 37 39 #include <video/pmag-ba-fb.h> 38 40 39 - struct pmag_ba_ramdac_regs { 40 - unsigned char addr_low; 41 - unsigned char pad0[3]; 42 - unsigned char addr_hi; 43 - unsigned char pad1[3]; 44 - unsigned char data; 45 - unsigned char pad2[3]; 46 - unsigned char cmap; 41 + 42 + struct pmagbafb_par { 43 + struct fb_info *next; 44 + volatile void __iomem *mmio; 45 + volatile u32 __iomem *dac; 46 + int slot; 47 47 }; 48 48 49 - /* 50 - * Max 3 TURBOchannel slots -> max 3 PMAG-BA :) 51 - */ 52 - static struct fb_info pmagba_fb_info[3]; 53 49 54 - static struct fb_var_screeninfo pmagbafb_defined = { 50 + static struct fb_info *root_pmagbafb_dev; 51 + 52 + static struct fb_var_screeninfo pmagbafb_defined __initdata = { 55 53 .xres = 1024, 56 54 .yres = 864, 57 55 .xres_virtual = 1024, ··· 59 61 .green.length = 8, 60 62 .blue.length = 8, 61 63 .activate = FB_ACTIVATE_NOW, 62 - .height = 274, 63 - .width = 195, 64 - .accel = FB_ACCEL_NONE, 64 + .height = -1, 65 + .width = -1, 66 + .accel_flags = FB_ACCEL_NONE, 67 + .pixclock = 14452, 68 + .left_margin = 116, 69 + .right_margin = 12, 70 + .upper_margin = 34, 71 + .lower_margin = 12, 72 + .hsync_len = 128, 73 + .vsync_len = 3, 74 + .sync = FB_SYNC_ON_GREEN, 65 75 .vmode = FB_VMODE_NONINTERLACED, 66 76 }; 67 77 68 - static struct fb_fix_screeninfo pmagbafb_fix = { 78 + static struct fb_fix_screeninfo pmagbafb_fix __initdata = { 69 79 .id = "PMAG-BA", 70 - .smem_len = (1024 * 864), 80 + .smem_len = (1024 * 1024), 71 81 .type = FB_TYPE_PACKED_PIXELS, 72 82 .visual = FB_VISUAL_PSEUDOCOLOR, 73 83 .line_length = 1024, 84 + .mmio_len = PMAG_BA_SIZE - PMAG_BA_BT459, 74 85 }; 75 86 76 - /* 77 - * Turn hardware cursor off 78 - */ 79 - void pmagbafb_erase_cursor(struct pmag_ba_ramdac_regs *bt459_regs) 87 + 88 + static inline void dac_write(struct pmagbafb_par *par, unsigned int reg, u8 v) 80 89 { 81 - bt459_regs->addr_low = 0; 82 - bt459_regs->addr_hi = 3; 83 - bt459_regs->data = 0; 90 + writeb(v, par->dac + reg / 4); 84 91 } 85 92 86 - /* 87 - * Set the palette. 88 - */ 89 - static int pmagbafb_setcolreg(unsigned regno, unsigned red, unsigned green, 90 - unsigned blue, unsigned transp, 91 - struct fb_info *info) 93 + static inline u8 dac_read(struct pmagbafb_par *par, unsigned int reg) 92 94 { 93 - struct pmag_ba_ramdac_regs *bt459_regs = (struct pmag_ba_ramdac_regs *) info->par; 95 + return readb(par->dac + reg / 4); 96 + } 94 97 95 - if (regno >= info->cmap.len) 96 - return 1; 98 + 99 + /* 100 + * Set the palette. 101 + */ 102 + static int pmagbafb_setcolreg(unsigned int regno, unsigned int red, 103 + unsigned int green, unsigned int blue, 104 + unsigned int transp, struct fb_info *info) 105 + { 106 + struct pmagbafb_par *par = info->par; 107 + 108 + BUG_ON(regno >= info->cmap.len); 97 109 98 110 red >>= 8; /* The cmap fields are 16 bits */ 99 - green >>= 8; /* wide, but the harware colormap */ 111 + green >>= 8; /* wide, but the hardware colormap */ 100 112 blue >>= 8; /* registers are only 8 bits wide */ 101 113 102 - bt459_regs->addr_low = (__u8) regno; 103 - bt459_regs->addr_hi = 0; 104 - bt459_regs->cmap = red; 105 - bt459_regs->cmap = green; 106 - bt459_regs->cmap = blue; 114 + mb(); 115 + dac_write(par, BT459_ADDR_LO, regno); 116 + dac_write(par, BT459_ADDR_HI, 0x00); 117 + wmb(); 118 + dac_write(par, BT459_CMAP, red); 119 + wmb(); 120 + dac_write(par, BT459_CMAP, green); 121 + wmb(); 122 + dac_write(par, BT459_CMAP, blue); 123 + 107 124 return 0; 108 125 } 109 126 110 127 static struct fb_ops pmagbafb_ops = { 111 128 .owner = THIS_MODULE, 112 - .fb_get_fix = gen_get_fix, 113 - .fb_get_var = gen_get_var, 114 129 .fb_setcolreg = pmagbafb_setcolreg, 115 130 .fb_fillrect = cfb_fillrect, 116 131 .fb_copyarea = cfb_copyarea, ··· 131 120 .fb_cursor = soft_cursor, 132 121 }; 133 122 134 - int __init pmagbafb_init_one(int slot) 123 + 124 + /* 125 + * Turn the hardware cursor off. 126 + */ 127 + static void __init pmagbafb_erase_cursor(struct fb_info *info) 135 128 { 136 - unsigned long base_addr = get_tc_base_addr(slot); 137 - struct fb_info *info = &pmagba_fb_info[slot]; 138 - struct display *disp = &pmagba_disp[slot]; 129 + struct pmagbafb_par *par = info->par; 139 130 140 - printk("PMAG-BA framebuffer in slot %d\n", slot); 141 - /* 142 - * Framebuffer display memory base address and friends 143 - */ 144 - pmagbafb_fix.smem_start = base_addr + PMAG_BA_ONBOARD_FBMEM_OFFSET; 145 - info->par = (base_addr + PMAG_BA_BT459_OFFSET); 131 + mb(); 132 + dac_write(par, BT459_ADDR_LO, 0x00); 133 + dac_write(par, BT459_ADDR_HI, 0x03); 134 + wmb(); 135 + dac_write(par, BT459_DATA, 0x00); 136 + } 146 137 147 - /* 148 - * Configure the Bt459 RAM DAC 149 - */ 150 - pmagbafb_erase_cursor((struct pmag_ba_ramdac_regs *) info->par); 151 138 152 - /* 153 - * Let there be consoles.. 154 - */ 139 + static int __init pmagbafb_init_one(int slot) 140 + { 141 + struct fb_info *info; 142 + struct pmagbafb_par *par; 143 + unsigned long base_addr; 144 + 145 + info = framebuffer_alloc(sizeof(struct pmagbafb_par), NULL); 146 + if (!info) 147 + return -ENOMEM; 148 + 149 + par = info->par; 150 + par->slot = slot; 151 + claim_tc_card(par->slot); 152 + 153 + base_addr = get_tc_base_addr(par->slot); 154 + 155 + par->next = root_pmagbafb_dev; 156 + root_pmagbafb_dev = info; 157 + 158 + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 159 + goto err_alloc; 160 + 155 161 info->fbops = &pmagbafb_ops; 162 + info->fix = pmagbafb_fix; 156 163 info->var = pmagbafb_defined; 157 - info->fix = pmagbafb_fix; 158 - info->screen_base = pmagbafb_fix.smem_start; 159 164 info->flags = FBINFO_DEFAULT; 160 165 161 - fb_alloc_cmap(&fb_info.cmap, 256, 0); 166 + /* MMIO mapping setup. */ 167 + info->fix.mmio_start = base_addr; 168 + par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 169 + if (!par->mmio) 170 + goto err_cmap; 171 + par->dac = par->mmio + PMAG_BA_BT459; 172 + 173 + /* Frame buffer mapping setup. */ 174 + info->fix.smem_start = base_addr + PMAG_BA_FBMEM; 175 + info->screen_base = ioremap_nocache(info->fix.smem_start, 176 + info->fix.smem_len); 177 + if (!info->screen_base) 178 + goto err_mmio_map; 179 + info->screen_size = info->fix.smem_len; 180 + 181 + pmagbafb_erase_cursor(info); 162 182 163 183 if (register_framebuffer(info) < 0) 164 - return 1; 184 + goto err_smem_map; 185 + 186 + pr_info("fb%d: %s frame buffer device in slot %d\n", 187 + info->node, info->fix.id, par->slot); 188 + 165 189 return 0; 190 + 191 + 192 + err_smem_map: 193 + iounmap(info->screen_base); 194 + 195 + err_mmio_map: 196 + iounmap(par->mmio); 197 + 198 + err_cmap: 199 + fb_dealloc_cmap(&info->cmap); 200 + 201 + err_alloc: 202 + root_pmagbafb_dev = par->next; 203 + release_tc_card(par->slot); 204 + framebuffer_release(info); 205 + return -ENXIO; 166 206 } 167 207 168 - /* 169 - * Initialise the framebuffer 170 - */ 171 - 172 - int __init pmagbafb_init(void) 208 + static void __exit pmagbafb_exit_one(void) 173 209 { 174 - int sid; 175 - int found = 0; 210 + struct fb_info *info = root_pmagbafb_dev; 211 + struct pmagbafb_par *par = info->par; 212 + 213 + unregister_framebuffer(info); 214 + iounmap(info->screen_base); 215 + iounmap(par->mmio); 216 + fb_dealloc_cmap(&info->cmap); 217 + root_pmagbafb_dev = par->next; 218 + release_tc_card(par->slot); 219 + framebuffer_release(info); 220 + } 221 + 222 + 223 + /* 224 + * Initialise the framebuffer. 225 + */ 226 + static int __init pmagbafb_init(void) 227 + { 228 + int count = 0; 229 + int slot; 176 230 177 231 if (fb_get_options("pmagbafb", NULL)) 178 - return -ENODEV; 232 + return -ENXIO; 179 233 180 - if (TURBOCHANNEL) { 181 - while ((sid = search_tc_card("PMAG-BA")) >= 0) { 182 - found = 1; 183 - claim_tc_card(sid); 184 - pmagbafb_init_one(sid); 185 - } 186 - return found ? 0 : -ENODEV; 187 - } else { 188 - return -ENODEV; 234 + while ((slot = search_tc_card("PMAG-BA")) >= 0) { 235 + if (pmagbafb_init_one(slot) < 0) 236 + break; 237 + count++; 189 238 } 239 + return (count > 0) ? 0 : -ENXIO; 190 240 } 191 241 242 + static void __exit pmagbafb_exit(void) 243 + { 244 + while (root_pmagbafb_dev) 245 + pmagbafb_exit_one(); 246 + } 247 + 248 + 192 249 module_init(pmagbafb_init); 250 + module_exit(pmagbafb_exit); 251 + 193 252 MODULE_LICENSE("GPL");
+22 -19
include/video/pmag-ba-fb.h
··· 1 1 /* 2 - * linux/drivers/video/pmag-ba-fb.h 2 + * linux/include/video/pmag-ba-fb.h 3 3 * 4 - * TurboChannel PMAG-BA framebuffer card support, 5 - * Copyright (C) 1999,2000,2001 by 6 - * Michael Engel <engel@unix-ag.org>, 7 - * Karsten Merker <merker@linuxtag.org> 8 - * This file is subject to the terms and conditions of the GNU General 9 - * Public License. See the file COPYING in the main directory of this 10 - * archive for more details. 4 + * TURBOchannel PMAG-BA Color Frame Buffer (CFB) card support, 5 + * Copyright (C) 1999, 2000, 2001 by 6 + * Michael Engel <engel@unix-ag.org>, 7 + * Karsten Merker <merker@linuxtag.org> 8 + * Copyright (c) 2005 Maciej W. Rozycki 9 + * 10 + * This file is subject to the terms and conditions of the GNU General 11 + * Public License. See the file COPYING in the main directory of this 12 + * archive for more details. 11 13 */ 12 14 13 - /* 14 - * Bt459 RAM DAC register base offset (rel. to TC slot base address) 15 - */ 15 + /* IOmem resource offsets. */ 16 + #define PMAG_BA_FBMEM 0x000000 /* frame buffer */ 17 + #define PMAG_BA_BT459 0x200000 /* Bt459 RAMDAC */ 18 + #define PMAG_BA_IRQ 0x300000 /* IRQ acknowledge */ 19 + #define PMAG_BA_ROM 0x380000 /* REX option ROM */ 20 + #define PMAG_BA_BT438 0x380000 /* Bt438 clock chip reset */ 21 + #define PMAG_BA_SIZE 0x400000 /* address space size */ 16 22 17 - #define PMAG_BA_BT459_OFFSET 0x00200000 18 - 19 - /* 20 - * Begin of PMAG-BA framebuffer memory relative to TC slot address, 21 - * resolution is 1024x864x8 22 - */ 23 - 24 - #define PMAG_BA_ONBOARD_FBMEM_OFFSET 0x00000000 23 + /* Bt459 register offsets, byte-wide registers. */ 24 + #define BT459_ADDR_LO 0x0 /* address low */ 25 + #define BT459_ADDR_HI 0x4 /* address high */ 26 + #define BT459_DATA 0x8 /* data window register */ 27 + #define BT459_CMAP 0xc /* color map window register */