1*6c7d0f6bSriastradh /* $NetBSD: drmfb_pci.c,v 1.5 2021/12/19 10:37:32 riastradh Exp $ */
2894a903bSriastradh
3894a903bSriastradh /*-
4894a903bSriastradh * Copyright (c) 2014 The NetBSD Foundation, Inc.
5894a903bSriastradh * All rights reserved.
6894a903bSriastradh *
7894a903bSriastradh * This code is derived from software contributed to The NetBSD Foundation
8894a903bSriastradh * by Taylor R. Campbell.
9894a903bSriastradh *
10894a903bSriastradh * Redistribution and use in source and binary forms, with or without
11894a903bSriastradh * modification, are permitted provided that the following conditions
12894a903bSriastradh * are met:
13894a903bSriastradh * 1. Redistributions of source code must retain the above copyright
14894a903bSriastradh * notice, this list of conditions and the following disclaimer.
15894a903bSriastradh * 2. Redistributions in binary form must reproduce the above copyright
16894a903bSriastradh * notice, this list of conditions and the following disclaimer in the
17894a903bSriastradh * documentation and/or other materials provided with the distribution.
18894a903bSriastradh *
19894a903bSriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20894a903bSriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21894a903bSriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22894a903bSriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23894a903bSriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24894a903bSriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25894a903bSriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26894a903bSriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27894a903bSriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28894a903bSriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29894a903bSriastradh * POSSIBILITY OF SUCH DAMAGE.
30894a903bSriastradh */
31894a903bSriastradh
32894a903bSriastradh /*
33894a903bSriastradh * drmfb_pci: drmfb hooks for PCI devices.
34894a903bSriastradh */
35894a903bSriastradh
36894a903bSriastradh #include <sys/cdefs.h>
37*6c7d0f6bSriastradh __KERNEL_RCSID(0, "$NetBSD: drmfb_pci.c,v 1.5 2021/12/19 10:37:32 riastradh Exp $");
388d3bbbe0Sriastradh
398d3bbbe0Sriastradh #ifdef _KERNEL_OPT
408d3bbbe0Sriastradh #include "vga.h"
418d3bbbe0Sriastradh #endif
42894a903bSriastradh
43894a903bSriastradh #include <sys/types.h>
44894a903bSriastradh #include <sys/device.h>
45894a903bSriastradh #include <sys/errno.h>
46894a903bSriastradh #include <sys/systm.h>
47894a903bSriastradh
48894a903bSriastradh #include <dev/pci/pciio.h>
49894a903bSriastradh #include <dev/pci/pcireg.h>
50894a903bSriastradh #include <dev/pci/pcivar.h>
51894a903bSriastradh #include <dev/pci/wsdisplay_pci.h>
52894a903bSriastradh
538d3bbbe0Sriastradh #if NVGA > 0
548d3bbbe0Sriastradh /*
558d3bbbe0Sriastradh * XXX All we really need is vga_is_console from vgavar.h, but the
568d3bbbe0Sriastradh * header files are missing their own dependencies, so we need to
578d3bbbe0Sriastradh * explicitly drag in the other crap.
588d3bbbe0Sriastradh */
598d3bbbe0Sriastradh #include <dev/ic/mc6845reg.h>
608d3bbbe0Sriastradh #include <dev/ic/pcdisplayvar.h>
618d3bbbe0Sriastradh #include <dev/ic/vgareg.h>
628d3bbbe0Sriastradh #include <dev/ic/vgavar.h>
638d3bbbe0Sriastradh #endif
648d3bbbe0Sriastradh
65*6c7d0f6bSriastradh #include <linux/pci.h>
66*6c7d0f6bSriastradh
67f21b21b0Sriastradh #include <drm/drm_device.h>
68894a903bSriastradh #include <drm/drm_fb_helper.h>
69894a903bSriastradh
700dc9dda4Schristos #include <drm/drmfb.h>
710dc9dda4Schristos #include <drm/drmfb_pci.h>
72894a903bSriastradh
73894a903bSriastradh /*
74894a903bSriastradh * drmfb_pci_mmap: Implementation of drmfb_params::dp_mmap. Don't use
75894a903bSriastradh * this for dp_mmapfb -- how to get at the framebuffer is device-
76894a903bSriastradh * specific.
77894a903bSriastradh */
78894a903bSriastradh paddr_t
drmfb_pci_mmap(struct drmfb_softc * sc,off_t offset,int prot)79894a903bSriastradh drmfb_pci_mmap(struct drmfb_softc *sc, off_t offset, int prot)
80894a903bSriastradh {
81894a903bSriastradh struct drm_device *const dev = sc->sc_da.da_fb_helper->dev;
82894a903bSriastradh const struct pci_attach_args *const pa = &dev->pdev->pd_pa;
83894a903bSriastradh unsigned i;
84894a903bSriastradh
85894a903bSriastradh for (i = 0; PCI_BAR(i) <= PCI_MAPREG_ROM; i++) {
86894a903bSriastradh pcireg_t type;
87894a903bSriastradh bus_addr_t addr;
88894a903bSriastradh bus_size_t size;
89894a903bSriastradh int flags;
90894a903bSriastradh
91894a903bSriastradh /* Interrogate the BAR. */
92894a903bSriastradh if (!pci_mapreg_probe(pa->pa_pc, pa->pa_tag, PCI_BAR(i),
93894a903bSriastradh &type))
94894a903bSriastradh continue;
95894a903bSriastradh if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM)
96894a903bSriastradh continue;
97894a903bSriastradh if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_BAR(i), type,
98894a903bSriastradh &addr, &size, &flags))
99894a903bSriastradh continue;
100894a903bSriastradh
101894a903bSriastradh /* Try to map it if it's in range. */
102894a903bSriastradh if ((addr <= offset) && (offset < (addr + size)))
103894a903bSriastradh return bus_space_mmap(pa->pa_memt, addr,
104894a903bSriastradh (offset - addr), prot, flags);
105894a903bSriastradh
106894a903bSriastradh /* Skip a slot if this was a 64-bit BAR. */
107894a903bSriastradh if ((PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_MEM) &&
108894a903bSriastradh (PCI_MAPREG_MEM_TYPE(type) == PCI_MAPREG_MEM_TYPE_64BIT))
109894a903bSriastradh i += 1;
110894a903bSriastradh }
111894a903bSriastradh
112894a903bSriastradh /* Failure! */
113894a903bSriastradh return -1;
114894a903bSriastradh }
115894a903bSriastradh
116894a903bSriastradh /*
117894a903bSriastradh * drmfb_pci_ioctl: Implementation of drmfb_params::dp_ioctl. Provides:
118894a903bSriastradh *
119894a903bSriastradh * - WSDISPLAY_GET_BUSID
120894a903bSriastradh * - WSDISPLAY_GTYPE
121894a903bSriastradh *
122894a903bSriastradh * Additionally allows access to PCI registers.
123894a903bSriastradh *
124894a903bSriastradh * XXX Do we need to provide access to PCI registers? I can't find
125894a903bSriastradh * anything that uses this functionality, and as is it is very
126894a903bSriastradh * dangerous.
127894a903bSriastradh */
128894a903bSriastradh int
drmfb_pci_ioctl(struct drmfb_softc * sc,unsigned long cmd,void * data,int flag,struct lwp * l)129894a903bSriastradh drmfb_pci_ioctl(struct drmfb_softc *sc, unsigned long cmd, void *data,
130894a903bSriastradh int flag, struct lwp *l)
131894a903bSriastradh {
132894a903bSriastradh struct drm_device *const dev = sc->sc_da.da_fb_helper->dev;
133894a903bSriastradh struct pci_attach_args *const pa = &dev->pdev->pd_pa;
134894a903bSriastradh
135894a903bSriastradh switch (cmd) {
136894a903bSriastradh /* PCI config read/write passthrough. */
137894a903bSriastradh case PCI_IOC_CFGREAD:
138894a903bSriastradh case PCI_IOC_CFGWRITE:
139894a903bSriastradh return pci_devioctl(pa->pa_pc, pa->pa_tag, cmd, data, flag, l);
140894a903bSriastradh
141894a903bSriastradh /* PCI-specific wsdisplay ioctls. */
142894a903bSriastradh case WSDISPLAYIO_GET_BUSID:
143894a903bSriastradh return wsdisplayio_busid_pci(dev->dev, pa->pa_pc, pa->pa_tag,
144894a903bSriastradh data);
145894a903bSriastradh case WSDISPLAYIO_GTYPE:
146894a903bSriastradh *(unsigned int *)data = WSDISPLAY_TYPE_PCIVGA;
147894a903bSriastradh return 0;
148894a903bSriastradh
149894a903bSriastradh default:
150894a903bSriastradh return EPASSTHROUGH;
151894a903bSriastradh }
152894a903bSriastradh }
1538d3bbbe0Sriastradh
1548d3bbbe0Sriastradh bool
drmfb_pci_is_vga_console(struct drm_device * dev)1558d3bbbe0Sriastradh drmfb_pci_is_vga_console(struct drm_device *dev)
1568d3bbbe0Sriastradh {
1578d3bbbe0Sriastradh
1588d3bbbe0Sriastradh #if NVGA > 0
1598d3bbbe0Sriastradh return vga_is_console(dev->pdev->pd_pa.pa_iot, -1);
1608d3bbbe0Sriastradh #else
1618d3bbbe0Sriastradh return false;
1628d3bbbe0Sriastradh #endif
1638d3bbbe0Sriastradh }
164