aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
commit06b8147c5dbd385b5b97ca74e19f6f3951ebc1cb (patch)
tree6ed9de7ca0ab3a65af6a189a89deb0a36ab35f6b /drivers/video
parent53baaaa9682c230410a057263d1ce2922f43ddc4 (diff)
parent8725f25acc656c1522d48a6746055099efdaca4c (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (49 commits) powerpc: Fix build bug with binutils < 2.18 and GCC < 4.2 powerpc/eeh: Don't panic when EEH_MAX_FAILS is exceeded fbdev: Teaches offb about palette on radeon r5xx/r6xx powerpc/cell/edac: Log a syndrome code in case of correctable error powerpc/cell: Add DMA_ATTR_WEAK_ORDERING dma attribute and use in Cell IOMMU code powerpc: Indicate which oprofile counters to use while in compat mode powerpc/boot: Change spaces to tabs powerpc: Remove duplicate 6xx option in Kconfig powerpc: Use PPC_LONG and PPC_LONG_ALIGN in lib/string.S powerpc: Use PPC_LONG_ALIGN in uaccess.h powerpc: Add a #define for aligning to a long-sized boundary powerpc: Fix OF parsing of 64 bits PCI addresses powerpc: Use WARN_ON(1) instead of __WARN() powerpc: Fix support for latencytop powerpc/ps3: Update ps3_defconfig powerpc/ps3: Add a sub-match id to ps3_system_bus powerpc: Add a 6xx defconfig powerpc/dma: Use the struct dma_attrs in iommu code powerpc/cell: Add support for power button of future IBM cell blades powerpc/cell: Cleanup sysreset_hack for IBM cell blades ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/offb.c192
-rw-r--r--drivers/video/ps3fb.c1
2 files changed, 143 insertions, 50 deletions
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index d7b3dcc0dc43..e1d9eeb1aeaf 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -47,6 +47,7 @@ enum {
47 cmap_M3B, /* ATI Rage Mobility M3 Head B */ 47 cmap_M3B, /* ATI Rage Mobility M3 Head B */
48 cmap_radeon, /* ATI Radeon */ 48 cmap_radeon, /* ATI Radeon */
49 cmap_gxt2000, /* IBM GXT2000 */ 49 cmap_gxt2000, /* IBM GXT2000 */
50 cmap_avivo, /* ATI R5xx */
50}; 51};
51 52
52struct offb_par { 53struct offb_par {
@@ -58,26 +59,36 @@ struct offb_par {
58 59
59struct offb_par default_par; 60struct offb_par default_par;
60 61
61 /*
62 * Interface used by the world
63 */
64
65static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
66 u_int transp, struct fb_info *info);
67static int offb_blank(int blank, struct fb_info *info);
68
69#ifdef CONFIG_PPC32 62#ifdef CONFIG_PPC32
70extern boot_infos_t *boot_infos; 63extern boot_infos_t *boot_infos;
71#endif 64#endif
72 65
73static struct fb_ops offb_ops = { 66/* Definitions used by the Avivo palette hack */
74 .owner = THIS_MODULE, 67#define AVIVO_DC_LUT_RW_SELECT 0x6480
75 .fb_setcolreg = offb_setcolreg, 68#define AVIVO_DC_LUT_RW_MODE 0x6484
76 .fb_blank = offb_blank, 69#define AVIVO_DC_LUT_RW_INDEX 0x6488
77 .fb_fillrect = cfb_fillrect, 70#define AVIVO_DC_LUT_SEQ_COLOR 0x648c
78 .fb_copyarea = cfb_copyarea, 71#define AVIVO_DC_LUT_PWL_DATA 0x6490
79 .fb_imageblit = cfb_imageblit, 72#define AVIVO_DC_LUT_30_COLOR 0x6494
80}; 73#define AVIVO_DC_LUT_READ_PIPE_SELECT 0x6498
74#define AVIVO_DC_LUT_WRITE_EN_MASK 0x649c
75#define AVIVO_DC_LUT_AUTOFILL 0x64a0
76
77#define AVIVO_DC_LUTA_CONTROL 0x64c0
78#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4
79#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN 0x64c8
80#define AVIVO_DC_LUTA_BLACK_OFFSET_RED 0x64cc
81#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0
82#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4
83#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
84
85#define AVIVO_DC_LUTB_CONTROL 0x6cc0
86#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE 0x6cc4
87#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN 0x6cc8
88#define AVIVO_DC_LUTB_BLACK_OFFSET_RED 0x6ccc
89#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE 0x6cd0
90#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN 0x6cd4
91#define AVIVO_DC_LUTB_WHITE_OFFSET_RED 0x6cd8
81 92
82 /* 93 /*
83 * Set a single color register. The values supplied are already 94 * Set a single color register. The values supplied are already
@@ -160,6 +171,17 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
160 out_le32(((unsigned __iomem *) par->cmap_adr) + regno, 171 out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
161 (red << 16 | green << 8 | blue)); 172 (red << 16 | green << 8 | blue));
162 break; 173 break;
174 case cmap_avivo:
175 /* Write to both LUTs for now */
176 writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
177 writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
178 writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
179 par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
180 writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
181 writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
182 writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
183 par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
184 break;
163 } 185 }
164 186
165 return 0; 187 return 0;
@@ -216,12 +238,59 @@ static int offb_blank(int blank, struct fb_info *info)
216 out_le32(((unsigned __iomem *) par->cmap_adr) + i, 238 out_le32(((unsigned __iomem *) par->cmap_adr) + i,
217 0); 239 0);
218 break; 240 break;
241 case cmap_avivo:
242 writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
243 writeb(i, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
244 writel(0, par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
245 writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
246 writeb(i, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
247 writel(0, par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
248 break;
219 } 249 }
220 } else 250 } else
221 fb_set_cmap(&info->cmap, info); 251 fb_set_cmap(&info->cmap, info);
222 return 0; 252 return 0;
223} 253}
224 254
255static int offb_set_par(struct fb_info *info)
256{
257 struct offb_par *par = (struct offb_par *) info->par;
258
259 /* On avivo, initialize palette control */
260 if (par->cmap_type == cmap_avivo) {
261 writel(0, par->cmap_adr + AVIVO_DC_LUTA_CONTROL);
262 writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_BLUE);
263 writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_GREEN);
264 writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_RED);
265 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_BLUE);
266 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_GREEN);
267 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_RED);
268 writel(0, par->cmap_adr + AVIVO_DC_LUTB_CONTROL);
269 writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_BLUE);
270 writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_GREEN);
271 writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_RED);
272 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_BLUE);
273 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_GREEN);
274 writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_RED);
275 writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
276 writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
277 writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
278 writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
279 writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
280 writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
281 }
282 return 0;
283}
284
285static struct fb_ops offb_ops = {
286 .owner = THIS_MODULE,
287 .fb_setcolreg = offb_setcolreg,
288 .fb_set_par = offb_set_par,
289 .fb_blank = offb_blank,
290 .fb_fillrect = cfb_fillrect,
291 .fb_copyarea = cfb_copyarea,
292 .fb_imageblit = cfb_imageblit,
293};
225 294
226static void __iomem *offb_map_reg(struct device_node *np, int index, 295static void __iomem *offb_map_reg(struct device_node *np, int index,
227 unsigned long offset, unsigned long size) 296 unsigned long offset, unsigned long size)
@@ -245,6 +314,59 @@ static void __iomem *offb_map_reg(struct device_node *np, int index,
245 return ioremap(taddr + offset, size); 314 return ioremap(taddr + offset, size);
246} 315}
247 316
317static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp,
318 const char *name, unsigned long address)
319{
320 struct offb_par *par = (struct offb_par *) info->par;
321
322 if (dp && !strncmp(name, "ATY,Rage128", 11)) {
323 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
324 if (par->cmap_adr)
325 par->cmap_type = cmap_r128;
326 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
327 || !strncmp(name, "ATY,RageM3p12A", 14))) {
328 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
329 if (par->cmap_adr)
330 par->cmap_type = cmap_M3A;
331 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
332 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
333 if (par->cmap_adr)
334 par->cmap_type = cmap_M3B;
335 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
336 par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
337 if (par->cmap_adr)
338 par->cmap_type = cmap_radeon;
339 } else if (!strncmp(name, "ATY,", 4)) {
340 unsigned long base = address & 0xff000000UL;
341 par->cmap_adr =
342 ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
343 par->cmap_data = par->cmap_adr + 1;
344 par->cmap_type = cmap_m64;
345 } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
346 of_device_is_compatible(dp, "pci1014,21c"))) {
347 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
348 if (par->cmap_adr)
349 par->cmap_type = cmap_gxt2000;
350 } else if (dp && !strncmp(name, "vga,Display-", 12)) {
351 /* Look for AVIVO initialized by SLOF */
352 struct device_node *pciparent = of_get_parent(dp);
353 const u32 *vid, *did;
354 vid = of_get_property(pciparent, "vendor-id", NULL);
355 did = of_get_property(pciparent, "device-id", NULL);
356 /* This will match most R5xx */
357 if (vid && did && *vid == 0x1002 &&
358 ((*did >= 0x7100 && *did < 0x7800) ||
359 (*did >= 0x9400))) {
360 par->cmap_adr = offb_map_reg(pciparent, 2, 0, 0x10000);
361 if (par->cmap_adr)
362 par->cmap_type = cmap_avivo;
363 }
364 of_node_put(pciparent);
365 }
366 info->fix.visual = (par->cmap_type != cmap_unknown) ?
367 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
368}
369
248static void __init offb_init_fb(const char *name, const char *full_name, 370static void __init offb_init_fb(const char *name, const char *full_name,
249 int width, int height, int depth, 371 int width, int height, int depth,
250 int pitch, unsigned long address, 372 int pitch, unsigned long address,
@@ -283,6 +405,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
283 405
284 fix = &info->fix; 406 fix = &info->fix;
285 var = &info->var; 407 var = &info->var;
408 info->par = par;
286 409
287 strcpy(fix->id, "OFfb "); 410 strcpy(fix->id, "OFfb ");
288 strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb ")); 411 strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
@@ -298,39 +421,9 @@ static void __init offb_init_fb(const char *name, const char *full_name,
298 fix->type_aux = 0; 421 fix->type_aux = 0;
299 422
300 par->cmap_type = cmap_unknown; 423 par->cmap_type = cmap_unknown;
301 if (depth == 8) { 424 if (depth == 8)
302 if (dp && !strncmp(name, "ATY,Rage128", 11)) { 425 offb_init_palette_hacks(info, dp, name, address);
303 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); 426 else
304 if (par->cmap_adr)
305 par->cmap_type = cmap_r128;
306 } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
307 || !strncmp(name, "ATY,RageM3p12A", 14))) {
308 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
309 if (par->cmap_adr)
310 par->cmap_type = cmap_M3A;
311 } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
312 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
313 if (par->cmap_adr)
314 par->cmap_type = cmap_M3B;
315 } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
316 par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
317 if (par->cmap_adr)
318 par->cmap_type = cmap_radeon;
319 } else if (!strncmp(name, "ATY,", 4)) {
320 unsigned long base = address & 0xff000000UL;
321 par->cmap_adr =
322 ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
323 par->cmap_data = par->cmap_adr + 1;
324 par->cmap_type = cmap_m64;
325 } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
326 of_device_is_compatible(dp, "pci1014,21c"))) {
327 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
328 if (par->cmap_adr)
329 par->cmap_type = cmap_gxt2000;
330 }
331 fix->visual = (par->cmap_type != cmap_unknown) ?
332 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
333 } else
334 fix->visual = FB_VISUAL_TRUECOLOR; 427 fix->visual = FB_VISUAL_TRUECOLOR;
335 428
336 var->xoffset = var->yoffset = 0; 429 var->xoffset = var->yoffset = 0;
@@ -395,7 +488,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
395 488
396 info->fbops = &offb_ops; 489 info->fbops = &offb_ops;
397 info->screen_base = ioremap(address, fix->smem_len); 490 info->screen_base = ioremap(address, fix->smem_len);
398 info->par = par;
399 info->pseudo_palette = (void *) (info + 1); 491 info->pseudo_palette = (void *) (info + 1);
400 info->flags = FBINFO_DEFAULT | foreign_endian; 492 info->flags = FBINFO_DEFAULT | foreign_endian;
401 493
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index dc3af1c78c56..4b5d80771904 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1297,6 +1297,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1297 1297
1298static struct ps3_system_bus_driver ps3fb_driver = { 1298static struct ps3_system_bus_driver ps3fb_driver = {
1299 .match_id = PS3_MATCH_ID_GRAPHICS, 1299 .match_id = PS3_MATCH_ID_GRAPHICS,
1300 .match_sub_id = PS3_MATCH_SUB_ID_FB,
1300 .core.name = DEVICE_NAME, 1301 .core.name = DEVICE_NAME,
1301 .core.owner = THIS_MODULE, 1302 .core.owner = THIS_MODULE,
1302 .probe = ps3fb_probe, 1303 .probe = ps3fb_probe,