Module Name: src Committed By: riastradh Date: Mon Aug 27 15:31:51 UTC 2018
Modified Files: src/sys/arch/arm/nvidia: tegra_drm.c tegra_drm.h tegra_drm_mode.c tegra_nouveau.c Log Message: Update tegra drm and nouveau to compile with new drmkms. Compile-tested only. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/nvidia/tegra_drm.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_drm.h cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/nvidia/tegra_drm_mode.c cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_nouveau.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/nvidia/tegra_drm.c diff -u src/sys/arch/arm/nvidia/tegra_drm.c:1.9 src/sys/arch/arm/nvidia/tegra_drm.c:1.10 --- src/sys/arch/arm/nvidia/tegra_drm.c:1.9 Thu Dec 28 14:02:08 2017 +++ src/sys/arch/arm/nvidia/tegra_drm.c Mon Aug 27 15:31:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_drm.c,v 1.9 2017/12/28 14:02:08 jmcneill Exp $ */ +/* $NetBSD: tegra_drm.c,v 1.10 2018/08/27 15:31:51 riastradh Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.9 2017/12/28 14:02:08 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.10 2018/08/27 15:31:51 riastradh Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -51,7 +51,6 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_drm.c, static int tegra_drm_match(device_t, cfdata_t, void *); static void tegra_drm_attach(device_t, device_t, void *); -static const char *tegra_drm_get_name(struct drm_device *); static int tegra_drm_set_busid(struct drm_device *, struct drm_master *); static int tegra_drm_load(struct drm_device *, unsigned long); @@ -80,13 +79,9 @@ static struct drm_driver tegra_drm_drive .date = DRIVER_DATE, .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL -}; + .patchlevel = DRIVER_PATCHLEVEL, -static const struct drm_bus tegra_drm_bus = { - .bus_type = DRIVER_BUS_PLATFORM, - .get_name = tegra_drm_get_name, - .set_busid = tegra_drm_set_busid + .set_busid = tegra_drm_set_busid, }; CFATTACH_DECL_NEW(tegra_drm, sizeof(struct tegra_drm_softc), @@ -191,8 +186,6 @@ tegra_drm_attach(device_t parent, device prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi); - driver->bus = &tegra_drm_bus; - sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev); if (sc->sc_ddev == NULL) { aprint_error_dev(self, "couldn't allocate DRM device\n"); @@ -219,12 +212,6 @@ tegra_drm_attach(device_t parent, device return; } -static const char * -tegra_drm_get_name(struct drm_device *ddev) -{ - return DRIVER_NAME; -} - static int tegra_drm_set_busid(struct drm_device *ddev, struct drm_master *master) { @@ -243,16 +230,8 @@ tegra_drm_set_busid(struct drm_device *d static int tegra_drm_load(struct drm_device *ddev, unsigned long flags) { - char *devname; int error; - devname = kzalloc(strlen(DRIVER_NAME) + 1, GFP_KERNEL); - if (devname == NULL) { - return -ENOMEM; - } - strcpy(devname, DRIVER_NAME); - ddev->devname = devname; - error = tegra_drm_mode_init(ddev); if (error) goto drmerr; Index: src/sys/arch/arm/nvidia/tegra_drm.h diff -u src/sys/arch/arm/nvidia/tegra_drm.h:1.8 src/sys/arch/arm/nvidia/tegra_drm.h:1.9 --- src/sys/arch/arm/nvidia/tegra_drm.h:1.8 Tue Dec 26 14:54:52 2017 +++ src/sys/arch/arm/nvidia/tegra_drm.h Mon Aug 27 15:31:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_drm.h,v 1.8 2017/12/26 14:54:52 jmcneill Exp $ */ +/* $NetBSD: tegra_drm.h,v 1.9 2018/08/27 15:31:51 riastradh Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -148,9 +148,9 @@ struct tegra_fbdev { int tegra_drm_mode_init(struct drm_device *); int tegra_drm_fb_init(struct drm_device *); -u32 tegra_drm_get_vblank_counter(struct drm_device *, int); -int tegra_drm_enable_vblank(struct drm_device *, int); -void tegra_drm_disable_vblank(struct drm_device *, int); +u32 tegra_drm_get_vblank_counter(struct drm_device *, unsigned int); +int tegra_drm_enable_vblank(struct drm_device *, unsigned int); +void tegra_drm_disable_vblank(struct drm_device *, unsigned int); int tegra_drm_framebuffer_init(struct drm_device *, struct tegra_framebuffer *); Index: src/sys/arch/arm/nvidia/tegra_drm_mode.c diff -u src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.16 src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.17 --- src/sys/arch/arm/nvidia/tegra_drm_mode.c:1.16 Tue Dec 26 14:54:52 2017 +++ src/sys/arch/arm/nvidia/tegra_drm_mode.c Mon Aug 27 15:31:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_drm_mode.c,v 1.16 2017/12/26 14:54:52 jmcneill Exp $ */ +/* $NetBSD: tegra_drm_mode.c,v 1.17 2018/08/27 15:31:51 riastradh Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,12 +27,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.16 2017/12/26 14:54:52 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.17 2018/08/27 15:31:51 riastradh Exp $"); #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_edid.h> +#include <drm/drm_plane_helper.h> #include <dev/i2c/ddcvar.h> @@ -46,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_drm_mo #include <dev/fdt/fdtvar.h> +#include <external/bsd/drm2/dist/drm/drm_internal.h> + static struct drm_framebuffer *tegra_fb_create(struct drm_device *, struct drm_file *, struct drm_mode_fb_cmd2 *); @@ -1321,7 +1324,7 @@ tegra_crtc_intr(void *priv) } u32 -tegra_drm_get_vblank_counter(struct drm_device *ddev, int crtc) +tegra_drm_get_vblank_counter(struct drm_device *ddev, unsigned int crtc) { struct tegra_drm_softc * const sc = tegra_drm_private(ddev); @@ -1332,7 +1335,7 @@ tegra_drm_get_vblank_counter(struct drm_ } int -tegra_drm_enable_vblank(struct drm_device *ddev, int crtc) +tegra_drm_enable_vblank(struct drm_device *ddev, unsigned int crtc) { struct tegra_crtc *tegra_crtc = NULL; struct drm_crtc *iter; @@ -1352,7 +1355,7 @@ tegra_drm_enable_vblank(struct drm_devic } void -tegra_drm_disable_vblank(struct drm_device *ddev, int crtc) +tegra_drm_disable_vblank(struct drm_device *ddev, unsigned int crtc) { struct tegra_crtc *tegra_crtc = NULL; struct drm_crtc *iter; Index: src/sys/arch/arm/nvidia/tegra_nouveau.c diff -u src/sys/arch/arm/nvidia/tegra_nouveau.c:1.10 src/sys/arch/arm/nvidia/tegra_nouveau.c:1.11 --- src/sys/arch/arm/nvidia/tegra_nouveau.c:1.10 Tue May 30 22:00:25 2017 +++ src/sys/arch/arm/nvidia/tegra_nouveau.c Mon Aug 27 15:31:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_nouveau.c,v 1.10 2017/05/30 22:00:25 jmcneill Exp $ */ +/* $NetBSD: tegra_nouveau.c,v 1.11 2018/08/27 15:31:51 riastradh Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.10 2017/05/30 22:00:25 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.11 2018/08/27 15:31:51 riastradh Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -45,11 +45,15 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_nouvea #include <dev/fdt/fdtvar.h> #include <drm/drmP.h> -#include <engine/device.h> +#include <core/tegra.h> +#include <nvkm/engine/device/priv.h> +#include <nvkm/subdev/mc/priv.h> extern char *nouveau_config; extern char *nouveau_debug; -extern struct drm_driver *const nouveau_drm_driver; +extern struct drm_driver *const nouveau_drm_driver_stub; /* XXX */ +extern struct drm_driver *const nouveau_drm_driver_platform; /* XXX */ +static bool nouveau_driver_initialized = false; /* XXX */ static int tegra_nouveau_match(device_t, cfdata_t, void *); static void tegra_nouveau_attach(device_t, device_t, void *); @@ -57,48 +61,67 @@ static void tegra_nouveau_attach(device_ struct tegra_nouveau_softc { device_t sc_dev; bus_space_tag_t sc_bst; + struct { + bus_addr_t addr; + bus_size_t size; + } sc_resources[2]; bus_dma_tag_t sc_dmat; int sc_phandle; + void *sc_ih; struct clk *sc_clk_gpu; struct clk *sc_clk_pwr; struct fdtbus_reset *sc_rst_gpu; struct drm_device *sc_drm_dev; - struct platform_device sc_platform_dev; - struct nouveau_device *sc_nv_dev; + struct nvkm_device sc_nv_dev; }; static void tegra_nouveau_init(device_t); -static int tegra_nouveau_get_irq(struct drm_device *); -static const char *tegra_nouveau_get_name(struct drm_device *); static int tegra_nouveau_set_busid(struct drm_device *, struct drm_master *); -static int tegra_nouveau_irq_install(struct drm_device *, - irqreturn_t (*)(void *), - int, const char *, void *, - struct drm_bus_irq_cookie **); -static void tegra_nouveau_irq_uninstall(struct drm_device *, - struct drm_bus_irq_cookie *); - -static struct drm_bus drm_tegra_nouveau_bus = { - .bus_type = DRIVER_BUS_PLATFORM, - .get_irq = tegra_nouveau_get_irq, - .get_name = tegra_nouveau_get_name, - .set_busid = tegra_nouveau_set_busid, - .irq_install = tegra_nouveau_irq_install, - .irq_uninstall = tegra_nouveau_irq_uninstall -}; + +static int tegra_nouveau_intr(void *); + +static int nvkm_device_tegra_init(struct nvkm_device *); +static void nvkm_device_tegra_fini(struct nvkm_device *, bool); + +static bus_space_tag_t + nvkm_device_tegra_resource_tag(struct nvkm_device *, unsigned); +static bus_addr_t + nvkm_device_tegra_resource_addr(struct nvkm_device *, unsigned); +static bus_size_t + nvkm_device_tegra_resource_size(struct nvkm_device *, unsigned); CFATTACH_DECL_NEW(tegra_nouveau, sizeof(struct tegra_nouveau_softc), tegra_nouveau_match, tegra_nouveau_attach, NULL, NULL); +static const struct nvkm_device_func nvkm_device_tegra_func = { + .tegra = NULL, /* XXX */ + .dtor = NULL, + .init = nvkm_device_tegra_init, + .fini = nvkm_device_tegra_fini, + .resource_tag = nvkm_device_tegra_resource_tag, + .resource_addr = nvkm_device_tegra_resource_addr, + .resource_size = nvkm_device_tegra_resource_size, + .cpu_coherent = false, +}; + +static const struct nvkm_device_tegra_func gk20a_platform_data = { + .iommu_bit = 34, +}; + +static const struct of_compat_data compat_data[] = { + { "nvidia,gk20a", (uintptr_t)&gk20a_platform_data }, + { "nvidia,gm20b", (uintptr_t)&gk20a_platform_data }, + { NULL, 0 }, +}; + static int tegra_nouveau_match(device_t parent, cfdata_t cf, void *aux) { - const char * const compatible[] = { "nvidia,gk20a", NULL }; struct fdt_attach_args * const faa = aux; - return of_match_compatible(faa->faa_phandle, compatible); + return of_match_compat_data(faa->faa_phandle, compat_data); } static void @@ -107,8 +130,21 @@ tegra_nouveau_attach(device_t parent, de struct tegra_nouveau_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; prop_dictionary_t prop = device_properties(self); + const struct of_compat_data *data = + of_search_compatible(faa->faa_phandle, compat_data); + const struct nvkm_device_tegra_func *tegra_func = + (const void *)data->data; int error; + KASSERT(tegra_func != NULL); + + if (!nouveau_driver_initialized) { + *nouveau_drm_driver_platform = *nouveau_drm_driver_stub; + nouveau_drm_driver_platform->set_busid = + tegra_nouveau_set_busid; + nouveau_driver_initialized = true; + } + sc->sc_dev = self; sc->sc_bst = faa->faa_bst; sc->sc_dmat = faa->faa_dmat; @@ -158,9 +194,9 @@ tegra_nouveau_attach(device_t parent, de tegra_pmc_remove_clamping(PMC_PARTID_TD); fdtbus_reset_deassert(sc->sc_rst_gpu); - error = -nouveau_device_create(&sc->sc_platform_dev, - NOUVEAU_BUS_PLATFORM, -1, device_xname(self), - nouveau_config, nouveau_debug, &sc->sc_nv_dev); + error = -nvkm_device_ctor(&nvkm_device_tegra_func, NULL, self, + NVKM_DEVICE_TEGRA, -1, device_xname(self), + nouveau_config, nouveau_debug, true, true, ~0ULL, &sc->sc_nv_dev); if (error) { aprint_error_dev(self, "couldn't create nouveau device: %d\n", error); @@ -174,7 +210,7 @@ static void tegra_nouveau_init(device_t self) { struct tegra_nouveau_softc * const sc = device_private(self); - struct drm_driver * const driver = nouveau_drm_driver; + struct drm_driver * const driver = nouveau_drm_driver_platform; struct drm_device *dev; bus_addr_t addr[2], size[2]; int error; @@ -185,9 +221,6 @@ tegra_nouveau_init(device_t self) return; } - driver->kdriver.platform_device = &sc->sc_platform_dev; - driver->bus = &drm_tegra_nouveau_bus; - dev = drm_dev_alloc(driver, sc->sc_dev); if (dev == NULL) { aprint_error_dev(self, "couldn't allocate DRM device\n"); @@ -197,18 +230,11 @@ tegra_nouveau_init(device_t self) dev->bus_dmat = sc->sc_dmat; dev->dmat = dev->bus_dmat; dev->dmat_subregion_p = false; - dev->platformdev = &sc->sc_platform_dev; - dev->platformdev->id = -1; - dev->platformdev->pd_dev = sc->sc_dev; - dev->platformdev->dmat = sc->sc_dmat; - dev->platformdev->nresource = 2; - dev->platformdev->resource[0].tag = sc->sc_bst; - dev->platformdev->resource[0].start = addr[0]; - dev->platformdev->resource[0].len = size[0]; - dev->platformdev->resource[1].tag = sc->sc_bst; - dev->platformdev->resource[1].start = addr[1]; - dev->platformdev->resource[1].len = size[1]; + sc->sc_resources[0].addr = addr[0]; + sc->sc_resources[0].size = size[0]; + sc->sc_resources[1].addr = addr[1]; + sc->sc_resources[1].size = size[1]; error = -drm_dev_register(dev, 0); if (error) { @@ -224,24 +250,9 @@ tegra_nouveau_init(device_t self) } static int -tegra_nouveau_get_irq(struct drm_device *dev) -{ - return TEGRA_INTR_GPU; -} - -static const char *tegra_nouveau_get_name(struct drm_device *dev) -{ - return "tegra_nouveau"; -} - -static int tegra_nouveau_set_busid(struct drm_device *dev, struct drm_master *master) { - int id; - - id = dev->platformdev->id; - if (id < 0) - id = 0; + int id = 0; /* XXX device_unit(self)? */ master->unique = kmem_asprintf("platform:tegra_nouveau:%02d", id); if (master->unique == NULL) @@ -252,71 +263,81 @@ tegra_nouveau_set_busid(struct drm_devic } static int -tegra_nouveau_irq_install(struct drm_device *dev, - irqreturn_t (*handler)(void *), int flags, const char *name, void *arg, - struct drm_bus_irq_cookie **cookiep) +tegra_nouveau_intr(void *cookie) { - struct tegra_nouveau_softc * const sc = device_private(dev->dev); + struct tegra_nouveau_softc *sc = cookie; + struct nvkm_mc *mc = sc->sc_nv_dev.mc; + bool handled = false; + + if (__predict_true(mc)) { + nvkm_mc_intr_unarm(mc); + nvkm_mc_intr(mc, &handled); + nvkm_mc_intr_rearm(mc); + } + + return handled; +} + +static int +nvkm_device_tegra_init(struct nvkm_device *nvdev) +{ + struct tegra_nouveau_softc *sc = + container_of(nvdev, struct tegra_nouveau_softc, sc_nv_dev); + device_t self = sc->sc_dev; char intrstr[128]; - char *inames, *p; - u_int index; - void *ih; - int len, resid; - - len = OF_getproplen(sc->sc_phandle, "interrupt-names"); - if (len <= 0) { - aprint_error_dev(dev->dev, "no interrupt-names property\n"); + + if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); return -EIO; } - inames = kmem_alloc(len, KM_SLEEP); - if (OF_getprop(sc->sc_phandle, "interrupt-names", inames, len) != len) { - aprint_error_dev(dev->dev, "failed to get interrupt-names\n"); - kmem_free(inames, len); + sc->sc_ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_VM, + FDT_INTR_MPSAFE, tegra_nouveau_intr, sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "couldn't establish interrupt on %s\n", + intrstr); return -EIO; } - p = inames; - resid = len; - index = 0; - while (resid > 0) { - if (strcmp(name, p) == 0) - break; - const int slen = strlen(p) + 1; - p += slen; - len -= slen; - ++index; - } - kmem_free(inames, len); - if (len == 0) { - aprint_error_dev(dev->dev, "unknown interrupt name '%s'\n", - name); - return -EINVAL; - } - - if (!fdtbus_intr_str(sc->sc_phandle, index, intrstr, sizeof(intrstr))) { - aprint_error_dev(dev->dev, "failed to decode interrupt\n"); - return -ENXIO; - } - - ih = fdtbus_intr_establish(sc->sc_phandle, index, IPL_DRM, - FDT_INTR_MPSAFE, handler, arg); - if (ih == NULL) { - aprint_error_dev(dev->dev, - "failed to establish interrupt on %s\n", intrstr); - return -ENOENT; - } - aprint_normal_dev(dev->dev, "interrupting on %s\n", intrstr); - - *cookiep = (struct drm_bus_irq_cookie *)ih; + aprint_normal_dev(self, "interrupting on %s\n", intrstr); return 0; } static void -tegra_nouveau_irq_uninstall(struct drm_device *dev, - struct drm_bus_irq_cookie *cookie) +nvkm_device_tegra_fini(struct nvkm_device *nvdev, bool suspend) +{ + struct tegra_nouveau_softc *sc = + container_of(nvdev, struct tegra_nouveau_softc, sc_nv_dev); + + fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); +} + +static bus_space_tag_t +nvkm_device_tegra_resource_tag(struct nvkm_device *dev, unsigned bar) +{ + struct tegra_nouveau_softc *sc = + container_of(dev, struct tegra_nouveau_softc, sc_nv_dev); + + KASSERT(bar < 2); + return sc->sc_bst; +} + +static bus_addr_t +nvkm_device_tegra_resource_addr(struct nvkm_device *dev, unsigned bar) +{ + struct tegra_nouveau_softc *sc = + container_of(dev, struct tegra_nouveau_softc, sc_nv_dev); + + KASSERT(bar < 2); + return sc->sc_resources[bar].addr; +} + +static bus_size_t +nvkm_device_tegra_resource_size(struct nvkm_device *dev, unsigned bar) { - struct tegra_nouveau_softc * const sc = device_private(dev->dev); + struct tegra_nouveau_softc *sc = + container_of(dev, struct tegra_nouveau_softc, sc_nv_dev); - fdtbus_intr_disestablish(sc->sc_phandle, cookie); + KASSERT(bar < 2); + return sc->sc_resources[bar].size; }