Module Name: src Committed By: jmcneill Date: Sun Dec 13 22:05:52 UTC 2015
Modified Files: src/sys/arch/arm/nvidia: tegra_nouveau.c Log Message: attach nouveau to fdt To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 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_nouveau.c diff -u src/sys/arch/arm/nvidia/tegra_nouveau.c:1.7 src/sys/arch/arm/nvidia/tegra_nouveau.c:1.8 --- src/sys/arch/arm/nvidia/tegra_nouveau.c:1.7 Tue Oct 27 13:21:19 2015 +++ src/sys/arch/arm/nvidia/tegra_nouveau.c Sun Dec 13 22:05:52 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_nouveau.c,v 1.7 2015/10/27 13:21:19 riastradh Exp $ */ +/* $NetBSD: tegra_nouveau.c,v 1.8 2015/12/13 22:05:52 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -26,10 +26,8 @@ * SUCH DAMAGE. */ -#include "locators.h" - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.7 2015/10/27 13:21:19 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.8 2015/12/13 22:05:52 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -42,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_nouvea #include <arm/nvidia/tegra_reg.h> #include <arm/nvidia/tegra_var.h> +#include <dev/fdt/fdtvar.h> + #include <drm/drmP.h> #include <engine/device.h> @@ -54,7 +54,9 @@ static void tegra_nouveau_attach(device_ struct tegra_nouveau_softc { device_t sc_dev; + bus_space_tag_t sc_bst; bus_dma_tag_t sc_dmat; + int sc_phandle; struct drm_device *sc_drm_dev; struct platform_device sc_platform_dev; struct nouveau_device *sc_nv_dev; @@ -88,22 +90,24 @@ CFATTACH_DECL_NEW(tegra_nouveau, sizeof( static int tegra_nouveau_match(device_t parent, cfdata_t cf, void *aux) { - return 1; + const char * const compatible[] = { "nvidia,gk20a", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); } static void tegra_nouveau_attach(device_t parent, device_t self, void *aux) { struct tegra_nouveau_softc * const sc = device_private(self); - struct tegraio_attach_args * const tio = aux; -#if notyet - const struct tegra_locators * const loc = &tio->tio_loc; -#endif + struct fdt_attach_args * const faa = aux; prop_dictionary_t prop = device_properties(self); int error; sc->sc_dev = self; - sc->sc_dmat = tio->tio_dmat; + sc->sc_bst = faa->faa_bst; + sc->sc_dmat = faa->faa_dmat; + sc->sc_phandle = faa->faa_phandle; aprint_naive("\n"); aprint_normal(": GPU\n"); @@ -131,9 +135,15 @@ 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_device *dev; - bus_space_tag_t bst = &armv7_generic_bs_tag; + bus_addr_t addr[2], size[2]; int error; + if (fdtbus_get_reg(sc->sc_phandle, 0, &addr[0], &size[0]) != 0 || + fdtbus_get_reg(sc->sc_phandle, 1, &addr[1], &size[1]) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + driver->kdriver.platform_device = &sc->sc_platform_dev; driver->bus = &drm_tegra_nouveau_bus; @@ -142,7 +152,7 @@ tegra_nouveau_init(device_t self) aprint_error_dev(self, "couldn't allocate DRM device\n"); return; } - dev->bst = bst; + dev->bst = sc->sc_bst; dev->bus_dmat = sc->sc_dmat; dev->dmat = dev->bus_dmat; dev->dmat_subregion_p = false; @@ -152,13 +162,12 @@ tegra_nouveau_init(device_t self) dev->platformdev->pd_dev = sc->sc_dev; dev->platformdev->dmat = sc->sc_dmat; dev->platformdev->nresource = 2; - dev->platformdev->resource[0].tag = bst; - dev->platformdev->resource[0].start = TEGRA_GPU_BASE; - dev->platformdev->resource[0].len = 0x01000000; - dev->platformdev->resource[1].tag = bst; - dev->platformdev->resource[1].start = TEGRA_GPU_BASE + - dev->platformdev->resource[0].len; - dev->platformdev->resource[1].len = 0x01000000; + 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]; error = -drm_dev_register(dev, 0); if (error) { @@ -206,18 +215,58 @@ tegra_nouveau_irq_install(struct drm_dev irqreturn_t (*handler)(void *), int flags, const char *name, void *arg, struct drm_bus_irq_cookie **cookiep) { + struct tegra_nouveau_softc * const sc = device_private(dev->dev); + char intrstr[128]; + char *inames, *p; + u_int index; void *ih; - int irq = TEGRA_INTR_GPU; + int len, resid; + + len = OF_getproplen(sc->sc_phandle, "interrupt-names"); + if (len <= 0) { + aprint_error_dev(dev->dev, "no interrupt-names property\n"); + return -EIO; + } - ih = intr_establish(irq, IPL_DRM, IST_LEVEL, handler, arg); + 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); + 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, - "couldn't establish interrupt (%s)\n", name); + "failed to establish interrupt on %s\n", intrstr); return -ENOENT; } - aprint_normal_dev(dev->dev, "interrupting on irq %d (%s)\n", - irq, name); + aprint_normal_dev(dev->dev, "interrupting on %s\n", intrstr); + *cookiep = (struct drm_bus_irq_cookie *)ih; return 0; } @@ -226,5 +275,7 @@ static void tegra_nouveau_irq_uninstall(struct drm_device *dev, struct drm_bus_irq_cookie *cookie) { - intr_disestablish(cookie); + struct tegra_nouveau_softc * const sc = device_private(dev->dev); + + fdtbus_intr_disestablish(sc->sc_phandle, cookie); }