Commit d190c5ba authored by David Eger's avatar David Eger Committed by Linus Torvalds

[PATCH] cirrusfb: update for amiga (zorro)

Cirrusfb updates:
  - Cirrusfb depends on Zorro or PCI
  - Revive Zorro support, using new Zorro driver framework
  - Merge PCI and Zorro code where possible
  - Use C99 initializers
  - Kill superfluous whitespace
  - #undef I/O ops before redefining them on Amiga

From: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarDavid Eger <eger@havoc.gtf.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d9dfcd12
...@@ -40,7 +40,7 @@ config FB ...@@ -40,7 +40,7 @@ config FB
config FB_CIRRUS config FB_CIRRUS
tristate "Cirrus Logic support" tristate "Cirrus Logic support"
depends on FB && (AMIGA || PCI) depends on FB && (ZORRO || PCI)
---help--- ---help---
This enables support for Cirrus Logic GD542x/543x based boards on This enables support for Cirrus Logic GD542x/543x based boards on
Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
......
...@@ -145,9 +145,6 @@ typedef enum { ...@@ -145,9 +145,6 @@ typedef enum {
* a run-time table? * a run-time table?
*/ */
static const struct cirrusfb_board_info_rec { static const struct cirrusfb_board_info_rec {
cirrusfb_board_t btype; /* chipset enum, not strictly necessary, as
* cirrusfb_board_info[] is directly indexed
* by this value */
char *name; /* ASCII name of chipset */ char *name; /* ASCII name of chipset */
long maxclock[5]; /* maximum video clock */ long maxclock[5]; /* maximum video clock */
/* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
...@@ -164,104 +161,115 @@ static const struct cirrusfb_board_info_rec { ...@@ -164,104 +161,115 @@ static const struct cirrusfb_board_info_rec {
unsigned char sr1f; /* SR1F VGA initial register value */ unsigned char sr1f; /* SR1F VGA initial register value */
} cirrusfb_board_info[] = { } cirrusfb_board_info[] = {
{ BT_NONE, }, /* dummy record */ [BT_SD64] = {
{ BT_SD64, .name = "CL SD64",
"CL SD64", .maxclock = {
{ 140000, 140000, 140000, 140000, 140000, }, /* guess */ /* guess */
/* the SD64/P4 have a higher max. videoclock */ /* the SD64/P4 have a higher max. videoclock */
TRUE, 140000, 140000, 140000, 140000, 140000,
TRUE, },
TRUE, .init_sr07 = TRUE,
0xF0, .init_sr1f = TRUE,
0xF0, .scrn_start_bit19 = TRUE,
0, /* unused, does not multiplex */ .sr07 = 0xF0,
0xF1, .sr07_1bpp = 0xF0,
0, /* unused, does not multiplex */ .sr07_8bpp = 0xF1,
0x20 }, .sr1f = 0x20
{ BT_PICCOLO, },
"CL Piccolo", [BT_PICCOLO] = {
{ 90000, 90000, 90000, 90000, 90000 }, /* guess */ .name = "CL Piccolo",
TRUE, .maxclock = {
TRUE, /* guess */
FALSE, 90000, 90000, 90000, 90000, 90000
0x80, },
0x80, .init_sr07 = TRUE,
0, /* unused, does not multiplex */ .init_sr1f = TRUE,
0x81, .scrn_start_bit19 = FALSE,
0, /* unused, does not multiplex */ .sr07 = 0x80,
0x22 }, .sr07_1bpp = 0x80,
{ BT_PICASSO, .sr07_8bpp = 0x81,
"CL Picasso", .sr1f = 0x22
{ 90000, 90000, 90000, 90000, 90000, }, /* guess */ },
TRUE, [BT_PICASSO] = {
TRUE, .name = "CL Picasso",
FALSE, .maxclock = {
0x20, /* guess */
0x20, 90000, 90000, 90000, 90000, 90000
0, /* unused, does not multiplex */ },
0x21, .init_sr07 = TRUE,
0, /* unused, does not multiplex */ .init_sr1f = TRUE,
0x22 }, .scrn_start_bit19 = FALSE,
{ BT_SPECTRUM, .sr07 = 0x20,
"CL Spectrum", .sr07_1bpp = 0x20,
{ 90000, 90000, 90000, 90000, 90000, }, /* guess */ .sr07_8bpp = 0x21,
TRUE, .sr1f = 0x22
TRUE, },
FALSE, [BT_SPECTRUM] = {
0x80, .name = "CL Spectrum",
0x80, .maxclock = {
0, /* unused, does not multiplex */ /* guess */
0x81, 90000, 90000, 90000, 90000, 90000
0, /* unused, does not multiplex */ },
0x22 }, .init_sr07 = TRUE,
{ BT_PICASSO4, .init_sr1f = TRUE,
"CL Picasso4", .scrn_start_bit19 = FALSE,
{ 135100, 135100, 85500, 85500, 0 }, .sr07 = 0x80,
TRUE, .sr07_1bpp = 0x80,
FALSE, .sr07_8bpp = 0x81,
TRUE, .sr1f = 0x22
0x20, },
0x20, [BT_PICASSO4] = {
0, /* unused, does not multiplex */ .name = "CL Picasso4",
0x21, .maxclock = {
0, /* unused, does not multiplex */ 135100, 135100, 85500, 85500, 0
0 }, },
{ BT_ALPINE, .init_sr07 = TRUE,
"CL Alpine", .init_sr1f = FALSE,
{ 85500, 85500, 50000, 28500, 0}, /* for the GD5430. GD5446 can do more... */ .scrn_start_bit19 = TRUE,
TRUE, .sr07 = 0x20,
TRUE, .sr07_1bpp = 0x20,
TRUE, .sr07_8bpp = 0x21,
0xA0, .sr1f = 0
0xA1, },
0xA7, [BT_ALPINE] = {
0xA1, .name = "CL Alpine",
0xA7, .maxclock = {
0x1C }, /* for the GD5430. GD5446 can do more... */
{ BT_GD5480, 85500, 85500, 50000, 28500, 0
"CL GD5480", },
{ 135100, 200000, 200000, 135100, 135100 }, .init_sr07 = TRUE,
TRUE, .init_sr1f = TRUE,
TRUE, .scrn_start_bit19 = TRUE,
TRUE, .sr07 = 0xA0,
0x10, .sr07_1bpp = 0xA1,
0x11, .sr07_1bpp_mux = 0xA7,
0, /* unused, does not multiplex */ .sr07_8bpp = 0xA1,
0x11, .sr07_8bpp_mux = 0xA7,
0, /* unused, does not multiplex */ .sr1f = 0x1C
0x1C }, },
{ BT_LAGUNA, [BT_GD5480] = {
"CL Laguna", .name = "CL GD5480",
{ 135100, 135100, 135100, 135100, 135100, }, /* guess */ .maxclock = {
FALSE, 135100, 200000, 200000, 135100, 135100
FALSE, },
TRUE, .init_sr07 = TRUE,
0, /* unused */ .init_sr1f = TRUE,
0, /* unused */ .scrn_start_bit19 = TRUE,
0, /* unused */ .sr07 = 0x10,
0, /* unused */ .sr07_1bpp = 0x11,
0, /* unused */ .sr07_8bpp = 0x11,
0 }, /* unused */ .sr1f = 0x1C
},
[BT_LAGUNA] = {
.name = "CL Laguna",
.maxclock = {
/* guess */
135100, 135100, 135100, 135100, 135100,
},
.init_sr07 = FALSE,
.init_sr1f = FALSE,
.scrn_start_bit19 = TRUE,
}
}; };
...@@ -289,31 +297,50 @@ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); ...@@ -289,31 +297,50 @@ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
#ifdef CONFIG_ZORRO #ifdef CONFIG_ZORRO
static const struct zorro_device_id cirrusfb_zorro_table[] = {
{
.id = ZORRO_PROD_HELFRICH_SD64_RAM,
.driver_data = BT_SD64,
}, {
.id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
.driver_data = BT_PICCOLO,
}, {
.id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
.driver_data = BT_PICASSO,
}, {
.id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
.driver_data = BT_SPECTRUM,
}, {
.id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
.driver_data = BT_PICASSO4,
},
{ 0 }
};
static const struct { static const struct {
cirrusfb_board_t btype; zorro_id id2;
zorro_id id, id2;
unsigned long size; unsigned long size;
} cirrusfb_zorro_probe_list[] __initdata = { } cirrusfb_zorro_table2[] = {
{ BT_SD64, [BT_SD64] = {
ZORRO_PROD_HELFRICH_SD64_RAM, .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
ZORRO_PROD_HELFRICH_SD64_REG, .size = 0x400000
0x400000 }, },
{ BT_PICCOLO, [BT_PICCOLO] = {
ZORRO_PROD_HELFRICH_PICCOLO_RAM, .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
ZORRO_PROD_HELFRICH_PICCOLO_REG, .size = 0x200000
0x200000 }, },
{ BT_PICASSO, [BT_PICASSO] = {
ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, .size = 0x200000
0x200000 }, },
{ BT_SPECTRUM, [BT_SPECTRUM] = {
ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, .size = 0x200000
0x200000 }, },
{ BT_PICASSO4, [BT_PICASSO4] = {
ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, .id2 = 0,
0, .size = 0x400000
0x400000 }, }
}; };
#endif /* CONFIG_ZORRO */ #endif /* CONFIG_ZORRO */
...@@ -381,13 +408,12 @@ struct cirrusfb_info { ...@@ -381,13 +408,12 @@ struct cirrusfb_info {
struct { u8 red, green, blue, pad; } palette[256]; struct { u8 red, green, blue, pad; } palette[256];
#ifdef CONFIG_ZORRO #ifdef CONFIG_ZORRO
unsigned long board_addr, struct zorro_dev *zdev;
board_size;
#endif #endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
struct pci_dev *pdev; struct pci_dev *pdev;
#endif #endif
void (*unmap)(struct cirrusfb_info *cinfo);
}; };
...@@ -401,50 +427,83 @@ static int noaccel = 0; ...@@ -401,50 +427,83 @@ static int noaccel = 0;
static const struct { static const struct {
const char *name; const char *name;
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
} cirrusfb_predefined[] = } cirrusfb_predefined[] = {
{
{"Autodetect", /* autodetect mode */
{0}
},
{"640x480", /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
{
640, 480, 640, 480, 0, 0, 8, 0,
{0, 8, 0},
{0, 8, 0},
{0, 8, 0},
{0, 0, 0},
0, 0, -1, -1, FB_ACCEL_NONE, 40000, 48, 16, 32, 8, 96, 4,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
},
{"800x600", /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
{ {
800, 600, 800, 600, 0, 0, 8, 0, /* autodetect mode */
{0, 8, 0}, .name = "Autodetect",
{0, 8, 0}, }, {
{0, 8, 0}, /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
{0, 0, 0}, .name = "640x480",
0, 0, -1, -1, FB_ACCEL_NONE, 20000, 128, 16, 24, 2, 96, 6, .var = {
0, FB_VMODE_NONINTERLACED .xres = 640,
} .yres = 480,
}, .xres_virtual = 640,
.yres_virtual = 480,
.bits_per_pixel = 8,
.red = { .length = 8 },
.green = { .length = 8 },
.blue = { .length = 8 },
.width = -1,
.height = -1,
.pixclock = 40000,
.left_margin = 48,
.right_margin = 16,
.upper_margin = 32,
.lower_margin = 8,
.hsync_len = 96,
.vsync_len = 4,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
}
}, {
/* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
.name = "800x600",
.var = {
.xres = 800,
.yres = 600,
.xres_virtual = 800,
.yres_virtual = 600,
.bits_per_pixel = 8,
.red = { .length = 8 },
.green = { .length = 8 },
.blue = { .length = 8 },
.width = -1,
.height = -1,
.pixclock = 20000,
.left_margin = 128,
.right_margin = 16,
.upper_margin = 24,
.lower_margin = 2,
.hsync_len = 96,
.vsync_len = 6,
.vmode = FB_VMODE_NONINTERLACED
}
}, {
/* /*
Modeline from XF86Config: * Modeline from XF86Config:
Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805 * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
*/ */
{"1024x768", /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */ /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
{ .name = "1024x768",
1024, 768, 1024, 768, 0, 0, 8, 0, .var = {
{0, 8, 0}, .xres = 1024,
{0, 8, 0}, .yres = 768,
{0, 8, 0}, .xres_virtual = 1024,
{0, 0, 0}, .yres_virtual = 768,
0, 0, -1, -1, FB_ACCEL_NONE, 12500, 144, 32, 30, 2, 192, 6, .bits_per_pixel = 8,
0, FB_VMODE_NONINTERLACED .red = { .length = 8 },
.green = { .length = 8 },
.blue = { .length = 8 },
.width = -1,
.height = -1,
.pixclock = 12500,
.left_margin = 144,
.right_margin = 32,
.upper_margin = 30,
.lower_margin = 2,
.hsync_len = 192,
.vsync_len = 6,
.vmode = FB_VMODE_NONINTERLACED
} }
} }
}; };
...@@ -2156,9 +2215,143 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo) ...@@ -2156,9 +2215,143 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
framebuffer_release(cinfo->info); framebuffer_release(cinfo->info);
pci_disable_device(pdev); pci_disable_device(pdev);
} }
#endif /* CONFIG_PCI */
#ifdef CONFIG_ZORRO
static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo)
{
zorro_release_device(cinfo->zdev);
if (cinfo->btype == BT_PICASSO4) {
cinfo->regbase -= 0x600000;
iounmap ((void *)cinfo->regbase);
iounmap ((void *)cinfo->fbmem);
} else {
if (zorro_resource_start(cinfo->zdev) > 0x01000000)
iounmap ((void *)cinfo->fbmem);
}
framebuffer_release(cinfo->info);
}
#endif /* CONFIG_ZORRO */
static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
{
struct fb_info *info = cinfo->info;
struct fb_var_screeninfo *var = &info->var;
info->currcon = -1;
info->par = cinfo;
info->pseudo_palette = cinfo->pseudo_palette;
info->flags = FBINFO_DEFAULT
| FBINFO_HWACCEL_XPAN
| FBINFO_HWACCEL_YPAN
| FBINFO_HWACCEL_FILLRECT
| FBINFO_HWACCEL_COPYAREA;
if (noaccel)
info->flags |= FBINFO_HWACCEL_DISABLED;
info->fbops = &cirrusfb_ops;
info->screen_base = cinfo->fbmem;
if (cinfo->btype == BT_GD5480) {
if (var->bits_per_pixel == 16)
info->screen_base += 1 * MB_;
if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
info->screen_base += 2 * MB_;
}
/* Fill fix common fields */
strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
sizeof(info->fix.id));
/* monochrome: only 1 memory plane */
/* 8 bit and above: Use whole memory area */
info->fix.smem_start = cinfo->fbmem_phys;
info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size;
info->fix.type = cinfo->currentmode.type;
info->fix.type_aux = 0;
info->fix.visual = cinfo->currentmode.visual;
info->fix.xpanstep = 1;
info->fix.ypanstep = 1;
info->fix.ywrapstep = 0;
info->fix.line_length = cinfo->currentmode.line_length;
/* FIXME: map region at 0xB8000 if available, fill in here */
info->fix.mmio_start = cinfo->fbregs_phys;
info->fix.mmio_len = 0;
info->fix.accel = FB_ACCEL_NONE;
fb_alloc_cmap(&info->cmap, 256, 0);
return 0;
}
static int cirrusfb_register(struct cirrusfb_info *cinfo)
{
struct fb_info *info;
int err;
cirrusfb_board_t btype;
DPRINTK ("ENTER\n");
printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n");
info = cinfo->info;
btype = cinfo->btype;
/* sanity checks */
assert (btype != BT_NONE);
DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem);
/* Make pretend we've set the var so our structures are in a "good" */
/* state, even though we haven't written the mode to the hw yet... */
info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
info->var.activate = FB_ACTIVATE_NOW;
err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
if (err < 0) {
/* should never happen */
DPRINTK("choking on default var... umm, no good.\n");
goto err_unmap_cirrusfb;
}
/* set all the vital stuff */
cirrusfb_set_fbinfo(cinfo);
err = register_framebuffer(info);
if (err < 0) {
printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err);
goto err_dealloc_cmap;
}
DPRINTK ("EXIT, returning 0\n");
return 0;
err_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
err_unmap_cirrusfb:
cinfo->unmap(cinfo);
return err;
}
static void __devexit cirrusfb_cleanup (struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
DPRINTK ("ENTER\n");
switch_monitor (cinfo, 0);
unregister_framebuffer (info);
fb_dealloc_cmap (&info->cmap);
printk ("Framebuffer unregistered\n");
cinfo->unmap(cinfo);
DPRINTK ("EXIT\n");
}
static struct cirrusfb_info *cirrusfb_pci_setup (struct pci_dev *pdev, #ifdef CONFIG_PCI
static int cirrusfb_pci_register (struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct cirrusfb_info *cinfo; struct cirrusfb_info *cinfo;
...@@ -2233,11 +2426,13 @@ static struct cirrusfb_info *cirrusfb_pci_setup (struct pci_dev *pdev, ...@@ -2233,11 +2426,13 @@ static struct cirrusfb_info *cirrusfb_pci_setup (struct pci_dev *pdev,
cinfo->fbmem_phys = board_addr; cinfo->fbmem_phys = board_addr;
cinfo->size = board_size; cinfo->size = board_size;
cinfo->unmap = cirrusfb_pci_unmap;
printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr); printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr);
printk ("Cirrus Logic chipset on PCI bus\n"); printk ("Cirrus Logic chipset on PCI bus\n");
pci_set_drvdata(pdev, info);
return cinfo; return cirrusfb_register(cinfo);
err_release_legacy: err_release_legacy:
if (release_io_ports) if (release_io_ports)
...@@ -2252,77 +2447,51 @@ static struct cirrusfb_info *cirrusfb_pci_setup (struct pci_dev *pdev, ...@@ -2252,77 +2447,51 @@ static struct cirrusfb_info *cirrusfb_pci_setup (struct pci_dev *pdev,
err_disable: err_disable:
pci_disable_device(pdev); pci_disable_device(pdev);
err_out: err_out:
return ERR_PTR(ret); return ret;
} }
#endif /* CONFIG_PCI */
void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
#ifdef CONFIG_ZORRO
static int cirrusfb_zorro_find (struct zorro_dev **z_o,
struct zorro_dev **z2_o,
cirrusfb_board_t *btype, unsigned long *size)
{ {
struct zorro_dev *z = NULL; struct fb_info *info = pci_get_drvdata(pdev);
int i; DPRINTK ("ENTER\n");
assert (z_o != NULL);
assert (btype != NULL);
for (i = 0; i < ARRAY_SIZE(cirrusfb_zorro_probe_list); i++)
if ((z = zorro_find_device(cirrusfb_zorro_probe_list[i].id, NULL)))
break;
if (z) {
*z_o = z;
if (cirrusfb_zorro_probe_list[i].id2)
*z2_o = zorro_find_device(cirrusfb_zorro_probe_list[i].id2, NULL);
else
*z2_o = NULL;
*btype = cirrusfb_zorro_probe_list[i].btype;
*size = cirrusfb_zorro_probe_list[i].size;
printk (KERN_INFO "cirrusfb: %s board detected; ",
cirrusfb_board_info[*btype].name);
return 0; cirrusfb_cleanup (info);
}
printk (KERN_NOTICE "cirrusfb: no supported board found.\n"); DPRINTK ("EXIT\n");
return -ENODEV;
} }
static struct pci_driver cirrusfb_pci_driver = {
static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo) .name = "cirrusfb",
{ .id_table = cirrusfb_pci_table,
release_mem_region(cinfo->board_addr, cinfo->board_size); .probe = cirrusfb_pci_register,
.remove = __devexit_p(cirrusfb_pci_unregister),
if (cinfo->btype == BT_PICASSO4) { #ifdef CONFIG_PM
cinfo->regbase -= 0x600000; #if 0
iounmap ((void *)cinfo->regbase); .suspend = cirrusfb_pci_suspend,
iounmap ((void *)cinfo->fbmem); .resume = cirrusfb_pci_resume,
} else { #endif
if (cinfo->board_addr > 0x01000000) #endif
iounmap ((void *)cinfo->fbmem); };
} #endif /* CONFIG_PCI */
framebuffer_release(cinfo->info);
}
static struct cirrusfb_info *cirrusfb_zorro_setup(void) #ifdef CONFIG_ZORRO
static int cirrusfb_zorro_register(struct zorro_dev *z,
const struct zorro_device_id *ent)
{ {
struct cirrusfb_info *cinfo; struct cirrusfb_info *cinfo;
struct fb_info *info; struct fb_info *info;
cirrusfb_board_t btype; cirrusfb_board_t btype;
struct zorro_dev *z = NULL, *z2 = NULL; struct zorro_dev *z2 = NULL;
unsigned long board_addr, board_size, size; unsigned long board_addr, board_size, size;
int ret; int ret;
ret = cirrusfb_zorro_find (&z, &z2, &btype, &size); btype = ent->driver_data;
if (ret < 0) if (cirrusfb_zorro_table2[btype].id2)
goto err_out; z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
size = cirrusfb_zorro_table2[btype].size;
printk(KERN_INFO "cirrusfb: %s board detected; ",
cirrusfb_board_info[btype].name);
info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
if (!info) { if (!info) {
...@@ -2339,11 +2508,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void) ...@@ -2339,11 +2508,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void)
assert (z2 >= 0); assert (z2 >= 0);
assert (btype != BT_NONE); assert (btype != BT_NONE);
cinfo->board_addr = board_addr = z->resource.start; cinfo->zdev = z;
cinfo->board_size = board_size = z->resource.end-z->resource.start+1; board_addr = zorro_resource_start(z);
board_size = zorro_resource_len(z);
cinfo->size = size; cinfo->size = size;
if (!request_mem_region(board_addr, board_size, "cirrusfb")) { if (!zorro_request_device(z, "cirrusfb")) {
printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n", printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",
board_addr); board_addr);
ret = -EBUSY; ret = -EBUSY;
...@@ -2370,7 +2540,7 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void) ...@@ -2370,7 +2540,7 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void)
cinfo->fbregs_phys = board_addr + 0x600000; cinfo->fbregs_phys = board_addr + 0x600000;
cinfo->fbmem_phys = board_addr + 16777216; cinfo->fbmem_phys = board_addr + 16777216;
cinfo->fbmem = ioremap (info->fbmem_phys, 16777216); cinfo->fbmem = ioremap (cinfo->fbmem_phys, 16777216);
if (!cinfo->fbmem) if (!cinfo->fbmem)
goto err_unmap_regbase; goto err_unmap_regbase;
} else { } else {
...@@ -2390,10 +2560,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void) ...@@ -2390,10 +2560,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void)
DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase);
} }
cinfo->unmap = cirrusfb_zorro_unmap;
printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
zorro_set_drvdata(z, info);
return 0; return cirrusfb_register(cinfo);
err_unmap_regbase: err_unmap_regbase:
/* Parental advisory: explicit hack */ /* Parental advisory: explicit hack */
...@@ -2403,153 +2575,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void) ...@@ -2403,153 +2575,12 @@ static struct cirrusfb_info *cirrusfb_zorro_setup(void)
err_release_fb: err_release_fb:
framebuffer_release(info); framebuffer_release(info);
err_out: err_out:
return ERR_PTR(ret); return ret;
}
#endif /* CONFIG_ZORRO */
static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
{
struct fb_info *info = cinfo->info;
struct fb_var_screeninfo *var = &info->var;
info->currcon = -1;
info->par = cinfo;
info->pseudo_palette = cinfo->pseudo_palette;
info->flags = FBINFO_DEFAULT
| FBINFO_HWACCEL_XPAN
| FBINFO_HWACCEL_YPAN
| FBINFO_HWACCEL_FILLRECT
| FBINFO_HWACCEL_COPYAREA;
if (noaccel)
info->flags |= FBINFO_HWACCEL_DISABLED;
info->fbops = &cirrusfb_ops;
info->screen_base = cinfo->fbmem;
if (cinfo->btype == BT_GD5480) {
if (var->bits_per_pixel == 16)
info->screen_base += 1 * MB_;
if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
info->screen_base += 2 * MB_;
}
/* Fill fix common fields */
strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
sizeof(info->fix.id));
/* monochrome: only 1 memory plane */
/* 8 bit and above: Use whole memory area */
info->fix.smem_start = cinfo->fbmem_phys;
info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size;
info->fix.type = cinfo->currentmode.type;
info->fix.type_aux = 0;
info->fix.visual = cinfo->currentmode.visual;
info->fix.xpanstep = 1;
info->fix.ypanstep = 1;
info->fix.ywrapstep = 0;
info->fix.line_length = cinfo->currentmode.line_length;
/* FIXME: map region at 0xB8000 if available, fill in here */
info->fix.mmio_start = cinfo->fbregs_phys;
info->fix.mmio_len = 0;
info->fix.accel = FB_ACCEL_NONE;
fb_alloc_cmap(&info->cmap, 256, 0);
return 0;
} }
#if defined(CONFIG_PCI) void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
#define cirrusfb_unmap cirrusfb_pci_unmap
#define cirrusfb_bus_setup cirrusfb_pci_setup
#elif defined(CONFIG_ZORRO)
#define cirrusfb_unmap cirrusfb_zorro_unmap
#define cirrusfb_bus_setup cirrusfb_zorro_setup
#endif
static int cirrusfb_pci_register (struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
struct fb_info *info; struct fb_info *info = zorro_get_drvdata(z);
struct cirrusfb_info *cinfo = NULL;
int err;
cirrusfb_board_t btype;
DPRINTK ("ENTER\n");
printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n");
cinfo = cirrusfb_bus_setup(pdev, ent);
if (IS_ERR(cinfo)) {
err = PTR_ERR(cinfo);
goto err_out;
}
info = cinfo->info;
btype = cinfo->btype;
/* sanity checks */
assert (btype != BT_NONE);
assert (btype == cirrusfb_board_info[btype].btype);
DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem);
/* Make pretend we've set the var so our structures are in a "good" */
/* state, even though we haven't written the mode to the hw yet... */
info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
info->var.activate = FB_ACTIVATE_NOW;
err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
if (err < 0) {
/* should never happen */
DPRINTK("choking on default var... umm, no good.\n");
goto err_unmap_cirrusfb;
}
/* set all the vital stuff */
cirrusfb_set_fbinfo(cinfo);
pci_set_drvdata(pdev, info);
err = register_framebuffer(info);
if (err < 0) {
printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err);
goto err_dealloc_cmap;
}
DPRINTK ("EXIT, returning 0\n");
return 0;
err_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
err_unmap_cirrusfb:
cirrusfb_unmap(cinfo);
err_out:
return err;
}
static void __devexit cirrusfb_cleanup (struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
DPRINTK ("ENTER\n");
#ifdef CONFIG_ZORRO
switch_monitor (cinfo, 0);
#endif
unregister_framebuffer (info);
fb_dealloc_cmap (&info->cmap);
printk ("Framebuffer unregistered\n");
cirrusfb_unmap (cinfo);
DPRINTK ("EXIT\n");
}
void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
DPRINTK ("ENTER\n"); DPRINTK ("ENTER\n");
cirrusfb_cleanup (info); cirrusfb_cleanup (info);
...@@ -2557,26 +2588,25 @@ void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev) ...@@ -2557,26 +2588,25 @@ void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
DPRINTK ("EXIT\n"); DPRINTK ("EXIT\n");
} }
static struct pci_driver cirrusfb_driver = { static struct zorro_driver cirrusfb_zorro_driver = {
.name = "cirrusfb", .name = "cirrusfb",
.id_table = cirrusfb_pci_table, .id_table = cirrusfb_zorro_table,
.probe = cirrusfb_pci_register, .probe = cirrusfb_zorro_register,
.remove = __devexit_p(cirrusfb_pci_unregister), .remove = __devexit_p(cirrusfb_zorro_unregister),
#ifdef CONFIG_PM
#if 0
.suspend = cirrusfb_pci_suspend,
.resume = cirrusfb_pci_resume,
#endif
#endif
}; };
#endif /* CONFIG_ZORRO */
int __init cirrusfb_init(void) int __init cirrusfb_init(void)
{ {
int error = 0;
#ifdef CONFIG_ZORRO #ifdef CONFIG_ZORRO
return cirrusfb_pci_register(NULL, NULL); error |= zorro_module_init(&cirrusfb_zorro_driver);
#else
return pci_module_init(&cirrusfb_driver);
#endif #endif
#ifdef CONFIG_PCI
error |= pci_module_init(&cirrusfb_pci_driver);
#endif
return error;
} }
...@@ -2619,7 +2649,12 @@ MODULE_LICENSE("GPL"); ...@@ -2619,7 +2649,12 @@ MODULE_LICENSE("GPL");
void __exit cirrusfb_exit (void) void __exit cirrusfb_exit (void)
{ {
pci_unregister_driver (&cirrusfb_driver); #ifdef CONFIG_PCI
pci_unregister_driver(&cirrusfb_pci_driver);
#endif
#ifdef CONFIG_ZORRO
zorro_unregister_driver(&cirrusfb_zorro_driver);
#endif
} }
#ifdef MODULE #ifdef MODULE
......
...@@ -26,8 +26,15 @@ ...@@ -26,8 +26,15 @@
/* /*
* FIXME * FIXME
* Ugh, we don't have PCI space, so map readb() and friends to use Zorro space * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space
* for MMIO accesses. This should make clgenfb work again on Amiga * for MMIO accesses. This should make cirrusfb work again on Amiga
*/ */
#undef inb_p
#undef inw_p
#undef outb_p
#undef outw
#undef readb
#undef writeb
#undef writew
#define inb_p(port) 0 #define inb_p(port) 0
#define inw_p(port) 0 #define inw_p(port) 0
#define outb_p(port, val) do { } while (0) #define outb_p(port, val) do { } while (0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment