diff options
Diffstat (limited to 'drivers/gpu/drm/vc4')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_bo.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_dpi.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_dsi.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_gem.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_hdmi.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_hvs.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_irq.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_render_cl.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_validate.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_validate_shaders.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_vec.c | 6 |
15 files changed, 151 insertions, 89 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 3f6704cf6608..af29432a6471 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -6,7 +6,8 @@ * published by the Free Software Foundation. */ -/* DOC: VC4 GEM BO management support. +/** + * DOC: VC4 GEM BO management support * * The VC4 GPU architecture (both scanout and rendering) has direct * access to system memory with no MMU in between. To support it, we @@ -186,6 +187,8 @@ out: /** * vc4_gem_create_object - Implementation of driver->gem_create_object. + * @dev: DRM device + * @size: Size in bytes of the memory the object will reference * * This lets the CMA helpers allocate object structs for us, and keep * our BO stats correct. @@ -208,21 +211,22 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) } struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, - bool from_cache) + bool allow_unzeroed) { size_t size = roundup(unaligned_size, PAGE_SIZE); struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_gem_cma_object *cma_obj; + struct vc4_bo *bo; if (size == 0) return ERR_PTR(-EINVAL); /* First, try to get a vc4_bo from the kernel BO cache. */ - if (from_cache) { - struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size); - - if (bo) - return bo; + bo = vc4_bo_get_from_cache(dev, size); + if (bo) { + if (!allow_unzeroed) + memset(bo->base.vaddr, 0, bo->base.base.size); + return bo; } cma_obj = drm_gem_cma_create(dev, size); @@ -313,6 +317,14 @@ void vc4_free_object(struct drm_gem_object *gem_bo) goto out; } + /* If this object was partially constructed but CMA allocation + * had failed, just free it. + */ + if (!bo->base.vaddr) { + vc4_bo_destroy(bo); + goto out; + } + cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); if (!cache_list) { vc4_bo_destroy(bo); diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 0c06844af445..24edd0c22cc9 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -11,12 +11,13 @@ * * In VC4, the Pixel Valve is what most closely corresponds to the * DRM's concept of a CRTC. The PV generates video timings from the - * output's clock plus its configuration. It pulls scaled pixels from + * encoder's clock plus its configuration. It pulls scaled pixels from * the HVS at that timing, and feeds it to the encoder. * * However, the DRM CRTC also collects the configuration of all the - * DRM planes attached to it. As a result, this file also manages - * setup of the VC4 HVS's display elements on the CRTC. + * DRM planes attached to it. As a result, the CRTC is also + * responsible for writing the display list for the HVS channel that + * the CRTC will use. * * The 2835 has 3 different pixel valves. pv0 in the audio power * domain feeds DSI0 or DPI, while pv1 feeds DS1 or SMI. pv2 in the @@ -654,9 +655,8 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, } } -int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id) +static int vc4_enable_vblank(struct drm_crtc *crtc) { - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); CRTC_WRITE(PV_INTEN, PV_INT_VFP_START); @@ -664,9 +664,8 @@ int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id) return 0; } -void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id) +static void vc4_disable_vblank(struct drm_crtc *crtc) { - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); CRTC_WRITE(PV_INTEN, 0); @@ -857,6 +856,8 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = { .atomic_duplicate_state = vc4_crtc_duplicate_state, .atomic_destroy_state = vc4_crtc_destroy_state, .gamma_set = vc4_crtc_gamma_set, + .enable_vblank = vc4_enable_vblank, + .disable_vblank = vc4_disable_vblank, }; static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index 1e1f6b8184d0..71435796c710 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -18,7 +18,8 @@ * DOC: VC4 DPI module * * The VC4 DPI hardware supports MIPI DPI type 4 and Nokia ViSSI - * signals, which are routed out to GPIO0-27 with the ALT2 function. + * signals. On BCM2835, these can be routed out to GPIO0-27 with the + * ALT2 function. */ #include "drm_atomic_helper.h" @@ -144,17 +145,6 @@ static const struct { DPI_REG(DPI_ID), }; -static void vc4_dpi_dump_regs(struct vc4_dpi *dpi) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dpi_regs); i++) { - DRM_INFO("0x%04x (%s): 0x%08x\n", - dpi_regs[i].reg, dpi_regs[i].name, - DPI_READ(dpi_regs[i].reg)); - } -} - #ifdef CONFIG_DEBUG_FS int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused) { @@ -416,8 +406,6 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data) if (IS_ERR(dpi->regs)) return PTR_ERR(dpi->regs); - vc4_dpi_dump_regs(dpi); - if (DPI_READ(DPI_ID) != DPI_ID_VALUE) { dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", DPI_READ(DPI_ID), DPI_ID_VALUE); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index a459745e96f7..205c1961ffb4 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -7,6 +7,22 @@ * published by the Free Software Foundation. */ +/** + * DOC: Broadcom VC4 Graphics Driver + * + * The Broadcom VideoCore 4 (present in the Raspberry Pi) contains a + * OpenGL ES 2.0-compatible 3D engine called V3D, and a highly + * configurable display output pipeline that supports HDMI, DSI, DPI, + * and Composite TV output. + * + * The 3D engine also has an interface for submitting arbitrary + * compute shader-style jobs using the same shader processor as is + * used for vertex and fragment shaders in GLES 2.0. However, given + * that the hardware isn't able to expose any standard interfaces like + * OpenGL compute shaders or OpenCL, it isn't supported by this + * driver. + */ + #include <linux/clk.h> #include <linux/component.h> #include <linux/device.h> @@ -137,9 +153,6 @@ static struct drm_driver vc4_drm_driver = { .irq_postinstall = vc4_irq_postinstall, .irq_uninstall = vc4_irq_uninstall, - .enable_vblank = vc4_enable_vblank, - .disable_vblank = vc4_disable_vblank, - .get_vblank_counter = drm_vblank_no_hw_counter, .get_scanout_position = vc4_crtc_get_scanoutpos, .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 0e59f3ee1b83..dffce6293d87 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -444,8 +444,6 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); /* vc4_crtc.c */ extern struct platform_driver vc4_crtc_driver; -int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id); -void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id); bool vc4_event_pending(struct drm_crtc *crtc); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 2736b0331beb..160f981d1cf4 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -771,16 +771,14 @@ static const struct drm_connector_helper_funcs vc4_dsi_connector_helper_funcs = static struct drm_connector *vc4_dsi_connector_init(struct drm_device *dev, struct vc4_dsi *dsi) { - struct drm_connector *connector = NULL; + struct drm_connector *connector; struct vc4_dsi_connector *dsi_connector; - int ret = 0; dsi_connector = devm_kzalloc(dev->dev, sizeof(*dsi_connector), GFP_KERNEL); - if (!dsi_connector) { - ret = -ENOMEM; - goto fail; - } + if (!dsi_connector) + return ERR_PTR(-ENOMEM); + connector = &dsi_connector->base; dsi_connector->dsi = dsi; @@ -796,12 +794,6 @@ static struct drm_connector *vc4_dsi_connector_init(struct drm_device *dev, drm_mode_connector_attach_encoder(connector, dsi->encoder); return connector; - -fail: - if (connector) - vc4_dsi_connector_destroy(connector); - - return ERR_PTR(ret); } static void vc4_dsi_encoder_destroy(struct drm_encoder *encoder) @@ -1461,8 +1453,9 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void *data) } /** - * Exposes clocks generated by the analog PHY that are consumed by - * CPRMAN (clk-bcm2835.c). + * vc4_dsi_init_phy_clocks - Exposes clocks generated by the analog + * PHY that are consumed by CPRMAN (clk-bcm2835.c). + * @dsi: DSI encoder */ static int vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 1eef98c3331d..e9c381c42139 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -512,9 +512,18 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) } /** - * Looks up a bunch of GEM handles for BOs and stores the array for - * use in the command validator that actually writes relocated - * addresses pointing to them. + * vc4_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects + * referenced by the job. + * @dev: DRM device + * @file_priv: DRM file for this fd + * @exec: V3D job being set up + * + * The command validator needs to reference BOs by their index within + * the submitted job's BO list. This does the validation of the job's + * BO list and reference counting for the lifetime of the job. + * + * Note that this function doesn't need to unreference the BOs on + * failure, because that will happen at vc4_complete_exec() time. */ static int vc4_cl_lookup_bos(struct drm_device *dev, @@ -847,9 +856,16 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, } /** - * Submits a command list to the VC4. + * vc4_submit_cl_ioctl() - Submits a job (frame) to the VC4. + * @dev: DRM device + * @data: ioctl argument + * @file_priv: DRM file for this fd * - * This is what is called batchbuffer emitting on other hardware. + * This is the main entrypoint for userspace to submit a 3D frame to + * the GPU. Userspace provides the binner command list (if + * applicable), and the kernel sets up the render command list to draw + * to the framebuffer described in the ioctl, using the command lists + * that the 3D engine's binner will produce. */ int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 93d5994f3a04..1be1e8304720 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -20,9 +20,26 @@ /** * DOC: VC4 Falcon HDMI module * - * The HDMI core has a state machine and a PHY. Most of the unit - * operates off of the HSM clock from CPRMAN. It also internally uses - * the PLLH_PIX clock for the PHY. + * The HDMI core has a state machine and a PHY. On BCM2835, most of + * the unit operates off of the HSM clock from CPRMAN. It also + * internally uses the PLLH_PIX clock for the PHY. + * + * HDMI infoframes are kept within a small packet ram, where each + * packet can be individually enabled for including in a frame. + * + * HDMI audio is implemented entirely within the HDMI IP block. A + * register in the HDMI encoder takes SPDIF frames from the DMA engine + * and transfers them over an internal MAI (multi-channel audio + * interconnect) bus to the encoder side for insertion into the video + * blank regions. + * + * The driver's HDMI encoder does not yet support power management. + * The HDMI encoder's power domain and the HSM/pixel clocks are kept + * continuously running, and only the HDMI logic and packet ram are + * powered off/on at disable/enable time. + * + * The driver does not yet support CEC control, though the HDMI + * encoder block has CEC support. */ #include "drm_atomic_helper.h" diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index f7f7677f6d8d..fd421ba3c5d7 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -9,12 +9,12 @@ /** * DOC: VC4 HVS module. * - * The HVS is the piece of hardware that does translation, scaling, - * colorspace conversion, and compositing of pixels stored in - * framebuffers into a FIFO of pixels going out to the Pixel Valve - * (CRTC). It operates at the system clock rate (the system audio - * clock gate, specifically), which is much higher than the pixel - * clock rate. + * The Hardware Video Scaler (HVS) is the piece of hardware that does + * translation, scaling, colorspace conversion, and compositing of + * pixels stored in framebuffers into a FIFO of pixels going out to + * the Pixel Valve (CRTC). It operates at the system clock rate (the + * system audio clock gate, specifically), which is much higher than + * the pixel clock rate. * * There is a single global HVS, with multiple output FIFOs that can * be consumed by the PVs. This file just manages the resources for diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 094bc6a475c1..cdc6e6760705 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -21,7 +21,8 @@ * IN THE SOFTWARE. */ -/** DOC: Interrupt management for the V3D engine. +/** + * DOC: Interrupt management for the V3D engine * * We have an interrupt status register (V3D_INTCTL) which reports * interrupts, and where writing 1 bits clears those interrupts. diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index f7a229df572d..110224c3a3ac 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -20,6 +20,7 @@ #include "vc4_drv.h" #include "vc4_regs.h" +#include "drm_atomic.h" #include "drm_atomic_helper.h" #include "drm_fb_cma_helper.h" #include "drm_plane_helper.h" @@ -769,12 +770,6 @@ vc4_update_plane(struct drm_plane *plane, if (!plane_state) goto out; - /* If we're changing the cursor contents, do that in the - * normal vblank-synced atomic path. - */ - if (fb != plane_state->fb) - goto out; - /* No configuring new scaling in the fast path. */ if (crtc_w != plane_state->crtc_w || crtc_h != plane_state->crtc_h || @@ -783,6 +778,11 @@ vc4_update_plane(struct drm_plane *plane, goto out; } + if (fb != plane_state->fb) { + drm_atomic_set_fb_for_plane(plane->state, fb); + vc4_plane_async_set_fb(plane, fb); + } + /* Set the cursor's position on the screen. This is the * expected change from the drm_mode_cursor_universal() * helper. diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c index 5cdd003605f5..4339471f517f 100644 --- a/drivers/gpu/drm/vc4/vc4_render_cl.c +++ b/drivers/gpu/drm/vc4/vc4_render_cl.c @@ -24,6 +24,10 @@ /** * DOC: Render command list generation * + * In the V3D hardware, render command lists are what load and store + * tiles of a framebuffer and optionally call out to binner-generated + * command lists to do the 3D drawing for that tile. + * * In the VC4 driver, render command list generation is performed by the * kernel instead of userspace. We do this because validating a * user-submitted command list is hard to get right and has high CPU overhead, diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c index 9fd171c361c2..da6f1e138e8d 100644 --- a/drivers/gpu/drm/vc4/vc4_validate.c +++ b/drivers/gpu/drm/vc4/vc4_validate.c @@ -22,21 +22,25 @@ */ /** - * Command list validator for VC4. + * DOC: Command list validator for VC4. * - * The VC4 has no IOMMU between it and system memory. So, a user with - * access to execute command lists could escalate privilege by + * Since the VC4 has no IOMMU between it and system memory, a user + * with access to execute command lists could escalate privilege by * overwriting system memory (drawing to it as a framebuffer) or - * reading system memory it shouldn't (reading it as a texture, or - * uniform data, or vertex data). + * reading system memory it shouldn't (reading it as a vertex buffer + * or index buffer) * - * This validates command lists to ensure that all accesses are within - * the bounds of the GEM objects referenced. It explicitly whitelists - * packets, and looks at the offsets in any address fields to make - * sure they're constrained within the BOs they reference. + * We validate binner command lists to ensure that all accesses are + * within the bounds of the GEM objects referenced by the submitted + * job. It explicitly whitelists packets, and looks at the offsets in + * any address fields to make sure they're contained within the BOs + * they reference. * - * Note that because of the validation that's happening anyway, this - * is where GEM relocation processing happens. + * Note that because CL validation is already reading the + * user-submitted CL and writing the validated copy out to the memory + * that the GPU will actually read, this is also where GEM relocation + * processing (turning BO references into actual addresses for the GPU + * to use) happens. */ #include "uapi/drm/vc4_drm.h" @@ -84,8 +88,12 @@ utile_height(int cpp) } /** - * The texture unit decides what tiling format a particular miplevel is using - * this function, so we lay out our miptrees accordingly. + * size_is_lt() - Returns whether a miplevel of the given size will + * use the lineartile (LT) tiling layout rather than the normal T + * tiling layout. + * @width: Width in pixels of the miplevel + * @height: Height in pixels of the miplevel + * @cpp: Bytes per pixel of the pixel format */ static bool size_is_lt(uint32_t width, uint32_t height, int cpp) diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 5dba13dd1e9b..0b2df5c6efb4 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -24,16 +24,21 @@ /** * DOC: Shader validator for VC4. * - * The VC4 has no IOMMU between it and system memory, so a user with - * access to execute shaders could escalate privilege by overwriting - * system memory (using the VPM write address register in the - * general-purpose DMA mode) or reading system memory it shouldn't - * (reading it as a texture, or uniform data, or vertex data). + * Since the VC4 has no IOMMU between it and system memory, a user + * with access to execute shaders could escalate privilege by + * overwriting system memory (using the VPM write address register in + * the general-purpose DMA mode) or reading system memory it shouldn't + * (reading it as a texture, uniform data, or direct-addressed TMU + * lookup). * - * This walks over a shader BO, ensuring that its accesses are - * appropriately bounded, and recording how many texture accesses are - * made and where so that we can do relocations for them in the + * The shader validator walks over a shader's BO, ensuring that its + * accesses are appropriately bounded, and recording where texture + * accesses are made so that we can do relocations for them in the * uniform stream. + * + * Shader BO are immutable for their lifetimes (enforced by not + * allowing mmaps, GEM prime export, or rendering to from a CL), so + * this validation is only performed at BO creation time. */ #include "vc4_drv.h" diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 32bb8ef985fb..09c1e05765fa 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -16,6 +16,12 @@ /** * DOC: VC4 SDTV module + * + * The VEC encoder generates PAL or NTSC composite video output. + * + * TV mode selection is done by an atomic property on the encoder, + * because a drm_mode_modeinfo is insufficient to distinguish between + * PAL and PAL-M or NTSC and NTSC-J. */ #include <drm/drm_atomic_helper.h> |