> Date: Thu, 23 Aug 2012 00:27:26 +0200
> From: Martin Pieuchot <[email protected]>
>
> On 22/08/12(Wed) 21:18, Mark Kettenis wrote:
> > > On 21/08/12(Tue) 20:58, Mark Kettenis wrote:
> > > > > Date: Tue, 21 Aug 2012 19:17:08 +0200
> > > > > From: Martin Pieuchot <[email protected]>
> > > > >
> > > > > Diff below is mostly a rewrite of vgafb_pci_probe() to determine the
> > > > > memory and mmio regions based on previously initialized BAR
> > > > > structures.
> > > > > But it also includes the glue to attach drm(4) to vgafb(4).
> > > > >
> > > > > It reuses the following functions from vga(4), the last three are
> > > > > required by any drm(4) driver:
> > > > > - vga_pci_bar_init()
> > > > > - vga_pci_bar_info()
> > > > > - vga_pci_bar_map()
> > > > > - vga_pci_bar_unmap()
> > > >
> > > > Looks like by "reuses" you mean "copies". That tends to be a bad idea
> > > > since results in diverging code. WOuldn't it be better to split out
> > > > these functions into their own file (vga_pci_common.c) and share them
> > > > between vga(4) and vgafb(4)?
> > >
> > > Sure, here's a diff that does only this, tested on i386 and macppc.
> > > I used Owain's copyright because he is the one who commited this code.
> > >
> > > Ok?
> >
> > Go for it.
> >
> > (If it wasn't obvious yet, I intend to use this code on sparc64 as well)
>
> And now the vgafb(4) part which includes two renames to keep the MD
> structures:
> vgafb_pci_softc -> vga_pci_softc
> vgafb_config -> vga_config
Bleah, I hadn't realised that was the consequence of the change.
Guess some redesign of the vga<->drm interface is in order. But don't
let me hold you back; that's something for later.
> I kept your suggestion for the agp cdev declaration.
>
> Ok?
If you remove the
> +#define DEBUG_VGAFB
;).
> Index: dev/pci/files.pci
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/files.pci,v
> retrieving revision 1.286
> diff -u -p -r1.286 files.pci
> --- dev/pci/files.pci 22 Aug 2012 20:58:30 -0000 1.286
> +++ dev/pci/files.pci 22 Aug 2012 22:03:02 -0000
> @@ -15,7 +15,7 @@ file dev/pci/pci_subr.c pci
> # Generic VGA
> attach vga at pci with vga_pci
> file dev/pci/vga_pci.c vga_pci
> -file dev/pci/vga_pci_common.c vga_pci
> +file dev/pci/vga_pci_common.c vga_pci | vgafb
>
> device tga: wsemuldisplaydev, rasops8, rasops32
> attach tga at pci
> Index: arch/macppc/macppc/conf.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/macppc/conf.c,v
> retrieving revision 1.47
> diff -u -p -r1.47 conf.c
> --- arch/macppc/macppc/conf.c 6 Apr 2012 15:10:40 -0000 1.47
> +++ arch/macppc/macppc/conf.c 22 Aug 2012 22:04:39 -0000
> @@ -119,6 +119,8 @@ cdev_decl(nnpfs_dev);
>
> #include "apm.h"
> #include "bthub.h"
> +#include "drm.h"
> +cdev_decl(drm);
>
> #include "wsmux.h"
>
> @@ -243,6 +245,8 @@ struct cdevsw cdevsw[] = {
> cdev_vscsi_init(NVSCSI,vscsi), /* 83: vscsi */
> cdev_disk_init(1,diskmap), /* 84: disk mapper */
> cdev_pppx_init(NPPPX,pppx), /* 85: pppx */
> + cdev_notdef(), /* 86: agp */
> + cdev_drm_init(NDRM,drm), /* 87: drm */
> };
> int nchrdev = nitems(cdevsw);
>
> Index: arch/macppc/pci/vgafb.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/pci/vgafb.c,v
> retrieving revision 1.40
> diff -u -p -r1.40 vgafb.c
> --- arch/macppc/pci/vgafb.c 21 Jun 2012 10:08:16 -0000 1.40
> +++ arch/macppc/pci/vgafb.c 22 Aug 2012 11:29:56 -0000
> @@ -53,16 +53,16 @@ struct cfdriver vgafb_cd = {
> NULL, "vgafb", DV_DULL,
> };
>
> -void vgafb_setcolor(struct vgafb_config *vc, unsigned int index,
> +void vgafb_setcolor(struct vga_config *vc, unsigned int index,
> u_int8_t r, u_int8_t g, u_int8_t b);
> -void vgafb_restore_default_colors(struct vgafb_config *vc);
> +void vgafb_restore_default_colors(struct vga_config *vc);
>
> struct vgafb_devconfig {
> struct rasops_info dc_rinfo; /* raster display data */
> int dc_blanked; /* currently had video disabled */
> };
>
> -extern struct vgafb_config vgafb_pci_console_vc;
> +extern struct vga_config vgafb_pci_console_vc;
> struct vgafb_devconfig vgafb_console_dc;
>
> struct wsscreen_descr vgafb_stdscreen = {
> @@ -94,8 +94,8 @@ struct wsdisplay_accessops vgafb_accesso
> vgafb_burn, /* burner */
> };
>
> -int vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
> -int vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm);
> +int vgafb_getcmap(struct vga_config *vc, struct wsdisplay_cmap *cm);
> +int vgafb_putcmap(struct vga_config *vc, struct wsdisplay_cmap *cm);
>
> #define FONT_WIDTH 8
> #define FONT_HEIGHT 16
> @@ -106,7 +106,7 @@ extern int allowaperture;
>
>
> void
> -vgafb_init(bus_space_tag_t iot, bus_space_tag_t memt, struct vgafb_config
> *vc,
> +vgafb_init(bus_space_tag_t iot, bus_space_tag_t memt, struct vga_config *vc,
> u_int32_t membase, size_t memsize, u_int32_t mmiobase, size_t mmiosize)
> {
> vc->vc_iot = iot;
> @@ -140,7 +140,7 @@ vgafb_init(bus_space_tag_t iot, bus_spac
> }
>
> void
> -vgafb_restore_default_colors(struct vgafb_config *vc)
> +vgafb_restore_default_colors(struct vga_config *vc)
> {
> int i;
>
> @@ -153,7 +153,7 @@ vgafb_restore_default_colors(struct vgaf
> }
>
> void
> -vgafb_wsdisplay_attach(struct device *parent, struct vgafb_config *vc,
> +vgafb_wsdisplay_attach(struct device *parent, struct vga_config *vc,
> int console)
> {
> struct wsemuldisplaydev_attach_args aa;
> @@ -178,7 +178,7 @@ vgafb_wsdisplay_attach(struct device *pa
> int
> vgafb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
> {
> - struct vgafb_config *vc = v;
> + struct vga_config *vc = v;
> struct wsdisplay_fbinfo *wdf;
>
> switch (cmd) {
> @@ -282,7 +282,7 @@ vgafb_ioctl(void *v, u_long cmd, caddr_t
> paddr_t
> vgafb_mmap(void *v, off_t off, int prot)
> {
> - struct vgafb_config *vc = v;
> + struct vga_config *vc = v;
>
> if (off & PGOFSET)
> return (-1);
> @@ -317,7 +317,7 @@ vgafb_mmap(void *v, off_t off, int prot)
> int
> vgafb_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, int type, int
> check)
> {
> - struct vgafb_config *vc = &vgafb_pci_console_vc;
> + struct vga_config *vc = &vgafb_pci_console_vc;
> struct vgafb_devconfig *dc = &vgafb_console_dc;
> struct rasops_info *ri = &dc->dc_rinfo;
> long defattr;
> @@ -358,7 +358,7 @@ struct {
> } vgafb_color[256];
>
> void
> -vgafb_setcolor(struct vgafb_config *vc, unsigned int index, u_int8_t r,
> +vgafb_setcolor(struct vga_config *vc, unsigned int index, u_int8_t r,
> u_int8_t g, u_int8_t b)
> {
> vc->vc_cmap_red[index] = r;
> @@ -373,7 +373,7 @@ vgafb_setcolor(struct vgafb_config *vc,
> }
>
> int
> -vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
> +vgafb_getcmap(struct vga_config *vc, struct wsdisplay_cmap *cm)
> {
> u_int index = cm->index;
> u_int count = cm->count;
> @@ -396,7 +396,7 @@ vgafb_getcmap(struct vgafb_config *vc, s
> }
>
> int
> -vgafb_putcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm)
> +vgafb_putcmap(struct vga_config *vc, struct wsdisplay_cmap *cm)
> {
> u_int index = cm->index;
> u_int count = cm->count;
> @@ -432,7 +432,7 @@ vgafb_putcmap(struct vgafb_config *vc, s
> void
> vgafb_burn(void *v, u_int on, u_int flags)
> {
> - struct vgafb_config *vc = v;
> + struct vga_config *vc = v;
>
> if (cons_backlight_available == 1 &&
> vc->vc_backlight_on != on) {
> @@ -449,7 +449,7 @@ int
> vgafb_alloc_screen(void *v, const struct wsscreen_descr *type, void
> **cookiep,
> int *curxp, int *curyp, long *attrp)
> {
> - struct vgafb_config *vc = v;
> + struct vga_config *vc = v;
> long defattr;
>
> if (vc->nscreens > 0)
> @@ -469,7 +469,7 @@ vgafb_alloc_screen(void *v, const struct
> void
> vgafb_free_screen(void *v, void *cookie)
> {
> - struct vgafb_config *vc = v;
> + struct vga_config *vc = v;
>
> if (vc == &vgafb_pci_console_vc)
> panic("vgafb_free_screen: console");
> Index: arch/macppc/pci/vgafb_pci.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/pci/vgafb_pci.c,v
> retrieving revision 1.25
> diff -u -p -r1.25 vgafb_pci.c
> --- arch/macppc/pci/vgafb_pci.c 21 Jun 2012 10:08:16 -0000 1.25
> +++ arch/macppc/pci/vgafb_pci.c 22 Aug 2012 12:21:20 -0000
> @@ -47,175 +47,101 @@
> #include <dev/rasops/rasops.h>
> #include <dev/wsfont/wsfont.h>
>
> +#include "drm.h"
> +
> #include <arch/macppc/pci/vgafbvar.h>
> -#include <arch/macppc/pci/vgafb_pcivar.h>
> +#include <dev/pci/vga_pcivar.h>
>
> -#define PCI_VENDORID(x) ((x) & 0xFFFF)
> -#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
> +#define DEBUG_VGAFB
>
> -struct vgafb_pci_softc {
> - struct device sc_dev;
> -
> - pcitag_t sc_pcitag; /* PCI tag, in case we need it. */
> - struct vgafb_config *sc_vc; /* VGA configuration */
> -};
> +#ifdef DEBUG_VGAFB
> +#define DPRINTF(x...) do { printf(x); } while (0);
> +#else
> +#define DPRINTF(x...)
> +#endif
>
> -int vgafb_pci_probe(struct pci_attach_args *pa, int id, u_int32_t *ioaddr,
> - u_int32_t *iosize, u_int32_t *memaddr, u_int32_t *memsize,
> - u_int32_t *cacheable, u_int32_t *mmioaddr, u_int32_t *mmiosize);
> int vgafb_pci_match(struct device *, void *, void *);
> void vgafb_pci_attach(struct device *, struct device *, void *);
>
> +void vgafb_pci_mem_init(struct vga_pci_softc *, uint32_t *, uint32_t *,
> + uint32_t *, uint32_t *);
> +
> struct cfattach vgafb_pci_ca = {
> - sizeof(struct vgafb_pci_softc), (cfmatch_t)vgafb_pci_match,
> vgafb_pci_attach,
> + sizeof(struct vga_pci_softc), (cfmatch_t)vgafb_pci_match,
> vgafb_pci_attach,
> };
>
> pcitag_t vgafb_pci_console_tag;
> -struct vgafb_config vgafb_pci_console_vc;
> +struct vga_config vgafb_pci_console_vc;
>
> -#if 0
> -#define DEBUG_VGAFB
> -#endif
> -
> -int
> -vgafb_pci_probe(struct pci_attach_args *pa, int id, u_int32_t *ioaddr,
> - u_int32_t *iosize, u_int32_t *memaddr, u_int32_t *memsize,
> - u_int32_t *cacheable, u_int32_t *mmioaddr, u_int32_t *mmiosize)
> +void
> +vgafb_pci_mem_init(struct vga_pci_softc *dev, uint32_t *memaddr,
> + uint32_t *memsize, uint32_t *mmioaddr, uint32_t *mmiosize)
> {
> - bus_addr_t addr;
> - bus_size_t size;
> - int tcacheable;
> - pci_chipset_tag_t pc = pa->pa_pc;
> - int retval;
> + struct vga_pci_bar *bar;
> int i;
>
> - *iosize = 0x0;
> *memsize = 0x0;
> *mmiosize = 0x0;
> - for (i = PCI_MAPREG_START; i <= PCI_MAPREG_PPB_END; i += 4) {
> -#ifdef DEBUG_VGAFB
> - printf("vgafb confread %x %x\n",
> - i, pci_conf_read(pc, pa->pa_tag, i));
> -#endif
> - /* need to check more than just two base addresses? */
> - if (PCI_MAPREG_TYPE(pci_conf_read(pc, pa->pa_tag, i)) ==
> - PCI_MAPREG_TYPE_IO) {
> - retval = pci_io_find(pc, pa->pa_tag, i,
> - &addr, &size);
> - if (retval != 0) {
> - continue;
> - }
> -#ifdef DEBUG_VGAFB
> - printf("vgafb_pci_probe: io %x addr %x size %x\n", i, addr, size);
> -#endif
> - if (*iosize == 0) {
> - *ioaddr = addr;
> - *iosize = size;
> - }
>
> - } else {
> - retval = pci_mem_find(pc, pa->pa_tag, i,
> - &addr, &size, &tcacheable);
> - if (retval != 0) {
> - continue;
> - }
> -#ifdef DEBUG_VGAFB
> - printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size);
> -#endif
> - if (size == 0 || addr == 0) {
> + for (i = 0; i < VGA_PCI_MAX_BARS; i++) {
> + bar = dev->bars[i];
> + if (bar == NULL)
> + continue;
> +
> + DPRINTF("\nvgafb: 0x%04x: BAR ", bar->addr);
> +
> + switch (PCI_MAPREG_TYPE(bar->maptype)) {
> + case PCI_MAPREG_TYPE_IO:
> + DPRINTF("io ");
> + break;
> + case PCI_MAPREG_TYPE_MEM:
> + if (bar->base == 0 || bar->maxsize == 0) {
> /* ignore this entry */
> } else if (*memsize == 0) {
> /*
> * first memory slot found goes into memory,
> * this is for the case of no mmio
> */
> - *memaddr = addr;
> - *memsize = size;
> - *cacheable = tcacheable;
> + *memaddr = bar->base;
> + *memsize = bar->maxsize;
> } else {
> /*
> - * Oh, we have a second 'memory'
> + * Oh, we have a second 'memory'
> * region, is this region the vga memory
> * or mmio, we guess that memory is
> * the larger of the two.
> - */
> - if (*memaddr >= size) {
> + */
> + if (*memsize >= bar->maxsize) {
> /* this is the mmio */
> - *mmioaddr = addr;
> - /* ATI driver maps 0x80000 mmio, grr */
> - if (size < 0x80000) {
> - size = 0x80000;
> - }
> - *mmiosize = size;
> + *mmioaddr = bar->base;
> + *mmiosize = bar->maxsize;
> } else {
> /* this is the memory */
> *mmioaddr = *memaddr;
> - *memaddr = addr;
> *mmiosize = *memsize;
> - *memsize = size;
> - *cacheable = tcacheable;
> - /* ATI driver maps 0x80000 mmio, grr */
> - if (*mmiosize < 0x80000) {
> - *mmiosize = 0x80000;
> - }
> + *memaddr = bar->base;
> + *memsize = bar->maxsize;
> }
> }
> + DPRINTF("mem ");
> + break;
> }
> - }
> -#ifdef DEBUG_VGAFB
> - printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n
> memsize %x, mmioaddr %x, mmiosize %x\n",
> - id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
> -#endif
> - if (*iosize == 0) {
> - if (id == 0) {
> -#ifdef powerpc
> - /* this is only used if on openfirmware system and
> - * the device does not have a iobase config register,
> - * eg CirrusLogic 5434 VGA. (they hardcode iobase to 0
> - * thus giving standard PC addresses for the registers)
> - */
> - int s;
> - u_int32_t sizedata;
> -
> - /*
> - * Open Firmware (yuck) shuts down devices before
> - * entering a program so we need to bring them back
> - * 'online' to respond to bus accesses... so far
> - * this is true on the power.4e.
> - */
> - s = splhigh();
> - sizedata = pci_conf_read(pc, pa->pa_tag,
> - PCI_COMMAND_STATUS_REG);
> - sizedata |= (PCI_COMMAND_MASTER_ENABLE |
> - PCI_COMMAND_IO_ENABLE |
> - PCI_COMMAND_PARITY_ENABLE |
> - PCI_COMMAND_SERR_ENABLE);
> - pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
> - sizedata);
> - splx(s);
>
> -#endif
> - /* if this is the first card, allow it
> - * to be accessed in vga iospace
> - */
> - *ioaddr = 0;
> - *iosize = 0x10000; /* 64k, good as any */
> + if (bar->maptype == PCI_MAPREG_MEM_TYPE_64BIT) {
> + DPRINTF("64bit");
> + i++;
> } else {
> - /* iospace not available, assume 640x480, pray */
> - *ioaddr = 0;
> - *iosize = 0;
> + DPRINTF("addr: 0x%08x/0x%08x", bar->base, bar->maxsize);
> }
> }
> -#ifdef DEBUG_VGAFB
> - printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n
> memsize %x, mmioaddr %x, mmiosize %x\n",
> - id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
> -#endif
> -
> - /* io and mmio spaces are not required to attach */
> - if (/* *iosize == 0 || */ *memsize == 0 /* || *mmiosize == 0 */)
> - return (0);
>
> - return (1);
> + /* ATI driver maps 0x80000 mmio, grr */
> + if (*mmiosize > 0 && *mmiosize < 0x80000) {
> + *mmiosize = 0x80000;
> + }
> +
> + DPRINTF("\nvgafb: memaddr %x, memsize %x, mmioaddr %x, mmiosize %x",
> + *memaddr, *memsize, *mmioaddr, *mmiosize);
> }
>
> int
> @@ -249,32 +175,37 @@ void
> vgafb_pci_attach(struct device *parent, struct device *self, void *aux)
> {
> struct pci_attach_args *pa = aux;
> - struct vgafb_pci_softc *sc = (struct vgafb_pci_softc *)self;
> - struct vgafb_config *vc;
> - u_int32_t memaddr, memsize, cacheable;
> - u_int32_t ioaddr, iosize;
> + struct vga_pci_softc *sc = (struct vga_pci_softc *)self;
> + struct vga_config *vc;
> + u_int32_t memaddr, memsize;
> u_int32_t mmioaddr, mmiosize;
> int console;
> - static int id = 0;
> - int myid;
> + pcireg_t reg;
>
> - myid = id;
>
> - vgafb_pci_probe(pa, myid, &ioaddr, &iosize,
> - &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize);
> + vga_pci_bar_init(sc, pa);
> + vgafb_pci_mem_init(sc, &memaddr, &memsize, &mmioaddr, &mmiosize);
>
>
> console = (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag,
> sizeof(pa->pa_tag)));
> if (console)
> vc = sc->sc_vc = &vgafb_pci_console_vc;
> else {
> - vc = sc->sc_vc = (struct vgafb_config *)
> - malloc(sizeof(struct vgafb_config), M_DEVBUF, M_WAITOK);
> + vc = sc->sc_vc = (struct vga_config *)
> + malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK);
>
> /* set up bus-independent VGA configuration */
> vgafb_init(pa->pa_iot, pa->pa_memt, vc,
> memaddr, memsize, mmioaddr, mmiosize);
> }
> +
> + /*
> + * Enable bus master; X might need this for accelerated graphics.
> + */
> + reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
> + reg |= PCI_COMMAND_MASTER_ENABLE;
> + pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);
> +
> vc->vc_mmap = vgafb_mmap;
> vc->vc_ioctl = vgafb_ioctl;
> vc->membase = memaddr;
> @@ -282,16 +213,14 @@ vgafb_pci_attach(struct device *parent,
> vc->mmiobase = mmioaddr;
> vc->mmiosize = mmiosize;
>
> - sc->sc_pcitag = pa->pa_tag;
> -
> - if (iosize == 0)
> - printf (", no io");
> -
> if (mmiosize != 0)
> printf (", mmio");
>
> printf("\n");
>
> vgafb_wsdisplay_attach(self, vc, console);
> - id++;
> +
> +#if NDRM > 0
> + config_found_sm(self, aux, NULL, drmsubmatch);
> +#endif
> }
> Index: arch/macppc/pci/vgafbvar.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/pci/vgafbvar.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 vgafbvar.h
> --- arch/macppc/pci/vgafbvar.h 21 Jun 2012 10:08:16 -0000 1.14
> +++ arch/macppc/pci/vgafbvar.h 22 Aug 2012 11:39:04 -0000
> @@ -28,7 +28,7 @@
> * rights to redistribute these changes.
> */
>
> -struct vgafb_config {
> +struct vga_config {
> /*
> * Filled in by front-ends.
> */
> @@ -68,12 +68,11 @@ struct vgafb_config {
> };
>
> void vgafb_init(bus_space_tag_t, bus_space_tag_t,
> - struct vgafb_config *, u_int32_t, size_t, u_int32_t, size_t);
> -void vgafb_wscons_attach(struct device *, struct vgafb_config *, int);
> -void vgafb_wscons_console(struct vgafb_config *);
> + struct vga_config *, u_int32_t, size_t, u_int32_t, size_t);
> +void vgafb_wscons_attach(struct device *, struct vga_config *, int);
> +void vgafb_wscons_console(struct vga_config *);
> int vgafb_cnattach(bus_space_tag_t, bus_space_tag_t, int, int);
> -void vgafb_wsdisplay_attach(struct device *parent,
> - struct vgafb_config *vc, int console);
> +void vgafb_wsdisplay_attach(struct device *, struct vga_config *, int);
> int vgafbioctl(void *, u_long, caddr_t, int, struct proc *);
> paddr_t vgafbmmap(void *, off_t, int);
> int vgafb_ioctl(void *, u_long, caddr_t, int, struct proc *);