This patch series for 5.6.y enables use of the xf86-video-armsoc-omap5 X11 driver [1] and the DRI3WSEGL plugin [2] for GC320-accelerated 2D display and 3D in X11 on the Pyra (with some appropriate TILER patches, in the Pyra repo).
The main outstanding issue is the lack of compatability between etnaviv and LPAE, due to swiotlb fragmentation from the long-lived mix of small and large buffers. It seems like this might have been fixed in 5.7, but still needs further investigation.
[1] https://github.com/julbouln/xf86-video-armsoc-omap5 [2] https://github.com/TexasInstruments/dri3wsegl
From: Matthijs van Duin matthijsvanduin@gmail.com
This fixes cases other than width=8k/stride=32k by using a proper sg_table with multiple entries for dmabufs, mapping each line to its correct TILER address.
Original-by: Matthijs van Duin matthijsvanduin@gmail.com Signed-off-by: David Shah dave@ds0.me --- drivers/gpu/drm/omapdrm/omap_gem.c | 79 ++++++++++++++++++++++- drivers/gpu/drm/omapdrm/omap_gem.h | 2 + drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | 31 ++------- 3 files changed, 83 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 66aa102faa7b..c1fe70cf98d8 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -70,8 +70,9 @@ struct omap_gem_object { refcount_t dma_addr_cnt;
/** - * If the buffer has been imported from a dmabuf the OMAP_DB_DMABUF flag - * is set and the sgt field is valid. + * buffer represented as sg table. It is valid if + * - the buffer is imported from dmabuf (OMAP_BO_MEM_DMABUF flag set) + * - the buffer is mapped through dmabuf (also increases dma_addr_cnt) */ struct sg_table *sgt;
@@ -894,6 +895,13 @@ static void omap_gem_unpin_locked(struct drm_gem_object *obj) return;
if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) { + + if (omap_obj->sgt) { + sg_free_table(omap_obj->sgt); + kfree(omap_obj->sgt); + omap_obj->sgt = NULL; + } + ret = tiler_unpin(omap_obj->block); if (ret) { dev_err(obj->dev->dev, @@ -1006,6 +1014,73 @@ int omap_gem_put_pages(struct drm_gem_object *obj) return 0; }
+struct sg_table *omap_gem_get_sg(struct drm_gem_object *obj) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + dma_addr_t addr; + struct sg_table *sgt; + struct scatterlist *sg; + unsigned int count, len, stride, i; + int ret; + + ret = omap_gem_pin(obj, &addr); + if (ret) + return ERR_PTR(ret); + + mutex_lock(&omap_obj->lock); + + sgt = omap_obj->sgt; + if (sgt) + goto out; + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + ret = -ENOMEM; + if (!sgt) + goto out_unpin; + + if (omap_obj->flags & OMAP_BO_TILED_MASK) { + enum tiler_fmt fmt = gem2fmt(omap_obj->flags); + len = omap_obj->width << (int)fmt; + count = omap_obj->height; + stride = tiler_stride(fmt, 0); + } else { + len = obj->size; + count = 1; + stride = 0; + } + + ret = sg_alloc_table(sgt, count, GFP_KERNEL); + if (ret) + goto out_free; + + for_each_sg(sgt->sgl, sg, count, i) { + sg_set_page(sg, phys_to_page(addr), len, offset_in_page(addr)); + sg_dma_address(sg) = addr; + sg_dma_len(sg) = len; + + addr += stride; + } + + omap_obj->sgt = sgt; +out: + mutex_unlock(&omap_obj->lock); + return sgt; + +out_free: + kfree(sgt); +out_unpin: + mutex_unlock(&omap_obj->lock); + omap_gem_unpin(obj); + return ERR_PTR(ret); +} + +void omap_gem_put_sg(struct drm_gem_object *obj, struct sg_table *sgt) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + BUG_ON(omap_obj->sgt != sgt); + omap_gem_unpin(obj); +} + #ifdef CONFIG_DRM_FBDEV_EMULATION /* * Get kernel virtual address for CPU access.. this more or less only diff --git a/drivers/gpu/drm/omapdrm/omap_gem.h b/drivers/gpu/drm/omapdrm/omap_gem.h index 729b7812a815..75371b4f485b 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.h +++ b/drivers/gpu/drm/omapdrm/omap_gem.h @@ -79,6 +79,8 @@ void omap_gem_unpin(struct drm_gem_object *obj); int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, bool remap); int omap_gem_put_pages(struct drm_gem_object *obj); +struct sg_table *omap_gem_get_sg(struct drm_gem_object *obj); +void omap_gem_put_sg(struct drm_gem_object *obj, struct sg_table *sgt);
u32 omap_gem_flags(struct drm_gem_object *obj); int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient, diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c index b319fe7f2371..7128ed44d2a0 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c @@ -21,45 +21,22 @@ static struct sg_table *omap_gem_map_dma_buf( { struct drm_gem_object *obj = attachment->dmabuf->priv; struct sg_table *sg; - dma_addr_t dma_addr; - int ret; - - sg = kzalloc(sizeof(*sg), GFP_KERNEL); - if (!sg) - return ERR_PTR(-ENOMEM); - - /* camera, etc, need physically contiguous.. but we need a - * better way to know this.. - */ - ret = omap_gem_pin(obj, &dma_addr); - if (ret) - goto out;
- ret = sg_alloc_table(sg, 1, GFP_KERNEL); - if (ret) - goto out; - - sg_init_table(sg->sgl, 1); - sg_dma_len(sg->sgl) = obj->size; - sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(dma_addr)), obj->size, 0); - sg_dma_address(sg->sgl) = dma_addr; + sg = omap_gem_get_sg(obj); + if (IS_ERR(sg)) + return sg;
/* this must be after omap_gem_pin() to ensure we have pages attached */ omap_gem_dma_sync_buffer(obj, dir);
return sg; -out: - kfree(sg); - return ERR_PTR(ret); }
static void omap_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *sg, enum dma_data_direction dir) { struct drm_gem_object *obj = attachment->dmabuf->priv; - omap_gem_unpin(obj); - sg_free_table(sg); - kfree(sg); + omap_gem_put_sg(obj, sg); }
static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer,
This adds the Vivante GC320 to the device tree and to the hwmod data.
Original-by: Robert Nelson robertcnelson@gmail.com Signed-off-by: David Shah dave@ds0.me --- arch/arm/boot/dts/omap5-board-common.dtsi | 4 +++ arch/arm/boot/dts/omap5.dtsi | 10 +++++++ arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 32 ++++++++++++++++++++++ 3 files changed, 46 insertions(+)
diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 62d8c3eb4547..efee0e4adfa3 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -785,3 +785,7 @@ hdmi_out: endpoint { }; }; }; + +&bb2d { + status = "ok"; +}; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 54af46254afc..bc5915689f8b 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -223,6 +223,16 @@ dmm@4e000000 { ti,hwmods = "dmm"; };
+ bb2d: bb2d@59000000 { + compatible = "vivante,gc"; + reg = <0x59000000 0x0700>; + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, // bus: DSS_L3_GICLK + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 13>; // core: BB2D_GFCLK + clock-names = "bus", "core"; + ti,hwmods = "bb2d"; + }; + emif1: emif@4c000000 { compatible = "ti,emif-4d5"; ti,hwmods = "emif1"; diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index ad398f6bc011..19eee76deddf 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -768,6 +768,37 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__sata = { .user = OCP_USER_MPU | OCP_USER_SDMA, };
+/* 'bb2d' class + * GC320 2D GPU + */ + +static struct omap_hwmod_class omap54xx_bb2d_hwmod_class = { + .name = "bb2d", +}; + +/* bb2d */ +static struct omap_hwmod omap54xx_bb2d_hwmod = { + .name = "bb2d", + .class = &omap54xx_bb2d_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dpll_core_h24x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_BB2D_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DSS_BB2D_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l3_main_1 -> bb2d */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__bb2d = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_bb2d_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* * Interfaces */ @@ -1029,6 +1060,7 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l3_main_2__l4_per, &omap54xx_l3_main_1__l4_wkup, &omap54xx_mpu__mpu_private, + &omap54xx_l3_main_1__bb2d, &omap54xx_l4_wkup__counter_32k, &omap54xx_l3_main_2__dss, &omap54xx_l3_main_2__dss_dispc,
I cannot reproduce the reported error, and disabling interrupts means anything waiting for the GPU to complete (the DRI3 plugin for example) has to wait for the 100ms timeout giving terrible framerates.
This also removes some dmesg-spam when interrupts are used.
Signed-off-by: David Shah dave@ds0.me --- drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/Makefile | 2 +- .../1.14.3699939/eurasia_km/services4/system/omap/sysconfig.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/Makefile b/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/Makefile index d6dbeb513566..2a1246f3c540 100644 --- a/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/Makefile +++ b/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/Makefile @@ -232,9 +232,9 @@ ccflags-y += -DPVR_DRI_DRM_PLATFORM_DEV ccflags-y += -DPVRSRV_NEED_PVR_DPF ccflags-y += -DMODULE # this disables some code in AcquireGPTimer in sysutils_linux.c ccflags-y += -DSUPPORT_DMABUF +ccflags-y += -DSYS_USING_INTERRUPTS # should probably be enabled but leads to paging errors, asynchronous external abort
# these must not be set or we can't compile successfully for omap -ccflags-n += -DSYS_USING_INTERRUPTS # should probably be enabled but leads to paging errors, asynchronous external abort ccflags-n += -DSUPPORT_DRI_DRM_EXT ccflags-n += -DSUPPORT_DRI_DRM_PLUGIN ccflags-n += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL diff --git a/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/services4/system/omap/sysconfig.c b/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/services4/system/omap/sysconfig.c index 4d50af33219d..5315eefe4069 100644 --- a/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/services4/system/omap/sysconfig.c +++ b/drivers/gpu/drm/pvrsgx/1.14.3699939/eurasia_km/services4/system/omap/sysconfig.c @@ -984,7 +984,6 @@ IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) { PVR_UNREFERENCED_PARAMETER(ui32ClearBits); PVR_UNREFERENCED_PARAMETER(psSysData); -printk("%s\n", __func__); #if defined(SYS_USING_INTERRUPTS) if (gpvOCPRegsLinAddr == IMG_NULL) {
Hi David, looks good to me. I'll pick it and try to back/forward port to 5.4, 5.7 and 5.8 asap.
BR and thanks, Nikolaus
Am 19.06.2020 um 17:34 schrieb David Shah dave@ds0.me:
This patch series for 5.6.y enables use of the xf86-video-armsoc-omap5 X11 driver [1] and the DRI3WSEGL plugin [2] for GC320-accelerated 2D display and 3D in X11 on the Pyra (with some appropriate TILER patches, in the Pyra repo).
The main outstanding issue is the lack of compatability between etnaviv and LPAE, due to swiotlb fragmentation from the long-lived mix of small and large buffers. It seems like this might have been fixed in 5.7, but still needs further investigation.
[1] https://github.com/julbouln/xf86-video-armsoc-omap5 [2] https://github.com/TexasInstruments/dri3wsegl
Kernel mailing list Kernel@pyra-handheld.com http://pyra-handheld.com/cgi-bin/mailman/listinfo/kernel