diff options
author | 2020-03-04 21:19:15 +0000 | |
---|---|---|
committer | 2020-03-04 21:19:15 +0000 | |
commit | ec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e (patch) | |
tree | 26aca4c5a8544552e1366b97455405701a3dd5ab | |
parent | Do not count pages mapped as PROT_NONE against the RLIMIT_DATA limit. (diff) | |
download | wireguard-openbsd-ec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e.tar.xz wireguard-openbsd-ec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e.zip |
Properly implement the page fault handler for CMA GEM buffers and actually
make drm(4) attach to rkdrm(4). This makes KMS work on the RK3399 SoC.
ok patrick@
-rw-r--r-- | sys/dev/fdt/rkdrm.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_gem_cma_helper.c | 53 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/drm/drmP.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h | 3 |
5 files changed, 45 insertions, 48 deletions
diff --git a/sys/dev/fdt/rkdrm.c b/sys/dev/fdt/rkdrm.c index ec8c1b1c678..ac12a48661b 100644 --- a/sys/dev/fdt/rkdrm.c +++ b/sys/dev/fdt/rkdrm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkdrm.c,v 1.1 2020/02/21 15:44:54 patrick Exp $ */ +/* $OpenBSD: rkdrm.c,v 1.2 2020/03/04 21:19:15 kettenis Exp $ */ /* $NetBSD: rk_drm.c,v 1.3 2019/12/15 01:00:58 mrg Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -72,8 +72,11 @@ void rkdrm_disable_vblank(struct drm_device *, unsigned int); int rkdrm_load(struct drm_device *, unsigned long); int rkdrm_unload(struct drm_device *); +int rkdrm_gem_fault(struct drm_gem_object *, struct uvm_faultinfo *, + off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int); + struct drm_driver rkdrm_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, + .driver_features = DRIVER_MODESET | DRIVER_GEM, .get_vblank_counter = rkdrm_get_vblank_counter, .enable_vblank = rkdrm_enable_vblank, @@ -82,7 +85,8 @@ struct drm_driver rkdrm_driver = { .dumb_create = drm_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, - /* XXX GEM stuff */ + .gem_free_object_unlocked = drm_gem_cma_free_object, + .gem_fault = drm_gem_cma_fault, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -113,6 +117,7 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux) { struct rkdrm_softc *sc = (struct rkdrm_softc *)self; struct fdt_attach_args *faa = aux; + struct drm_attach_args arg; sc->sc_dmat = faa->fa_dmat; sc->sc_iot = faa->fa_iot; @@ -120,6 +125,15 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux) printf("\n"); + memset(&arg, 0, sizeof(arg)); + arg.driver = &rkdrm_driver; + arg.drm = &sc->sc_ddev; + arg.dmat = faa->fa_dmat; + arg.bst = faa->fa_iot; + arg.busid = sc->sc_dev.dv_xname; + arg.busid_len = strlen(sc->sc_dev.dv_xname) + 1; + config_found_sm(self, &arg, drmprint, drmsubmatch); + config_mountroot(self, rkdrm_attachhook); } @@ -299,7 +313,7 @@ rkdrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) switch (cmd) { case WSDISPLAYIO_GTYPE: - *(u_int *)data = WSDISPLAY_TYPE_EFIFB; + *(u_int *)data = WSDISPLAY_TYPE_RKDRM; return 0; case WSDISPLAYIO_GINFO: wdf = (struct wsdisplay_fbinfo *)data; @@ -416,11 +430,6 @@ rkdrm_attachhook(struct device *dev) return; } - sc->sc_ddev.driver = &rkdrm_driver; - sc->sc_ddev.dev_private = sc; - sc->sc_ddev.bst = sc->sc_iot; - sc->sc_ddev.dmat = sc->sc_dmat; - drm_mode_config_init(&sc->sc_ddev); sc->sc_ddev.mode_config.min_width = 0; sc->sc_ddev.mode_config.min_height = 0; @@ -495,9 +504,7 @@ rkdrm_attachhook(struct device *dev) config_found_sm(&sc->sc_dev, &aa, wsemuldisplaydevprint, wsemuldisplaydevsubmatch); -#ifdef notyet drm_dev_register(&sc->sc_ddev, 0); -#endif } int diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index c5969e94e05..d34e7f4bef2 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_drv.c,v 1.172 2020/03/03 09:23:54 kettenis Exp $ */ +/* $OpenBSD: drm_drv.c,v 1.173 2020/03/04 21:19:15 kettenis Exp $ */ /*- * Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org> * Copyright © 2008 Intel Corporation @@ -87,8 +87,6 @@ int drm_detach(struct device *, int); void drm_quiesce(struct drm_device *); void drm_wakeup(struct drm_device *); int drm_activate(struct device *, int); -int drmprint(void *, const char *); -int drmsubmatch(struct device *, void *, void *); int drm_dequeue_event(struct drm_device *, struct drm_file *, size_t, struct drm_pending_event **); diff --git a/sys/dev/pci/drm/drm_gem_cma_helper.c b/sys/dev/pci/drm/drm_gem_cma_helper.c index 30bf992d263..8e0021c4ab7 100644 --- a/sys/dev/pci/drm/drm_gem_cma_helper.c +++ b/sys/dev/pci/drm/drm_gem_cma_helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_gem_cma_helper.c,v 1.1 2020/02/21 15:42:36 patrick Exp $ */ +/* $OpenBSD: drm_gem_cma_helper.c,v 1.2 2020/03/04 21:19:15 kettenis Exp $ */ /* $NetBSD: drm_gem_cma_helper.c,v 1.9 2019/11/05 23:29:28 jmcneill Exp $ */ /*- * Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca> @@ -76,10 +76,14 @@ drm_gem_cma_create_internal(struct drm_device *ddev, size_t size, #endif memset(obj->vaddr, 0, obj->dmasize); - drm_gem_private_object_init(ddev, &obj->base, size); + error = drm_gem_object_init(ddev, &obj->base, size); + if (error) + goto unload; return obj; +unload: + bus_dmamap_unload(obj->dmat, obj->dmamap); destroy: bus_dmamap_destroy(obj->dmat, obj->dmamap); unmap: @@ -189,51 +193,44 @@ done: return error; } -static int -drm_gem_cma_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, - struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type, - int flags) +int +drm_gem_cma_fault(struct drm_gem_object *gem_obj, struct uvm_faultinfo *ufi, + off_t offset, vaddr_t vaddr, vm_page_t *pps, int npages, int centeridx, + vm_prot_t access_type, int flags) { struct vm_map_entry *entry = ufi->entry; - struct uvm_object *uobj = entry->object.uvm_obj; - struct drm_gem_object *gem_obj = - container_of(uobj, struct drm_gem_object, uobj); struct drm_gem_cma_object *obj = to_drm_gem_cma_obj(gem_obj); - off_t curr_offset; - vaddr_t curr_va; + struct uvm_object *uobj = &obj->base.uobj; paddr_t paddr; int lcv, retval; vm_prot_t mapprot; - if (UVM_ET_ISCOPYONWRITE(entry)) - return EIO; - - curr_offset = entry->offset + (vaddr - entry->start); - curr_va = vaddr; + offset -= drm_vma_node_offset_addr(&obj->base.vma_node); + mapprot = ufi->entry->protection; retval = 0; - for (lcv = 0; lcv < npages; lcv++, curr_offset += PAGE_SIZE, - curr_va += PAGE_SIZE) { + for (lcv = 0; lcv < npages; lcv++, offset += PAGE_SIZE, + vaddr += PAGE_SIZE) { if ((flags & PGO_ALLPAGES) == 0 && lcv != centeridx) continue; + if (pps[lcv] == PGO_DONTCARE) continue; paddr = bus_dmamem_mmap(obj->dmat, obj->dmasegs, 1, - curr_offset, access_type, 0); + offset, access_type, BUS_DMA_NOCACHE); if (paddr == -1) { - retval = EIO; + retval = VM_PAGER_BAD; break; } - mapprot = ufi->entry->protection; - if (pmap_enter(ufi->orig_map->pmap, curr_va, paddr, mapprot, - PMAP_CANFAIL | mapprot) != 0) { + if (pmap_enter(ufi->orig_map->pmap, vaddr, paddr, + mapprot, PMAP_CANFAIL | mapprot) != 0) { pmap_update(ufi->orig_map->pmap); uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap, uobj, NULL); uvm_wait("drm_gem_cma_fault"); - return ERESTART; + return VM_PAGER_REFAULT; } } @@ -243,14 +240,6 @@ drm_gem_cma_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, return retval; } -#ifdef notyet -const struct uvm_pagerops drm_gem_cma_uvm_ops = { - .pgo_reference = drm_gem_pager_reference, - .pgo_detach = drm_gem_pager_detach, - .pgo_fault = drm_gem_cma_fault, -}; -#endif - struct sg_table * drm_gem_cma_prime_get_sg_table(struct drm_gem_object *gem_obj) { diff --git a/sys/dev/pci/drm/include/drm/drmP.h b/sys/dev/pci/drm/include/drm/drmP.h index 041c14c797a..832d016032b 100644 --- a/sys/dev/pci/drm/include/drm/drmP.h +++ b/sys/dev/pci/drm/include/drm/drmP.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drmP.h,v 1.7 2020/03/03 09:23:54 kettenis Exp $ */ +/* $OpenBSD: drmP.h,v 1.8 2020/03/04 21:19:15 kettenis Exp $ */ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com */ @@ -239,6 +239,8 @@ int drm_linux_acpi_notify(struct aml_node *, int, void *); int drm_pciprobe(struct pci_attach_args *, const struct drm_pcidev * ); struct drm_device *drm_attach_pci(struct drm_driver *, struct pci_attach_args *, int, int, struct device *, struct drm_device *); +int drmprint(void *, const char *); +int drmsubmatch(struct device *, void *, void *); dev_type_ioctl(drmioctl); dev_type_read(drmread); dev_type_poll(drmpoll); diff --git a/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h b/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h index df4e4de031a..b388a0d99c7 100644 --- a/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h +++ b/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h @@ -11,7 +11,8 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *, struct drm_device *, struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *, size_t); -extern const struct uvm_pagerops drm_gem_cma_uvm_ops; +int drm_gem_cma_fault(struct drm_gem_object *, struct uvm_faultinfo *, + off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int); struct drm_gem_cma_object { struct drm_gem_object base; |