diff options
133 files changed, 2633 insertions, 980 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml new file mode 100644 index 000000000000..3791c9f4ebab --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP DWC HDMI TX Encoder + +maintainers: + - Lucas Stach <l.stach@pengutronix.de> + +description: + The i.MX8MP HDMI transmitter is a Synopsys DesignWare + HDMI 2.0a TX controller IP. + +allOf: + - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml# + +properties: + compatible: + enum: + - fsl,imx8mp-hdmi-tx + + reg-io-width: + const: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: iahb + - const: isfr + - const: cec + - const: pix + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Parallel RGB input port + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: HDMI output port + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - power-domains + - ports + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/imx8mp-clock.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/power/imx8mp-power.h> + + hdmi@32fd8000 { + compatible = "fsl,imx8mp-hdmi-tx"; + reg = <0x32fd8000 0x7eff>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_HDMI_APB>, + <&clk IMX8MP_CLK_HDMI_REF_266M>, + <&clk IMX8MP_CLK_32K>, + <&hdmi_tx_phy>; + clock-names = "iahb", "isfr", "cec", "pix"; + power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>; + reg-io-width = <1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + + hdmi_tx_from_pvi: endpoint { + remote-endpoint = <&pvi_to_hdmi_tx>; + }; + }; + + port@1 { + reg = <1>; + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml index 6ec6d287bff4..c93878b6d718 100644 --- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: SN65DSI86 DSI to eDP bridge chip maintainers: - - Sandeep Panda <spanda@codeaurora.org> + - Douglas Anderson <dianders@chromium.org> description: | The Texas Instruments SN65DSI86 bridge takes MIPI DSI in and outputs eDP. diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml new file mode 100644 index 000000000000..56da1636014c --- /dev/null +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi-pvi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP HDMI Parallel Video Interface + +maintainers: + - Lucas Stach <l.stach@pengutronix.de> + +description: + The HDMI parallel video interface is a timing and sync generator block in the + i.MX8MP SoC, that sits between the video source and the HDMI TX controller. + +properties: + compatible: + const: fsl,imx8mp-hdmi-pvi + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Input from the LCDIF controller. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Output to the HDMI TX controller. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - interrupts + - power-domains + - ports + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/power/imx8mp-power.h> + + display-bridge@32fc4000 { + compatible = "fsl,imx8mp-hdmi-pvi"; + reg = <0x32fc4000 0x44>; + interrupt-parent = <&irqsteer_hdmi>; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + pvi_from_lcdif3: endpoint { + remote-endpoint = <&lcdif3_to_pvi>; + }; + }; + + port@1 { + reg = <1>; + pvi_to_hdmi_tx: endpoint { + remote-endpoint = <&hdmi_tx_from_pvi>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/panel/boe,th101mb31ig002-28a.yaml b/Documentation/devicetree/bindings/display/panel/boe,th101mb31ig002-28a.yaml new file mode 100644 index 000000000000..32df26cbfeed --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/boe,th101mb31ig002-28a.yaml @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/boe,th101mb31ig002-28a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BOE TH101MB31IG002-28A WXGA DSI Display Panel + +maintainers: + - Manuel Traut <manut@mecka.net> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + enum: + # BOE TH101MB31IG002-28A 10.1" WXGA TFT LCD panel + - boe,th101mb31ig002-28a + + reg: true + backlight: true + enable-gpios: true + power-supply: true + port: true + rotation: true + +required: + - compatible + - reg + - enable-gpios + - power-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + compatible = "boe,th101mb31ig002-28a"; + reg = <0>; + backlight = <&backlight_lcd0>; + enable-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; + rotation = <90>; + power-supply = <&vcc_3v3>; + port { + panel_in_dsi: endpoint { + remote-endpoint = <&dsi_out_con>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt36672e.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt36672e.yaml new file mode 100644 index 000000000000..dc4672f3d01d --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672e.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/novatek,nt36672e.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36672E LCD DSI Panel + +maintainers: + - Ritesh Kumar <quic_riteshk@quicinc.com> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: novatek,nt36672e + + reg: + maxItems: 1 + description: DSI virtual channel + + vddi-supply: true + avdd-supply: true + avee-supply: true + port: true + reset-gpios: true + backlight: true + +required: + - compatible + - reg + - vddi-supply + - avdd-supply + - avee-supply + - reset-gpios + - port + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + dsi { + #address-cells = <1>; + #size-cells = <0>; + panel@0 { + compatible = "novatek,nt36672e"; + reg = <0>; + + reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>; + + vddi-supply = <&vreg_l8c_1p8>; + avdd-supply = <&disp_avdd>; + avee-supply = <&disp_avee>; + + backlight = <&pwm_backlight>; + + port { + panel0_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 634a10c6f2dd..233c620722dd 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -141,6 +141,8 @@ properties: - edt,etm0700g0edh6 # Emerging Display Technology Corp. LVDS WSVGA TFT Display with capacitive touch - edt,etml0700y5dha + # Emerging Display Technology Corp. 10.1" LVDS WXGA TFT Display with capacitive touch + - edt,etml1010g3dra # Emerging Display Technology Corp. 5.7" VGA TFT LCD panel with # capacitive touch - edt,etmv570g2dhu diff --git a/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml index fa745a6f4456..772399067515 100644 --- a/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml +++ b/Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml @@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Visionox model RM69299 Panels maintainers: - - Harigovindan P <harigovi@codeaurora.org> + - Abhinav Kumar <quic_abhinavk@quicinc.com> + - Jessica Zhang <quic_jesszhan@quicinc.com> description: | This binding is for display panels using a Visionox RM692999 panel. diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 5fd20a306718..335de7fcddee 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -153,18 +153,6 @@ Managed Resources .. kernel-doc:: include/drm/drm_managed.h :internal: -Bus-specific Device Registration and PCI Support ------------------------------------------------- - -A number of functions are provided to help with device registration. The -functions deal with PCI and platform devices respectively and are only -provided for historical reasons. These are all deprecated and shouldn't -be used in new drivers. Besides that there's a few helpers for pci -drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_pci.c - :export: - Open/Close, File Operations and IOCTLs ====================================== diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst index f05eccd2c07c..b7c0baf97dbe 100644 --- a/Documentation/gpu/introduction.rst +++ b/Documentation/gpu/introduction.rst @@ -164,6 +164,8 @@ Conference talks Slides and articles ------------------- +* `The Linux graphics stack in a nutshell, part 1 <https://lwn.net/Articles/955376/>`_ - Thomas Zimmermann (2023) +* `The Linux graphics stack in a nutshell, part 2 <https://lwn.net/Articles/955708/>`_ - Thomas Zimmermann (2023) * `Understanding the Linux Graphics Stack <https://bootlin.com/doc/training/graphics/graphics-slides.pdf>`_ - Bootlin (2022) * `DRM KMS overview <https://wiki.st.com/stm32mpu/wiki/DRM_KMS_overview>`_ - STMicroelectronics (2021) * `Linux graphic stack <https://studiopixl.com/2017-05-13/linux-graphic-stack-an-overview>`_ - Nathan Gauër (2017) diff --git a/Documentation/gpu/rfc/index.rst b/Documentation/gpu/rfc/index.rst index e4f7b005138d..476719771eef 100644 --- a/Documentation/gpu/rfc/index.rst +++ b/Documentation/gpu/rfc/index.rst @@ -31,7 +31,3 @@ host such documentation: .. toctree:: i915_vm_bind.rst - -.. toctree:: - - xe.rst diff --git a/MAINTAINERS b/MAINTAINERS index bf0e94937818..3bc7e122a094 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7308,6 +7308,7 @@ F: drivers/gpu/drm/xlnx/ DRM GPU SCHEDULER M: Luben Tuikov <ltuikov89@gmail.com> +M: Matthew Brost <matthew.brost@intel.com> L: dri-devel@lists.freedesktop.org S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index e0fd99e61a2d..0393a9bba3a8 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -102,7 +102,7 @@ static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(1); * * * Drivers are allowed to call dma_fence_wait() from their &mmu_notifier * respectively &mmu_interval_notifier callbacks. This means any code required - * for fence completeion cannot allocate memory with GFP_NOFS or GFP_NOIO. + * for fence completion cannot allocate memory with GFP_NOFS or GFP_NOIO. * Only GFP_ATOMIC is permissible, which might fail. * * Note that only GPU drivers have a reasonable excuse for both requiring @@ -522,7 +522,7 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout) EXPORT_SYMBOL(dma_fence_wait_timeout); /** - * dma_fence_release - default relese function for fences + * dma_fence_release - default release function for fences * @kref: &dma_fence.recfount * * This is the default release functions for &dma_fence. Drivers shouldn't call @@ -974,8 +974,8 @@ void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline) EXPORT_SYMBOL(dma_fence_set_deadline); /** - * dma_fence_describe - Dump fence describtion into seq_file - * @fence: the 6fence to describe + * dma_fence_describe - Dump fence description into seq_file + * @fence: the fence to describe * @seq: the seq_file to put the textual description into * * Dump a textual description of the fence and it's state into the seq_file. diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index eb8b733065b2..e2869fb31140 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -405,7 +405,7 @@ static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor) * * Beware that the iterator can be restarted. Code which accumulates statistics * or similar needs to check for this with dma_resv_iter_is_restarted(). For - * this reason prefer the locked dma_resv_iter_first() whenver possible. + * this reason prefer the locked dma_resv_iter_first() whenever possible. * * Returns the first fence from an unlocked dma_resv obj. */ @@ -428,7 +428,7 @@ EXPORT_SYMBOL(dma_resv_iter_first_unlocked); * * Beware that the iterator can be restarted. Code which accumulates statistics * or similar needs to check for this with dma_resv_iter_is_restarted(). For - * this reason prefer the locked dma_resv_iter_next() whenver possible. + * this reason prefer the locked dma_resv_iter_next() whenever possible. * * Returns the next fence from an unlocked dma_resv obj. */ diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 6ec33d36f3a4..872edb47bb53 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -19,8 +19,7 @@ menuconfig DRM # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate # device and dmabuf fd. Let's make sure that is available for our userspace. select KCMP - select VIDEO_CMDLINE - select VIDEO_NOMODESET + select VIDEO help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index b9674c57c436..82b4b2019fca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -329,7 +329,8 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, ring->eop_gpu_addr = kiq->eop_gpu_addr; ring->no_scheduler = true; - sprintf(ring->name, "kiq_%d.%d.%d.%d", xcc_id, ring->me, ring->pipe, ring->queue); + snprintf(ring->name, sizeof(ring->name), "kiq_%d.%d.%d.%d", + xcc_id, ring->me, ring->pipe, ring->queue); r = amdgpu_ring_init(adev, ring, 1024, irq, AMDGPU_CP_KIQ_IRQ_DRIVER0, AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 425cebcc5cbf..b671b0665492 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -220,9 +220,6 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain) placement->num_placement = c; placement->placement = places; - - placement->num_busy_placement = c; - placement->busy_placement = places; } /** @@ -1397,8 +1394,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) AMDGPU_GEM_DOMAIN_GTT); /* Avoid costly evictions; only set GTT as a busy placement */ - abo->placement.num_busy_placement = 1; - abo->placement.busy_placement = &abo->placements[1]; + abo->placements[0].flags |= TTM_PL_FLAG_DESIRED; r = ttm_bo_validate(bo, &abo->placement, &ctx); if (unlikely(r == -EBUSY || r == -ERESTARTSYS)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 75c9fd2c6c2a..8722beba494e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -102,23 +102,19 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, /* Don't handle scatter gather BOs */ if (bo->type == ttm_bo_type_sg) { placement->num_placement = 0; - placement->num_busy_placement = 0; return; } /* Object isn't an AMDGPU object so ignore */ if (!amdgpu_bo_is_amdgpu_bo(bo)) { placement->placement = &placements; - placement->busy_placement = &placements; placement->num_placement = 1; - placement->num_busy_placement = 1; return; } abo = ttm_to_amdgpu_bo(bo); if (abo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) { placement->num_placement = 0; - placement->num_busy_placement = 0; return; } @@ -128,13 +124,13 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, case AMDGPU_PL_OA: case AMDGPU_PL_DOORBELL: placement->num_placement = 0; - placement->num_busy_placement = 0; return; case TTM_PL_VRAM: if (!adev->mman.buffer_funcs_enabled) { /* Move to system memory */ amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); + } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && amdgpu_bo_in_cpu_visible_vram(abo)) { @@ -149,8 +145,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, AMDGPU_GEM_DOMAIN_CPU); abo->placements[0].fpfn = adev->gmc.visible_vram_size >> PAGE_SHIFT; abo->placements[0].lpfn = 0; - abo->placement.busy_placement = &abo->placements[1]; - abo->placement.num_busy_placement = 1; + abo->placements[0].flags |= TTM_PL_FLAG_DESIRED; } else { /* Move to GTT memory */ amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT | @@ -966,8 +961,6 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) /* allocate GART space */ placement.num_placement = 1; placement.placement = &placements; - placement.num_busy_placement = 1; - placement.busy_placement = &placements; placements.fpfn = 0; placements.lpfn = adev->gmc.gart_size >> PAGE_SHIFT; placements.mem_type = TTM_PL_TT; diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c index 483c28c7fc99..c83486cf6b15 100644 --- a/drivers/gpu/drm/bridge/chrontel-ch7033.c +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c @@ -230,14 +230,14 @@ static const struct drm_connector_funcs ch7033_connector_funcs = { static int ch7033_connector_get_modes(struct drm_connector *connector) { struct ch7033_priv *priv = conn_to_ch7033_priv(connector); - struct edid *edid; + const struct drm_edid *drm_edid; int ret; - edid = drm_bridge_get_edid(priv->next_bridge, connector); - drm_connector_update_edid_property(connector, edid); - if (edid) { - ret = drm_add_edid_modes(connector, edid); - kfree(edid); + drm_edid = drm_bridge_edid_read(priv->next_bridge, connector); + drm_edid_connector_update(connector, drm_edid); + if (drm_edid) { + ret = drm_edid_connector_add_modes(connector); + drm_edid_free(drm_edid); } else { ret = drm_add_modes_noedid(connector, 1920, 1080); drm_set_preferred_mode(connector, 1024, 768); diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 5a4f3d58501e..5965e8027529 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -3,6 +3,24 @@ if ARCH_MXC || COMPILE_TEST config DRM_IMX_LDB_HELPER tristate +config DRM_IMX8MP_DW_HDMI_BRIDGE + tristate "Freescale i.MX8MP HDMI-TX bridge support" + depends on OF + depends on COMMON_CLK + select DRM_DW_HDMI + select DRM_IMX8MP_HDMI_PVI + select PHY_FSL_SAMSUNG_HDMI_PHY + help + Choose this to enable support for the internal HDMI encoder found + on the i.MX8MP SoC. + +config DRM_IMX8MP_HDMI_PVI + tristate "Freescale i.MX8MP HDMI PVI bridge support" + depends on OF + help + Choose this to enable support for the internal HDMI TX Parallel + Video Interface found on the Freescale i.MX8MP SoC. + config DRM_IMX8QM_LDB tristate "Freescale i.MX8QM LVDS display bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index 2b0c2e44aa1b..edb0a7b71b30 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -1,4 +1,6 @@ obj-$(CONFIG_DRM_IMX_LDB_HELPER) += imx-ldb-helper.o +obj-$(CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE) += imx8mp-hdmi-tx.o +obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o obj-$(CONFIG_DRM_IMX8QM_LDB) += imx8qm-ldb.o obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c new file mode 100644 index 000000000000..f2a09c879e3d --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_crtc.h> +#include <linux/bitfield.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#define HTX_PVI_CTRL 0x0 +#define PVI_CTRL_OP_VSYNC_POL BIT(18) +#define PVI_CTRL_OP_HSYNC_POL BIT(17) +#define PVI_CTRL_OP_DE_POL BIT(16) +#define PVI_CTRL_INP_VSYNC_POL BIT(14) +#define PVI_CTRL_INP_HSYNC_POL BIT(13) +#define PVI_CTRL_INP_DE_POL BIT(12) +#define PVI_CTRL_MODE_MASK GENMASK(2, 1) +#define PVI_CTRL_MODE_LCDIF 2 +#define PVI_CTRL_EN BIT(0) + +struct imx8mp_hdmi_pvi { + struct drm_bridge bridge; + struct device *dev; + struct drm_bridge *next_bridge; + void __iomem *regs; +}; + +static inline struct imx8mp_hdmi_pvi * +to_imx8mp_hdmi_pvi(struct drm_bridge *bridge) +{ + return container_of(bridge, struct imx8mp_hdmi_pvi, bridge); +} + +static int imx8mp_hdmi_pvi_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + + return drm_bridge_attach(bridge->encoder, pvi->next_bridge, + bridge, flags); +} + +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct drm_atomic_state *state = bridge_state->base.state; + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + struct drm_connector_state *conn_state; + const struct drm_display_mode *mode; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + u32 bus_flags = 0, val; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + conn_state = drm_atomic_get_new_connector_state(state, connector); + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + + if (WARN_ON(pm_runtime_resume_and_get(pvi->dev))) + return; + + mode = &crtc_state->adjusted_mode; + + val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL; + + if (pvi->next_bridge->timings) + bus_flags = pvi->next_bridge->timings->input_bus_flags; + else if (bridge_state) + bus_flags = bridge_state->input_bus_cfg.flags; + + if (bus_flags & DRM_BUS_FLAG_DE_HIGH) + val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL; + + writel(val, pvi->regs + HTX_PVI_CTRL); +} + +static void imx8mp_hdmi_pvi_bridge_disable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + + writel(0x0, pvi->regs + HTX_PVI_CTRL); + + pm_runtime_put(pvi->dev); +} + +static u32 * +imx8mp_hdmi_pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); + struct drm_bridge *next_bridge = pvi->next_bridge; + struct drm_bridge_state *next_state; + + if (!next_bridge->funcs->atomic_get_input_bus_fmts) + return NULL; + + next_state = drm_atomic_get_new_bridge_state(crtc_state->state, + next_bridge); + + return next_bridge->funcs->atomic_get_input_bus_fmts(next_bridge, + next_state, + crtc_state, + conn_state, + output_fmt, + num_input_fmts); +} + +static const struct drm_bridge_funcs imx_hdmi_pvi_bridge_funcs = { + .attach = imx8mp_hdmi_pvi_bridge_attach, + .atomic_enable = imx8mp_hdmi_pvi_bridge_enable, + .atomic_disable = imx8mp_hdmi_pvi_bridge_disable, + .atomic_get_input_bus_fmts = imx8mp_hdmi_pvi_bridge_get_input_bus_fmts, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, +}; + +static int imx8mp_hdmi_pvi_probe(struct platform_device *pdev) +{ + struct device_node *remote; + struct imx8mp_hdmi_pvi *pvi; + + pvi = devm_kzalloc(&pdev->dev, sizeof(*pvi), GFP_KERNEL); + if (!pvi) + return -ENOMEM; + + platform_set_drvdata(pdev, pvi); + pvi->dev = &pdev->dev; + + pvi->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pvi->regs)) + return PTR_ERR(pvi->regs); + + /* Get the next bridge in the pipeline. */ + remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1); + if (!remote) + return -EINVAL; + + pvi->next_bridge = of_drm_find_bridge(remote); + of_node_put(remote); + + if (!pvi->next_bridge) + return dev_err_probe(&pdev->dev, -EPROBE_DEFER, + "could not find next bridge\n"); + + pm_runtime_enable(&pdev->dev); + + /* Register the bridge. */ + pvi->bridge.funcs = &imx_hdmi_pvi_bridge_funcs; + pvi->bridge.of_node = pdev->dev.of_node; + pvi->bridge.timings = pvi->next_bridge->timings; + + drm_bridge_add(&pvi->bridge); + + return 0; +} + +static int imx8mp_hdmi_pvi_remove(struct platform_device *pdev) +{ + struct imx8mp_hdmi_pvi *pvi = platform_get_drvdata(pdev); + + drm_bridge_remove(&pvi->bridge); + + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static const struct of_device_id imx8mp_hdmi_pvi_match[] = { + { + .compatible = "fsl,imx8mp-hdmi-pvi", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, imx8mp_hdmi_pvi_match); + +static struct platform_driver imx8mp_hdmi_pvi_driver = { + .probe = imx8mp_hdmi_pvi_probe, + .remove = imx8mp_hdmi_pvi_remove, + .driver = { + .name = "imx-hdmi-pvi", + .of_match_table = imx8mp_hdmi_pvi_match, + }, +}; +module_platform_driver(imx8mp_hdmi_pvi_driver); + +MODULE_DESCRIPTION("i.MX8MP HDMI TX Parallel Video Interface bridge driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c new file mode 100644 index 000000000000..89fc432ac611 --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <linux/clk.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <drm/bridge/dw_hdmi.h> +#include <drm/drm_modes.h> + +struct imx8mp_hdmi { + struct dw_hdmi_plat_data plat_data; + struct dw_hdmi *dw_hdmi; + struct clk *pixclk; +}; + +static enum drm_mode_status +imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data; + + if (mode->clock < 13500) + return MODE_CLOCK_LOW; + + if (mode->clock > 297000) + return MODE_CLOCK_HIGH; + + if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) != + mode->clock * 1000) + return MODE_CLOCK_RANGE; + + /* We don't support double-clocked and Interlaced modes */ + if ((mode->flags & DRM_MODE_FLAG_DBLCLK) || + (mode->flags & DRM_MODE_FLAG_INTERLACE)) + return MODE_BAD; + + return MODE_OK; +} + +static int imx8mp_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *display, + const struct drm_display_mode *mode) +{ + return 0; +} + +static void imx8mp_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data) +{ +} + +static void im8mp_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) +{ + /* + * Just release PHY core from reset, all other power management is done + * by the PHY driver. + */ + dw_hdmi_phy_gen1_reset(hdmi); + + dw_hdmi_phy_setup_hpd(hdmi, data); +} + +static const struct dw_hdmi_phy_ops imx8mp_hdmi_phy_ops = { + .init = imx8mp_hdmi_phy_init, + .disable = imx8mp_hdmi_phy_disable, + .setup_hpd = im8mp_hdmi_phy_setup_hpd, + .read_hpd = dw_hdmi_phy_read_hpd, + .update_hpd = dw_hdmi_phy_update_hpd, +}; + +static int imx8mp_dw_hdmi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dw_hdmi_plat_data *plat_data; + struct imx8mp_hdmi *hdmi; + + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + plat_data = &hdmi->plat_data; + + hdmi->pixclk = devm_clk_get(dev, "pix"); + if (IS_ERR(hdmi->pixclk)) + return dev_err_probe(dev, PTR_ERR(hdmi->pixclk), + "Unable to get pixel clock\n"); + + plat_data->mode_valid = imx8mp_hdmi_mode_valid; + plat_data->phy_ops = &imx8mp_hdmi_phy_ops; + plat_data->phy_name = "SAMSUNG HDMI TX PHY"; + plat_data->priv_data = hdmi; + plat_data->phy_force_vendor = true; + + hdmi->dw_hdmi = dw_hdmi_probe(pdev, plat_data); + if (IS_ERR(hdmi->dw_hdmi)) + return PTR_ERR(hdmi->dw_hdmi); + + platform_set_drvdata(pdev, hdmi); + + return 0; +} + +static int imx8mp_dw_hdmi_remove(struct platform_device *pdev) +{ + struct imx8mp_hdmi *hdmi = platform_get_drvdata(pdev); + + dw_hdmi_remove(hdmi->dw_hdmi); + + return 0; +} + +static int __maybe_unused imx8mp_dw_hdmi_pm_suspend(struct device *dev) +{ + return 0; +} + +static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) +{ + struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_resume(hdmi->dw_hdmi); + + return 0; +} + +static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, + imx8mp_dw_hdmi_pm_resume) +}; + +static const struct of_device_id imx8mp_dw_hdmi_of_table[] = { + { .compatible = "fsl,imx8mp-hdmi-tx" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx8mp_dw_hdmi_of_table); + +static struct platform_driver imx8mp_dw_hdmi_platform_driver = { + .probe = imx8mp_dw_hdmi_probe, + .remove = imx8mp_dw_hdmi_remove, + .driver = { + .name = "imx8mp-dw-hdmi-tx", + .of_match_table = imx8mp_dw_hdmi_of_table, + .pm = &imx8mp_dw_hdmi_pm_ops, + }, +}; + +module_platform_driver(imx8mp_dw_hdmi_platform_driver); + +MODULE_DESCRIPTION("i.MX8MP HDMI encoder driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c index 273157428c82..e7c4bef74aa4 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -440,16 +440,16 @@ lt8912_connector_mode_valid(struct drm_connector *connector, static int lt8912_connector_get_modes(struct drm_connector *connector) { - struct edid *edid; + const struct drm_edid *drm_edid; int ret = -1; int num = 0; struct lt8912 *lt = connector_to_lt8912(connector); u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; - edid = drm_bridge_get_edid(lt->hdmi_port, connector); - if (edid) { - drm_connector_update_edid_property(connector, edid); - num = drm_add_edid_modes(connector, edid); + drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector); + drm_edid_connector_update(connector, drm_edid); + if (drm_edid) { + num = drm_edid_connector_add_modes(connector); } else { return ret; } @@ -459,7 +459,7 @@ static int lt8912_connector_get_modes(struct drm_connector *connector) if (ret) num = ret; - kfree(edid); + drm_edid_free(drm_edid); return num; } @@ -620,8 +620,8 @@ lt8912_bridge_detect(struct drm_bridge *bridge) return lt8912_check_cable_status(lt); } -static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge, - struct drm_connector *connector) +static const struct drm_edid *lt8912_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) { struct lt8912 *lt = bridge_to_lt8912(bridge); @@ -630,7 +630,7 @@ static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge, * given to the hdmi connector node. */ if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID) - return drm_bridge_get_edid(lt->hdmi_port, connector); + return drm_bridge_edid_read(lt->hdmi_port, connector); dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n"); return NULL; @@ -642,7 +642,7 @@ static const struct drm_bridge_funcs lt8912_bridge_funcs = { .mode_set = lt8912_bridge_mode_set, .enable = lt8912_bridge_enable, .detect = lt8912_bridge_detect, - .get_edid = lt8912_bridge_get_edid, + .edid_read = lt8912_bridge_edid_read, }; static int lt8912_bridge_resume(struct device *dev) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 9663601ce098..b9205d14d943 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -18,6 +18,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_edid.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> #include <drm/drm_print.h> diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index e971b75e90ad..4eaf99618749 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -21,6 +21,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_edid.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -294,12 +295,12 @@ static int lt9611uxc_connector_get_modes(struct drm_connector *connector) { struct lt9611uxc *lt9611uxc = connector_to_lt9611uxc(connector); unsigned int count; - struct edid *edid; + const struct drm_edid *drm_edid; - edid = drm_bridge_get_edid(<9611uxc->bridge, connector); - drm_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); - kfree(edid); + drm_edid = drm_bridge_edid_read(<9611uxc->bridge, connector); + drm_edid_connector_update(connector, drm_edid); + count = drm_edid_connector_add_modes(connector); + drm_edid_free(drm_edid); return count; } diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 6a10aa5c85f5..95fedc68b0ae 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -96,6 +96,7 @@ #define DSIM_MFLUSH_VS BIT(29) /* This flag is valid only for exynos3250/3472/5260/5430 */ #define DSIM_CLKLANE_STOP BIT(30) +#define DSIM_NON_CONTINUOUS_CLKLANE BIT(31) /* DSIM_ESCMODE */ #define DSIM_TX_TRIGGER_RST BIT(4) @@ -945,8 +946,12 @@ static int samsung_dsim_init_link(struct samsung_dsim *dsi) * power consumption. */ if (driver_data->has_clklane_stop && - dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) + dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { + if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) + reg |= DSIM_NON_CONTINUOUS_CLKLANE; + reg |= DSIM_CLKLANE_STOP; + } samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg); lanes_mask = BIT(dsi->lanes) - 1; @@ -1498,6 +1503,7 @@ static void samsung_dsim_atomic_disable(struct drm_bridge *bridge, if (!(dsi->state & DSIM_STATE_ENABLED)) return; + samsung_dsim_set_display_enable(dsi, false); dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; } @@ -1506,8 +1512,6 @@ static void samsung_dsim_atomic_post_disable(struct drm_bridge *bridge, { struct samsung_dsim *dsi = bridge_to_dsi(bridge); - samsung_dsim_set_display_enable(dsi, false); - dsi->state &= ~DSIM_STATE_ENABLED; pm_runtime_put_sync(dsi->dev); } diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c index cbe8e778d7c7..5813a2c4fc5e 100644 --- a/drivers/gpu/drm/bridge/simple-bridge.c +++ b/drivers/gpu/drm/bridge/simple-bridge.c @@ -51,18 +51,20 @@ drm_connector_to_simple_bridge(struct drm_connector *connector) static int simple_bridge_get_modes(struct drm_connector *connector) { struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector); - struct edid *edid; + const struct drm_edid *drm_edid; int ret; if (sbridge->next_bridge->ops & DRM_BRIDGE_OP_EDID) { - edid = drm_bridge_get_edid(sbridge->next_bridge, connector); - if (!edid) + drm_edid = drm_bridge_edid_read(sbridge->next_bridge, connector); + if (!drm_edid) DRM_INFO("EDID read failed. Fallback to standard modes\n"); } else { - edid = NULL; + drm_edid = NULL; } - if (!edid) { + drm_edid_connector_update(connector, drm_edid); + + if (!drm_edid) { /* * In case we cannot retrieve the EDIDs (missing or broken DDC * bus from the next bridge), fallback on the XGA standards and @@ -73,9 +75,8 @@ static int simple_bridge_get_modes(struct drm_connector *connector) return ret; } - drm_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); + ret = drm_edid_connector_add_modes(connector); + drm_edid_free(drm_edid); return ret; } diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index aca5bb0866f8..ca74a20015b3 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -31,6 +31,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_edid.h> #include <drm/drm_of.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index eb0d82a91cb9..f10ba91dc252 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -617,9 +617,14 @@ static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock) continue; for (i_post = 0; i_post < ARRAY_SIZE(ext_div); i_post++) { for (div = 1; div <= 16; div++) { - u32 clk; + u32 clk, iclk; u64 tmp; + /* PCLK PLL input unit clock ... 6..40 MHz */ + iclk = refclk / (div * ext_div[i_pre]); + if (iclk < 6000000 || iclk > 40000000) + continue; + tmp = pixelclock * ext_div[i_pre] * ext_div[i_post] * div; do_div(tmp, refclk); diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index 28848a8eb42e..c7bef5c23927 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -50,18 +50,20 @@ drm_connector_to_tfp410(struct drm_connector *connector) static int tfp410_get_modes(struct drm_connector *connector) { struct tfp410 *dvi = drm_connector_to_tfp410(connector); - struct edid *edid; + const struct drm_edid *drm_edid; int ret; if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) { - edid = drm_bridge_get_edid(dvi->next_bridge, connector); - if (!edid) + drm_edid = drm_bridge_edid_read(dvi->next_bridge, connector); + if (!drm_edid) DRM_INFO("EDID read failed. Fallback to standard modes\n"); } else { - edid = NULL; + drm_edid = NULL; } - if (!edid) { + drm_edid_connector_update(connector, drm_edid); + + if (!drm_edid) { /* * No EDID, fallback on the XGA standard modes and prefer a mode * pretty much anything can handle. @@ -71,11 +73,9 @@ static int tfp410_get_modes(struct drm_connector *connector) return ret; } - drm_connector_update_edid_property(connector, edid); - - ret = drm_add_edid_modes(connector, edid); + ret = drm_edid_connector_add_modes(connector); - kfree(edid); + drm_edid_free(drm_edid); return ret; } diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index f73f3471e94e..106f2d40d222 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -26,6 +26,7 @@ if [[ "$KERNEL_ARCH" = "arm64" ]]; then DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dtb" + DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dtb" elif [[ "$KERNEL_ARCH" = "arm" ]]; then GCC_ARCH="arm-linux-gnueabihf" DEBIAN_ARCH="armhf" diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml index dac92cc2777c..084e3ff8e3f4 100644 --- a/drivers/gpu/drm/ci/gitlab-ci.yml +++ b/drivers/gpu/drm/ci/gitlab-ci.yml @@ -1,6 +1,6 @@ variables: DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa - DRM_CI_COMMIT_SHA: &drm-ci-commit-sha edfbf74df1d4d6ce54ffe24566108be0e1a98c3d + DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 9d162de9a05155e1c4041857a5848842749164cf UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm TARGET_BRANCH: drm-next @@ -25,7 +25,9 @@ variables: # per-job artifact storage on MinIO JOB_ARTIFACTS_BASE: ${PIPELINE_ARTIFACTS_BASE}/${CI_JOB_ID} # default kernel for rootfs before injecting the current kernel tree - KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/gfx-ci/linux/v6.4.12-for-mesa-ci-f6b4ad45f48d + KERNEL_REPO: "gfx-ci/linux" + KERNEL_TAG: "v6.6.4-for-mesa-ci-e4f4c500f7fb" + KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/${KERNEL_REPO}/${KERNEL_TAG} LAVA_TAGS: subset-1-gfx LAVA_JOB_PRIORITY: 30 @@ -133,6 +135,11 @@ stages: - if: &is-pre-merge-for-marge '$GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"' when: on_success +.never-post-merge-rules: + rules: + - if: *is-post-merge + when: never + # Rule to filter for only scheduled pipelines. .scheduled_pipeline-rules: rules: @@ -150,6 +157,7 @@ stages: .build-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] # Run automatically once all dependency jobs have passed - when: on_success @@ -157,6 +165,7 @@ stages: .container+build-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] - when: manual .ci-deqp-artifacts: @@ -175,6 +184,7 @@ stages: .container-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] # Run pipeline by default in the main project if any CI pipeline # configuration files were changed, to ensure docker images are up to date - if: *is-post-merge diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml index 2c9a1838e728..355b794ef2b1 100644 --- a/drivers/gpu/drm/ci/test.yml +++ b/drivers/gpu/drm/ci/test.yml @@ -82,20 +82,35 @@ tags: - $RUNNER_TAG -msm:sc7180: +.msm-sc7180: extends: - .lava-igt:arm64 stage: msm - parallel: 4 variables: DRIVER_NAME: msm - DEVICE_TYPE: sc7180-trogdor-lazor-limozeen - DTB: sc7180-trogdor-lazor-limozeen-nots-r5 BOOT_METHOD: depthcharge KERNEL_IMAGE_TYPE: "" - GPU_VERSION: sc7180 + +msm:sc7180-trogdor-lazor-limozeen: + extends: + - .msm-sc7180 + parallel: 4 + variables: + DEVICE_TYPE: sc7180-trogdor-lazor-limozeen + DTB: sc7180-trogdor-lazor-limozeen-nots-r5 + GPU_VERSION: ${DEVICE_TYPE} RUNNER_TAG: mesa-ci-x86-64-lava-sc7180-trogdor-lazor-limozeen +msm:sc7180-trogdor-kingoftown: + extends: + - .msm-sc7180 + parallel: 6 + variables: + DEVICE_TYPE: sc7180-trogdor-kingoftown + DTB: sc7180-trogdor-kingoftown + GPU_VERSION: ${DEVICE_TYPE} + RUNNER_TAG: mesa-ci-x86-64-lava-sc7180-trogdor-kingoftown + msm:apq8016: extends: - .baremetal-igt-arm64 @@ -324,6 +339,7 @@ virtio_gpu:none: GPU_VERSION: none extends: - .test-gl + - .test-rules tags: - kvm script: diff --git a/drivers/gpu/drm/ci/testlist.txt b/drivers/gpu/drm/ci/testlist.txt index f82cd90372f4..eaeb751bb0ad 100644 --- a/drivers/gpu/drm/ci/testlist.txt +++ b/drivers/gpu/drm/ci/testlist.txt @@ -2910,3 +2910,52 @@ kms_writeback@writeback-invalid-parameters kms_writeback@writeback-fb-id kms_writeback@writeback-check-output prime_mmap_kms@buffer-sharing +msm_shrink@copy-gpu-sanitycheck-8 +msm_shrink@copy-gpu-sanitycheck-32 +msm_shrink@copy-gpu-8 +msm_shrink@copy-gpu-32 +msm_shrink@copy-gpu-madvise-8 +msm_shrink@copy-gpu-madvise-32 +msm_shrink@copy-gpu-oom-8 +msm_shrink@copy-gpu-oom-32 +msm_shrink@copy-mmap-sanitycheck-8 +msm_shrink@copy-mmap-sanitycheck-32 +msm_shrink@copy-mmap-8 +msm_shrink@copy-mmap-32 +msm_shrink@copy-mmap-madvise-8 +msm_shrink@copy-mmap-madvise-32 +msm_shrink@copy-mmap-oom-8 +msm_shrink@copy-mmap-oom-32 +msm_shrink@copy-mmap-dmabuf-sanitycheck-8 +msm_shrink@copy-mmap-dmabuf-sanitycheck-32 +msm_shrink@copy-mmap-dmabuf-8 +msm_shrink@copy-mmap-dmabuf-32 +msm_shrink@copy-mmap-dmabuf-madvise-8 +msm_shrink@copy-mmap-dmabuf-madvise-32 +msm_shrink@copy-mmap-dmabuf-oom-8 +msm_shrink@copy-mmap-dmabuf-oom-32 +msm_mapping@ring +msm_mapping@sqefw +msm_mapping@shadow +msm_submitoverhead@submitbench-10-bos +msm_submitoverhead@submitbench-10-bos-no-implicit-sync +msm_submitoverhead@submitbench-100-bos +msm_submitoverhead@submitbench-100-bos-no-implicit-sync +msm_submitoverhead@submitbench-250-bos +msm_submitoverhead@submitbench-250-bos-no-implicit-sync +msm_submitoverhead@submitbench-500-bos +msm_submitoverhead@submitbench-500-bos-no-implicit-sync +msm_submitoverhead@submitbench-1000-bos +msm_submitoverhead@submitbench-1000-bos-no-implicit-sync +msm_recovery@hangcheck +msm_recovery@gpu-fault +msm_recovery@gpu-fault-parallel +msm_recovery@iova-fault +msm_submit@empty-submit +msm_submit@invalid-queue-submit +msm_submit@invalid-flags-submit +msm_submit@invalid-in-fence-submit +msm_submit@invalid-duplicate-bo-submit +msm_submit@invalid-cmd-idx-submit +msm_submit@invalid-cmd-type-submit +msm_submit@valid-submit diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt index d39d254c935e..44a5c62dedad 100644 --- a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt @@ -6,8 +6,6 @@ kms_cursor_legacy@all-pipes-single-bo,Fail kms_cursor_legacy@all-pipes-single-move,Fail kms_cursor_legacy@all-pipes-torture-bo,Fail kms_cursor_legacy@all-pipes-torture-move,Fail -kms_cursor_legacy@forked-bo,Fail -kms_cursor_legacy@forked-move,Fail kms_cursor_legacy@pipe-A-forked-bo,Fail kms_cursor_legacy@pipe-A-forked-move,Fail kms_cursor_legacy@pipe-A-single-bo,Fail @@ -18,3 +16,4 @@ kms_force_connector_basic@force-edid,Fail kms_hdmi_inject@inject-4k,Fail kms_selftest@drm_format,Timeout kms_selftest@drm_format_helper,Timeout +msm_mapping@ring,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt deleted file mode 100644 index f71166a57731..000000000000 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt +++ /dev/null @@ -1,30 +0,0 @@ -kms_color@ctm-0-25,Fail -kms_color@ctm-0-50,Fail -kms_color@ctm-0-75,Fail -kms_color@ctm-blue-to-red,Fail -kms_color@ctm-green-to-red,Fail -kms_color@ctm-negative,Fail -kms_color@ctm-red-to-blue,Fail -kms_color@ctm-signed,Fail -kms_cursor_legacy@cursor-vs-flip-toggle,Fail -kms_cursor_legacy@cursor-vs-flip-varying-size,Fail -kms_cursor_legacy@cursorA-vs-flipA-atomic-transitions,Crash -kms_flip@flip-vs-modeset-vs-hang,Fail -kms_flip@flip-vs-panning-vs-hang,Fail -kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail -kms_plane_alpha_blend@alpha-7efc,Fail -kms_plane_alpha_blend@coverage-7efc,Fail -kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail -kms_plane_alpha_blend@pipe-A-alpha-7efc,Fail -kms_plane_alpha_blend@pipe-A-coverage-7efc,Fail -kms_plane_alpha_blend@pipe-A-coverage-vs-premult-vs-constant,Fail -kms_plane_alpha_blend@pipe-B-alpha-7efc,Fail -kms_plane_alpha_blend@pipe-B-alpha-basic,Fail -kms_plane_alpha_blend@pipe-B-alpha-opaque-fb,Fail -kms_plane_alpha_blend@pipe-B-constant-alpha-max,Fail -kms_plane_alpha_blend@pipe-B-constant-alpha-mid,Fail -kms_plane_alpha_blend@pipe-B-coverage-7efc,Fail -kms_plane_alpha_blend@pipe-B-coverage-vs-premult-vs-constant,Fail -kms_rmfb@close-fd,Fail -kms_universal_plane@disable-primary-vs-flip-pipe-b,Fail -kms_universal_plane@universal-plane-pipe-B-sanity,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt deleted file mode 100644 index 04730044ed12..000000000000 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt +++ /dev/null @@ -1,17 +0,0 @@ -kms_color@ctm-0-25 -kms_color@ctm-0-50 -kms_color@ctm-0-75 -kms_color@ctm-blue-to-red -kms_color@ctm-green-to-red -kms_color@ctm-negative -kms_color@ctm-red-to-blue -kms_color@ctm-signed -kms_flip@flip-vs-modeset-vs-hang -kms_flip@flip-vs-panning-vs-hang -kms_plane@pixel-format -kms_plane@pixel-format-source-clamping -kms_plane@plane-position-covered -kms_plane@plane-position-hole -kms_plane@plane-position-hole-dpms -kms_writeback@writeback-fb-id -kms_writeback@writeback-invalid-parameters diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt deleted file mode 100644 index e59a2fddfde0..000000000000 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Suspend to RAM seems to be broken on this machine -.*suspend.* - -# Test incorrectly assumes that CTM support implies gamma/degamma -# LUT support. None of the subtests handle the case of only having -# CTM support -#kms_color.* diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt new file mode 100644 index 000000000000..7e4d8744fcc6 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt @@ -0,0 +1,17 @@ +kms_color@ctm-0-25,Fail +kms_color@ctm-0-50,Fail +kms_color@ctm-0-75,Fail +kms_color@ctm-blue-to-red,Fail +kms_color@ctm-green-to-red,Fail +kms_color@ctm-negative,Fail +kms_color@ctm-red-to-blue,Fail +kms_color@ctm-signed,Fail +kms_cursor_legacy@cursor-vs-flip-toggle,Fail +kms_cursor_legacy@cursor-vs-flip-varying-size,Fail +kms_flip@flip-vs-modeset-vs-hang,Fail +kms_flip@flip-vs-panning-vs-hang,Fail +kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail +kms_plane_alpha_blend@alpha-7efc,Fail +kms_plane_alpha_blend@coverage-7efc,Fail +kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail +kms_rmfb@close-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt new file mode 100644 index 000000000000..7e4d8744fcc6 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt @@ -0,0 +1,17 @@ +kms_color@ctm-0-25,Fail +kms_color@ctm-0-50,Fail +kms_color@ctm-0-75,Fail +kms_color@ctm-blue-to-red,Fail +kms_color@ctm-green-to-red,Fail +kms_color@ctm-negative,Fail +kms_color@ctm-red-to-blue,Fail +kms_color@ctm-signed,Fail +kms_cursor_legacy@cursor-vs-flip-toggle,Fail +kms_cursor_legacy@cursor-vs-flip-varying-size,Fail +kms_flip@flip-vs-modeset-vs-hang,Fail +kms_flip@flip-vs-panning-vs-hang,Fail +kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail +kms_plane_alpha_blend@alpha-7efc,Fail +kms_plane_alpha_blend@coverage-7efc,Fail +kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail +kms_rmfb@close-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt index c55baa2d18c1..e9043a00383e 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt @@ -15,7 +15,7 @@ kms_color@pipe-A-ctm-max,Fail kms_color@pipe-A-ctm-negative,Fail kms_color@pipe-A-ctm-red-to-blue,Fail kms_color@pipe-A-legacy-gamma,Fail -kms_cursor_legacy@basic-flip-after-cursor-legacy,Fail +kms_cursor_legacy@basic-flip-after-cursor-atomic,Fail kms_cursor_legacy@basic-flip-after-cursor-varying-size,Fail kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail kms_cursor_legacy@basic-flip-before-cursor-legacy,Fail @@ -29,9 +29,6 @@ kms_cursor_legacy@flip-vs-cursor-atomic,Fail kms_cursor_legacy@flip-vs-cursor-crc-atomic,Fail kms_cursor_legacy@flip-vs-cursor-crc-legacy,Fail kms_cursor_legacy@flip-vs-cursor-legacy,Fail -kms_cursor_legacy@short-flip-after-cursor-atomic-transitions,Fail -kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size,Fail -kms_cursor_legacy@short-flip-after-cursor-toggle,Fail kms_flip@flip-vs-modeset-vs-hang,Fail kms_flip@flip-vs-panning-vs-hang,Fail kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt index 16d205c04cbb..8a492f01eaa4 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt @@ -1,12 +1,22 @@ -kms_cursor_legacy@basic-flip-after-cursor-atomic -kms_cursor_legacy@basic-flip-before-cursor-varying-size -kms_cursor_legacy@cursorA-vs-flipA-toggle -kms_cursor_legacy@flip-vs-cursor-atomic-transitions +# Board Name: msm:sdm845 +# Bug Report: https://lore.kernel.org/dri-devel/46287831-edfa-78e8-6055-d7a08831c445@collabora.com/T/#u +# Failure Rate: 50 +# IGT Version: 1.28-gd2af13d9f +# Linux Version: 6.7.0-rc3 + +# Reported by deqp-runner +kms_cursor_legacy@basic-flip-after-cursor-legacy kms_cursor_legacy@flip-vs-cursor-toggle kms_cursor_legacy@flip-vs-cursor-varying-size +kms_cursor_legacy@short-flip-after-cursor-toggle kms_cursor_legacy@short-flip-before-cursor-atomic-transitions -kms_cursor_legacy@short-flip-before-cursor-toggle -kms_flip@flip-vs-modeset-vs-hang -kms_flip@flip-vs-panning-vs-hang -kms_plane@pixel-format -kms_plane@pixel-format-source-clamping +kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size +msm_shrink@copy-gpu-32 +msm_shrink@copy-gpu-oom-32 + +# The below test shows inconsistency across multiple runs, giving +# results of Pass and Fail alternately. +kms_cursor_legacy@basic-flip-before-cursor-varying-size +kms_cursor_legacy@flip-vs-cursor-atomic-transitions +kms_cursor_legacy@short-flip-after-cursor-atomic-transitions +kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt index 42675f1c6d76..618e3a3a7277 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt @@ -1,2 +1,7 @@ # Hangs machine -kms_bw.*
\ No newline at end of file +kms_bw.* + +# Failing due to a bootloader/fw issue. The workaround in mesa CI involves these two patches +# https://gitlab.freedesktop.org/gfx-ci/linux/-/commit/4b49f902ec6f2bb382cbbf489870573f4b43371e +# https://gitlab.freedesktop.org/gfx-ci/linux/-/commit/38cdf4c5559771e2474ae0fecef8469f65147bc1 +msm_mapping@* diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index 8a165be1a821..5afc26be9d2a 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -127,7 +127,7 @@ static void dp_aux_ep_shutdown(struct device *dev) aux_ep_drv->shutdown(to_dp_aux_ep_dev(dev)); } -static struct bus_type dp_aux_bus_type = { +static const struct bus_type dp_aux_bus_type = { .name = "dp-aux", .match = dp_aux_ep_match, .probe = dp_aux_ep_probe, diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index cee3188adf3d..a3065d4aa3d6 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -27,8 +27,9 @@ #include <linux/mutex.h> #include <drm/drm_atomic_state_helper.h> -#include <drm/drm_debugfs.h> #include <drm/drm_bridge.h> +#include <drm/drm_debugfs.h> +#include <drm/drm_edid.h> #include <drm/drm_encoder.h> #include <drm/drm_file.h> #include <drm/drm_of.h> @@ -1207,26 +1208,45 @@ int drm_bridge_get_modes(struct drm_bridge *bridge, EXPORT_SYMBOL_GPL(drm_bridge_get_modes); /** - * drm_bridge_get_edid - get the EDID data of the connected display + * drm_bridge_edid_read - read the EDID data of the connected display * @bridge: bridge control structure * @connector: the connector to read EDID for * * If the bridge supports output EDID retrieval, as reported by the - * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to - * get the EDID and return it. Otherwise return NULL. + * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.edid_read to get + * the EDID and return it. Otherwise return NULL. + * + * If &drm_bridge_funcs.edid_read is not set, fall back to using + * &drm_bridge_funcs.get_edid and wrapping it in struct drm_edid. * * RETURNS: * The retrieved EDID on success, or NULL otherwise. */ -struct edid *drm_bridge_get_edid(struct drm_bridge *bridge, - struct drm_connector *connector) +const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) { if (!(bridge->ops & DRM_BRIDGE_OP_EDID)) return NULL; - return bridge->funcs->get_edid(bridge, connector); + /* Transitional: Fall back to ->get_edid. */ + if (!bridge->funcs->edid_read) { + const struct drm_edid *drm_edid; + struct edid *edid; + + edid = bridge->funcs->get_edid(bridge, connector); + if (!edid) + return NULL; + + drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH); + + kfree(edid); + + return drm_edid; + } + + return bridge->funcs->edid_read(bridge, connector); } -EXPORT_SYMBOL_GPL(drm_bridge_get_edid); +EXPORT_SYMBOL_GPL(drm_bridge_edid_read); /** * drm_bridge_hpd_enable - enable hot plug detection for the bridge diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 3acd67021ec6..982552c9f92c 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -239,27 +239,27 @@ static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector, struct drm_bridge *bridge) { enum drm_connector_status status; - struct edid *edid; + const struct drm_edid *drm_edid; int n; status = drm_bridge_connector_detect(connector, false); if (status != connector_status_connected) goto no_edid; - edid = drm_bridge_get_edid(bridge, connector); - if (!drm_edid_is_valid(edid)) { - kfree(edid); + drm_edid = drm_bridge_edid_read(bridge, connector); + if (!drm_edid_valid(drm_edid)) { + drm_edid_free(drm_edid); goto no_edid; } - drm_connector_update_edid_property(connector, edid); - n = drm_add_edid_modes(connector, edid); + drm_edid_connector_update(connector, drm_edid); + n = drm_edid_connector_add_modes(connector); - kfree(edid); + drm_edid_free(drm_edid); return n; no_edid: - drm_connector_update_edid_property(connector, NULL); + drm_edid_connector_update(connector, NULL); return 0; } diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c index 48ee851b61d9..2da094bdf8a4 100644 --- a/drivers/gpu/drm/drm_exec.c +++ b/drivers/gpu/drm/drm_exec.c @@ -76,7 +76,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec) * If nr is non-zero then it is used as the initial objects table size. * In either case, the table will grow (be re-allocated) on demand. */ -void drm_exec_init(struct drm_exec *exec, uint32_t flags, unsigned nr) +void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr) { if (!nr) nr = PAGE_SIZE / sizeof(void *); diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index b67eafa55715..75f2eaf0d5b6 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -147,7 +147,6 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, invariant_flags = TTM_PL_FLAG_TOPDOWN; gbo->placement.placement = gbo->placements; - gbo->placement.busy_placement = gbo->placements; if (pl_flag & DRM_GEM_VRAM_PL_FLAG_VRAM) { gbo->placements[c].mem_type = TTM_PL_VRAM; @@ -160,7 +159,6 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, } gbo->placement.num_placement = c; - gbo->placement.num_busy_placement = c; for (i = 0; i < c; ++i) { gbo->placements[i].fpfn = 0; diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c index bcd111404b12..7646f67bda4e 100644 --- a/drivers/gpu/drm/drm_managed.c +++ b/drivers/gpu/drm/drm_managed.c @@ -177,6 +177,45 @@ int __drmm_add_action_or_reset(struct drm_device *dev, EXPORT_SYMBOL(__drmm_add_action_or_reset); /** + * drmm_release_action - release a managed action from a &drm_device + * @dev: DRM device + * @action: function which would be called when @dev is released + * @data: opaque pointer, passed to @action + * + * This function calls the @action previously added by drmm_add_action() + * immediately. + * The @action is removed from the list of cleanup actions for @dev, + * which means that it won't be called in the final drm_dev_put(). + */ +void drmm_release_action(struct drm_device *dev, + drmres_release_t action, + void *data) +{ + struct drmres *dr_match = NULL, *dr; + unsigned long flags; + + spin_lock_irqsave(&dev->managed.lock, flags); + list_for_each_entry_reverse(dr, &dev->managed.resources, node.entry) { + if (dr->node.release == action) { + if (!data || (data && *(void **)dr->data == data)) { + dr_match = dr; + del_dr(dev, dr_match); + break; + } + } + } + spin_unlock_irqrestore(&dev->managed.lock, flags); + + if (WARN_ON(!dr_match)) + return; + + action(dev, data); + + free_dr(dr_match); +} +EXPORT_SYMBOL(drmm_release_action); + +/** * drmm_kmalloc - &drm_device managed kmalloc() * @dev: DRM device * @size: size of the memory allocation diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 843a6dbda93a..ef6e416522f8 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -89,7 +89,7 @@ static const struct dev_pm_ops mipi_dsi_device_pm_ops = { .restore = pm_generic_restore, }; -static struct bus_type mipi_dsi_bus_type = { +static const struct bus_type mipi_dsi_bus_type = { .name = "mipi-dsi", .match = mipi_dsi_device_match, .uevent = mipi_dsi_uevent, diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 3d92f66e550c..aa93129c3397 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -117,6 +117,12 @@ static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = { .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, }; +static const struct drm_dmi_panel_orientation_data lcd1080x1920_rightside_up = { + .width = 1080, + .height = 1920, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { .width = 1200, .height = 1920, @@ -279,6 +285,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03") }, .driver_data = (void *)&lcd720x1280_rightside_up, + }, { /* GPD Win Mini */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1617-01") + }, + .driver_data = (void *)&lcd1080x1920_rightside_up, }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 9227f8146a58..a6b0aaf30cbe 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -65,8 +65,6 @@ static const struct ttm_place sys_placement_flags = { static struct ttm_placement i915_sys_placement = { .num_placement = 1, .placement = &sys_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_placement_flags, }; /** @@ -157,32 +155,28 @@ i915_ttm_place_from_region(const struct intel_memory_region *mr, static void i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj, - struct ttm_place *requested, - struct ttm_place *busy, + struct ttm_place *places, struct ttm_placement *placement) { unsigned int num_allowed = obj->mm.n_placements; unsigned int flags = obj->flags; unsigned int i; - placement->num_placement = 1; + places[0].flags |= TTM_PL_FLAG_DESIRED; i915_ttm_place_from_region(num_allowed ? obj->mm.placements[0] : - obj->mm.region, requested, obj->bo_offset, + obj->mm.region, &places[0], obj->bo_offset, obj->base.size, flags); /* Cache this on object? */ - placement->num_busy_placement = num_allowed; - for (i = 0; i < placement->num_busy_placement; ++i) - i915_ttm_place_from_region(obj->mm.placements[i], busy + i, - obj->bo_offset, obj->base.size, flags); - - if (num_allowed == 0) { - *busy = *requested; - placement->num_busy_placement = 1; + for (i = 0; i < num_allowed; ++i) { + i915_ttm_place_from_region(obj->mm.placements[i], + &places[i + 1], obj->bo_offset, + obj->base.size, flags); + places[i + 1].flags |= TTM_PL_FLAG_FALLBACK; } - placement->placement = requested; - placement->busy_placement = busy; + placement->num_placement = num_allowed + 1; + placement->placement = places; } static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, @@ -789,7 +783,8 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj, int ret; /* First try only the requested placement. No eviction. */ - real_num_busy = fetch_and_zero(&placement->num_busy_placement); + real_num_busy = placement->num_placement; + placement->num_placement = 1; ret = ttm_bo_validate(bo, placement, &ctx); if (ret) { ret = i915_ttm_err_to_gem(ret); @@ -805,7 +800,7 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj, * If the initial attempt fails, allow all accepted placements, * evicting if necessary. */ - placement->num_busy_placement = real_num_busy; + placement->num_placement = real_num_busy; ret = ttm_bo_validate(bo, placement, &ctx); if (ret) return i915_ttm_err_to_gem(ret); @@ -839,7 +834,7 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj, static int i915_ttm_get_pages(struct drm_i915_gem_object *obj) { - struct ttm_place requested, busy[I915_TTM_MAX_PLACEMENTS]; + struct ttm_place places[I915_TTM_MAX_PLACEMENTS + 1]; struct ttm_placement placement; /* restricted by sg_alloc_table */ @@ -849,7 +844,7 @@ static int i915_ttm_get_pages(struct drm_i915_gem_object *obj) GEM_BUG_ON(obj->mm.n_placements > I915_TTM_MAX_PLACEMENTS); /* Move to the requested placement. */ - i915_ttm_placement_from_obj(obj, &requested, busy, &placement); + i915_ttm_placement_from_obj(obj, places, &placement); return __i915_ttm_get_pages(obj, &placement); } @@ -879,9 +874,7 @@ static int __i915_ttm_migrate(struct drm_i915_gem_object *obj, i915_ttm_place_from_region(mr, &requested, obj->bo_offset, obj->base.size, flags); placement.num_placement = 1; - placement.num_busy_placement = 1; placement.placement = &requested; - placement.busy_placement = &requested; ret = __i915_ttm_get_pages(obj, &placement); if (ret) diff --git a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c index c9b54bb2692d..803e3fcdb50f 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c +++ b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c @@ -42,14 +42,13 @@ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base) { struct dcss_blkctl *blkctl; - blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL); + blkctl = devm_kzalloc(dcss->dev, sizeof(*blkctl), GFP_KERNEL); if (!blkctl) return -ENOMEM; - blkctl->base_reg = ioremap(blkctl_base, SZ_4K); + blkctl->base_reg = devm_ioremap(dcss->dev, blkctl_base, SZ_4K); if (!blkctl->base_reg) { dev_err(dcss->dev, "unable to remap BLK CTRL base\n"); - kfree(blkctl); return -ENOMEM; } @@ -60,11 +59,3 @@ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base) return 0; } - -void dcss_blkctl_exit(struct dcss_blkctl *blkctl) -{ - if (blkctl->base_reg) - iounmap(blkctl->base_reg); - - kfree(blkctl); -} diff --git a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c index 3a84cb3209c4..e41d5c2a3ea4 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c +++ b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c @@ -202,7 +202,7 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base) struct dcss_ctxld *ctxld; int ret; - ctxld = kzalloc(sizeof(*ctxld), GFP_KERNEL); + ctxld = devm_kzalloc(dcss->dev, sizeof(*ctxld), GFP_KERNEL); if (!ctxld) return -ENOMEM; @@ -217,7 +217,7 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base) goto err; } - ctxld->ctxld_reg = ioremap(ctxld_base, SZ_4K); + ctxld->ctxld_reg = devm_ioremap(dcss->dev, ctxld_base, SZ_4K); if (!ctxld->ctxld_reg) { dev_err(dcss->dev, "ctxld: unable to remap ctxld base\n"); ret = -ENOMEM; @@ -226,18 +226,14 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base) ret = dcss_ctxld_irq_config(ctxld, to_platform_device(dcss->dev)); if (ret) - goto err_irq; + goto err; dcss_ctxld_hw_cfg(ctxld); return 0; -err_irq: - iounmap(ctxld->ctxld_reg); - err: dcss_ctxld_free_ctx(ctxld); - kfree(ctxld); return ret; } @@ -246,11 +242,7 @@ void dcss_ctxld_exit(struct dcss_ctxld *ctxld) { free_irq(ctxld->irq, ctxld); - if (ctxld->ctxld_reg) - iounmap(ctxld->ctxld_reg); - dcss_ctxld_free_ctx(ctxld); - kfree(ctxld); } static int dcss_ctxld_enable_locked(struct dcss_ctxld *ctxld) diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c index 4f3af0dfb344..597e9b7bd4bf 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c @@ -109,8 +109,6 @@ dtg_err: dcss_ctxld_exit(dcss->ctxld); ctxld_err: - dcss_blkctl_exit(dcss->blkctl); - dcss_clocks_disable(dcss); return ret; @@ -124,7 +122,6 @@ static void dcss_submodules_stop(struct dcss_dev *dcss) dcss_ss_exit(dcss->ss); dcss_dtg_exit(dcss->dtg); dcss_ctxld_exit(dcss->ctxld); - dcss_blkctl_exit(dcss->blkctl); dcss_clocks_disable(dcss); } @@ -170,6 +167,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output) struct resource *res; struct dcss_dev *dcss; const struct dcss_type_data *devtype; + resource_size_t res_len; devtype = of_device_get_match_data(dev); if (!devtype) { @@ -183,7 +181,13 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output) return ERR_PTR(-EINVAL); } - dcss = kzalloc(sizeof(*dcss), GFP_KERNEL); + res_len = res->end - res->start; + if (!devm_request_mem_region(dev, res->start, res_len, "dcss")) { + dev_err(dev, "cannot request memory region\n"); + return ERR_PTR(-EBUSY); + } + + dcss = devm_kzalloc(dev, sizeof(*dcss), GFP_KERNEL); if (!dcss) return ERR_PTR(-ENOMEM); @@ -194,7 +198,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output) ret = dcss_clks_init(dcss); if (ret) { dev_err(dev, "clocks initialization failed\n"); - goto err; + return ERR_PTR(ret); } dcss->of_port = of_graph_get_port_by_id(dev->of_node, 0); @@ -226,9 +230,6 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output) clks_err: dcss_clks_release(dcss); -err: - kfree(dcss); - return ERR_PTR(ret); } @@ -246,8 +247,6 @@ void dcss_dev_destroy(struct dcss_dev *dcss) dcss_submodules_stop(dcss); dcss_clks_release(dcss); - - kfree(dcss); } static int dcss_dev_suspend(struct device *dev) diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.h b/drivers/gpu/drm/imx/dcss/dcss-dev.h index f27b87c09599..b032e873d227 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dev.h +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.h @@ -104,7 +104,6 @@ extern const struct dev_pm_ops dcss_dev_pm_ops; /* BLKCTL */ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base); void dcss_blkctl_cfg(struct dcss_blkctl *blkctl); -void dcss_blkctl_exit(struct dcss_blkctl *blkctl); /* CTXLD */ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base); diff --git a/drivers/gpu/drm/imx/dcss/dcss-dpr.c b/drivers/gpu/drm/imx/dcss/dcss-dpr.c index df9dab949bf2..072eb209249f 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dpr.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dpr.c @@ -135,7 +135,7 @@ static int dcss_dpr_ch_init_all(struct dcss_dpr *dpr, unsigned long dpr_base) ch->base_ofs = dpr_base + i * 0x1000; - ch->base_reg = ioremap(ch->base_ofs, SZ_4K); + ch->base_reg = devm_ioremap(dpr->dev, ch->base_ofs, SZ_4K); if (!ch->base_reg) { dev_err(dpr->dev, "dpr: unable to remap ch %d base\n", i); @@ -155,7 +155,7 @@ int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base) { struct dcss_dpr *dpr; - dpr = kzalloc(sizeof(*dpr), GFP_KERNEL); + dpr = devm_kzalloc(dcss->dev, sizeof(*dpr), GFP_KERNEL); if (!dpr) return -ENOMEM; @@ -164,18 +164,8 @@ int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base) dpr->ctxld = dcss->ctxld; dpr->ctx_id = CTX_SB_HP; - if (dcss_dpr_ch_init_all(dpr, dpr_base)) { - int i; - - for (i = 0; i < 3; i++) { - if (dpr->ch[i].base_reg) - iounmap(dpr->ch[i].base_reg); - } - - kfree(dpr); - + if (dcss_dpr_ch_init_all(dpr, dpr_base)) return -ENOMEM; - } return 0; } @@ -189,12 +179,7 @@ void dcss_dpr_exit(struct dcss_dpr *dpr) struct dcss_dpr_ch *ch = &dpr->ch[ch_no]; dcss_writel(0, ch->base_reg + DCSS_DPR_SYSTEM_CTRL0); - - if (ch->base_reg) - iounmap(ch->base_reg); } - - kfree(dpr); } static u32 dcss_dpr_x_pix_wide_adjust(struct dcss_dpr_ch *ch, u32 pix_wide, diff --git a/drivers/gpu/drm/imx/dcss/dcss-drv.c b/drivers/gpu/drm/imx/dcss/dcss-drv.c index ad5f29ea8f6a..d881f5a34760 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-drv.c +++ b/drivers/gpu/drm/imx/dcss/dcss-drv.c @@ -51,15 +51,13 @@ static int dcss_drv_platform_probe(struct platform_device *pdev) of_node_put(remote); - mdrv = kzalloc(sizeof(*mdrv), GFP_KERNEL); + mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL); if (!mdrv) return -ENOMEM; mdrv->dcss = dcss_dev_create(dev, hdmi_output); - if (IS_ERR(mdrv->dcss)) { - err = PTR_ERR(mdrv->dcss); - goto err; - } + if (IS_ERR(mdrv->dcss)) + return PTR_ERR(mdrv->dcss); dev_set_drvdata(dev, mdrv); @@ -75,8 +73,6 @@ static int dcss_drv_platform_probe(struct platform_device *pdev) dcss_shutoff: dcss_dev_destroy(mdrv->dcss); -err: - kfree(mdrv); return err; } @@ -86,8 +82,6 @@ static void dcss_drv_platform_remove(struct platform_device *pdev) dcss_kms_detach(mdrv->kms); dcss_dev_destroy(mdrv->dcss); - - kfree(mdrv); } static void dcss_drv_platform_shutdown(struct platform_device *pdev) diff --git a/drivers/gpu/drm/imx/dcss/dcss-dtg.c b/drivers/gpu/drm/imx/dcss/dcss-dtg.c index 30de00540f63..2968f5d5bd41 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dtg.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dtg.c @@ -152,7 +152,7 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base) int ret = 0; struct dcss_dtg *dtg; - dtg = kzalloc(sizeof(*dtg), GFP_KERNEL); + dtg = devm_kzalloc(dcss->dev, sizeof(*dtg), GFP_KERNEL); if (!dtg) return -ENOMEM; @@ -160,11 +160,10 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base) dtg->dev = dcss->dev; dtg->ctxld = dcss->ctxld; - dtg->base_reg = ioremap(dtg_base, SZ_4K); + dtg->base_reg = devm_ioremap(dtg->dev, dtg_base, SZ_4K); if (!dtg->base_reg) { - dev_err(dcss->dev, "dtg: unable to remap dtg base\n"); - ret = -ENOMEM; - goto err_ioremap; + dev_err(dtg->dev, "dtg: unable to remap dtg base\n"); + return -ENOMEM; } dtg->base_ofs = dtg_base; @@ -175,17 +174,7 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base) dtg->control_status |= OVL_DATA_MODE | BLENDER_VIDEO_ALPHA_SEL | ((dtg->alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK); - ret = dcss_dtg_irq_config(dtg, to_platform_device(dcss->dev)); - if (ret) - goto err_irq; - - return 0; - -err_irq: - iounmap(dtg->base_reg); - -err_ioremap: - kfree(dtg); + ret = dcss_dtg_irq_config(dtg, to_platform_device(dtg->dev)); return ret; } @@ -193,11 +182,6 @@ err_ioremap: void dcss_dtg_exit(struct dcss_dtg *dtg) { free_irq(dtg->ctxld_kick_irq, dtg); - - if (dtg->base_reg) - iounmap(dtg->base_reg); - - kfree(dtg); } void dcss_dtg_sync_set(struct dcss_dtg *dtg, struct videomode *vm) diff --git a/drivers/gpu/drm/imx/dcss/dcss-scaler.c b/drivers/gpu/drm/imx/dcss/dcss-scaler.c index 47852b9dd5ea..825728c356ff 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-scaler.c +++ b/drivers/gpu/drm/imx/dcss/dcss-scaler.c @@ -302,7 +302,7 @@ static int dcss_scaler_ch_init_all(struct dcss_scaler *scl, ch->base_ofs = scaler_base + i * 0x400; - ch->base_reg = ioremap(ch->base_ofs, SZ_4K); + ch->base_reg = devm_ioremap(scl->dev, ch->base_ofs, SZ_4K); if (!ch->base_reg) { dev_err(scl->dev, "scaler: unable to remap ch base\n"); return -ENOMEM; @@ -318,7 +318,7 @@ int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base) { struct dcss_scaler *scaler; - scaler = kzalloc(sizeof(*scaler), GFP_KERNEL); + scaler = devm_kzalloc(dcss->dev, sizeof(*scaler), GFP_KERNEL); if (!scaler) return -ENOMEM; @@ -327,18 +327,8 @@ int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base) scaler->ctxld = dcss->ctxld; scaler->ctx_id = CTX_SB_HP; - if (dcss_scaler_ch_init_all(scaler, scaler_base)) { - int i; - - for (i = 0; i < 3; i++) { - if (scaler->ch[i].base_reg) - iounmap(scaler->ch[i].base_reg); - } - - kfree(scaler); - + if (dcss_scaler_ch_init_all(scaler, scaler_base)) return -ENOMEM; - } return 0; } @@ -351,12 +341,7 @@ void dcss_scaler_exit(struct dcss_scaler *scl) struct dcss_scaler_ch *ch = &scl->ch[ch_no]; dcss_writel(0, ch->base_reg + DCSS_SCALER_CTRL); - - if (ch->base_reg) - iounmap(ch->base_reg); } - - kfree(scl); } void dcss_scaler_ch_enable(struct dcss_scaler *scl, int ch_num, bool en) diff --git a/drivers/gpu/drm/imx/dcss/dcss-ss.c b/drivers/gpu/drm/imx/dcss/dcss-ss.c index 8ddf08da911b..0df81866fb7b 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-ss.c +++ b/drivers/gpu/drm/imx/dcss/dcss-ss.c @@ -83,7 +83,7 @@ int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base) { struct dcss_ss *ss; - ss = kzalloc(sizeof(*ss), GFP_KERNEL); + ss = devm_kzalloc(dcss->dev, sizeof(*ss), GFP_KERNEL); if (!ss) return -ENOMEM; @@ -91,10 +91,9 @@ int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base) ss->dev = dcss->dev; ss->ctxld = dcss->ctxld; - ss->base_reg = ioremap(ss_base, SZ_4K); + ss->base_reg = devm_ioremap(ss->dev, ss_base, SZ_4K); if (!ss->base_reg) { - dev_err(dcss->dev, "ss: unable to remap ss base\n"); - kfree(ss); + dev_err(ss->dev, "ss: unable to remap ss base\n"); return -ENOMEM; } @@ -108,11 +107,6 @@ void dcss_ss_exit(struct dcss_ss *ss) { /* stop SS */ dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL); - - if (ss->base_reg) - iounmap(ss->base_reg); - - kfree(ss); } void dcss_ss_subsam_set(struct dcss_ss *ss) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index 53840ab054c7..71d70194fcbd 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -655,7 +655,7 @@ static int imx_ldb_probe(struct platform_device *pdev) for (i = 0; i < 4; i++) { char clkname[16]; - sprintf(clkname, "di%d_sel", i); + snprintf(clkname, sizeof(clkname), "di%d_sel", i); imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname); if (IS_ERR(imx_ldb->clk_sel[i])) { ret = PTR_ERR(imx_ldb->clk_sel[i]); diff --git a/drivers/gpu/drm/ingenic/Kconfig b/drivers/gpu/drm/ingenic/Kconfig index b440e0cdc057..3db117c5edd9 100644 --- a/drivers/gpu/drm/ingenic/Kconfig +++ b/drivers/gpu/drm/ingenic/Kconfig @@ -11,7 +11,6 @@ config DRM_INGENIC select DRM_GEM_DMA_HELPER select REGMAP select REGMAP_MMIO - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE help Choose this option for DRM support for the Ingenic SoCs. diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index 4f9736e5f929..7ea244d876ca 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -75,29 +75,34 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) } else { bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); if (!bo->base.sgt) { - sg_free_table(&sgt); - return -ENOMEM; + ret = -ENOMEM; + goto err_out0; } } ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); - if (ret) { - sg_free_table(&sgt); - kfree(bo->base.sgt); - bo->base.sgt = NULL; - return ret; - } + if (ret) + goto err_out1; *bo->base.sgt = sgt; if (vm) { ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); if (ret) - return ret; + goto err_out2; } bo->heap_size = new_size; return 0; + +err_out2: + dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); +err_out1: + kfree(bo->base.sgt); + bo->base.sgt = NULL; +err_out0: + sg_free_table(&sgt); + return ret; } int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c index 89ccc0c43169..d8ff60b46abe 100644 --- a/drivers/gpu/drm/loongson/lsdc_drv.c +++ b/drivers/gpu/drm/loongson/lsdc_drv.c @@ -184,7 +184,7 @@ static int lsdc_get_dedicated_vram(struct lsdc_device *ldev, drm_info(ddev, "Dedicated vram start: 0x%llx, size: %uMiB\n", (u64)base, (u32)(size >> 20)); - return 0; + return (size > SZ_1M) ? 0 : -ENODEV; } static struct lsdc_device * diff --git a/drivers/gpu/drm/loongson/lsdc_ttm.c b/drivers/gpu/drm/loongson/lsdc_ttm.c index bf79dc55afa4..465f622ac05d 100644 --- a/drivers/gpu/drm/loongson/lsdc_ttm.c +++ b/drivers/gpu/drm/loongson/lsdc_ttm.c @@ -54,7 +54,6 @@ static void lsdc_bo_set_placement(struct lsdc_bo *lbo, u32 domain) pflags |= TTM_PL_FLAG_TOPDOWN; lbo->placement.placement = lbo->placements; - lbo->placement.busy_placement = lbo->placements; if (domain & LSDC_GEM_DOMAIN_VRAM) { lbo->placements[c].mem_type = TTM_PL_VRAM; @@ -77,7 +76,6 @@ static void lsdc_bo_set_placement(struct lsdc_bo *lbo, u32 domain) } lbo->placement.num_placement = c; - lbo->placement.num_busy_placement = c; for (i = 0; i < c; ++i) { lbo->placements[i].fpfn = 0; diff --git a/drivers/gpu/drm/mcde/Kconfig b/drivers/gpu/drm/mcde/Kconfig index 4f3d68e11bc1..907460b69d4f 100644 --- a/drivers/gpu/drm/mcde/Kconfig +++ b/drivers/gpu/drm/mcde/Kconfig @@ -11,7 +11,6 @@ config DRM_MCDE select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE help Choose this option for DRM support for the ST-Ericsson MCDE Multi-Channel Display Engine. diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index 25ea76558690..fff6ce394f98 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -323,19 +323,31 @@ static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, enum drm_connector_status status) { struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); - struct edid *edid; if (!encoder_hdmi->cec_notifier) return; if (status == connector_status_connected) { - edid = drm_bridge_get_edid(encoder_hdmi->next_bridge, encoder_hdmi->connector); - if (!edid) + const struct drm_edid *drm_edid; + const struct edid *edid; + + drm_edid = drm_bridge_edid_read(encoder_hdmi->next_bridge, + encoder_hdmi->connector); + if (!drm_edid) return; + /* + * FIXME: The CEC physical address should be set using + * cec_notifier_set_phys_addr(encoder_hdmi->cec_notifier, + * connector->display_info.source_physical_address) from a path + * that has read the EDID and called + * drm_edid_connector_update(). + */ + edid = drm_edid_raw(drm_edid); + cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); - kfree(edid); + drm_edid_free(drm_edid); } else cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); } diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d37d599aec27..c8e1bbebdffe 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -11,6 +11,7 @@ #include <linux/of_irq.h> #include <linux/delay.h> #include <drm/display/drm_dp_aux_bus.h> +#include <drm/drm_edid.h> #include "msm_drv.h" #include "msm_kms.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 00cc7d1abaa3..56dcd25db1ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -405,27 +405,6 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, } static void -set_placement_list(struct ttm_place *pl, unsigned *n, uint32_t domain) -{ - *n = 0; - - if (domain & NOUVEAU_GEM_DOMAIN_VRAM) { - pl[*n].mem_type = TTM_PL_VRAM; - pl[*n].flags = 0; - (*n)++; - } - if (domain & NOUVEAU_GEM_DOMAIN_GART) { - pl[*n].mem_type = TTM_PL_TT; - pl[*n].flags = 0; - (*n)++; - } - if (domain & NOUVEAU_GEM_DOMAIN_CPU) { - pl[*n].mem_type = TTM_PL_SYSTEM; - pl[(*n)++].flags = 0; - } -} - -static void set_placement_range(struct nouveau_bo *nvbo, uint32_t domain) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); @@ -452,10 +431,6 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t domain) nvbo->placements[i].fpfn = fpfn; nvbo->placements[i].lpfn = lpfn; } - for (i = 0; i < nvbo->placement.num_busy_placement; ++i) { - nvbo->busy_placements[i].fpfn = fpfn; - nvbo->busy_placements[i].lpfn = lpfn; - } } } @@ -463,15 +438,32 @@ void nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t domain, uint32_t busy) { - struct ttm_placement *pl = &nvbo->placement; + unsigned int *n = &nvbo->placement.num_placement; + struct ttm_place *pl = nvbo->placements; - pl->placement = nvbo->placements; - set_placement_list(nvbo->placements, &pl->num_placement, domain); + domain |= busy; - pl->busy_placement = nvbo->busy_placements; - set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, - domain | busy); + *n = 0; + if (domain & NOUVEAU_GEM_DOMAIN_VRAM) { + pl[*n].mem_type = TTM_PL_VRAM; + pl[*n].flags = busy & NOUVEAU_GEM_DOMAIN_VRAM ? + TTM_PL_FLAG_FALLBACK : 0; + (*n)++; + } + if (domain & NOUVEAU_GEM_DOMAIN_GART) { + pl[*n].mem_type = TTM_PL_TT; + pl[*n].flags = busy & NOUVEAU_GEM_DOMAIN_GART ? + TTM_PL_FLAG_FALLBACK : 0; + (*n)++; + } + if (domain & NOUVEAU_GEM_DOMAIN_CPU) { + pl[*n].mem_type = TTM_PL_SYSTEM; + pl[*n].flags = busy & NOUVEAU_GEM_DOMAIN_CPU ? + TTM_PL_FLAG_FALLBACK : 0; + (*n)++; + } + nvbo->placement.placement = nvbo->placements; set_placement_range(nvbo, domain); } @@ -1314,11 +1306,6 @@ vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) nvbo->placements[i].lpfn = mappable; } - for (i = 0; i < nvbo->placement.num_busy_placement; ++i) { - nvbo->busy_placements[i].fpfn = 0; - nvbo->busy_placements[i].lpfn = mappable; - } - nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, 0); } diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index 70c551921a9e..e9dfab6a8156 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -15,7 +15,6 @@ struct nouveau_bo { struct ttm_placement placement; u32 valid_domains; struct ttm_place placements[3]; - struct ttm_place busy_placements[3]; bool force_coherent; struct ttm_bo_kmap_obj kmap; struct list_head head; diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index cc03e0c22ff3..4d1008915499 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -112,7 +112,7 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, { struct nouveau_cli *cli = nouveau_cli(file_priv); struct drm_nouveau_svm_bind *args = data; - unsigned target, cmd, priority; + unsigned target, cmd; unsigned long addr, end; struct mm_struct *mm; @@ -136,9 +136,6 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, return -EINVAL; } - priority = args->header >> NOUVEAU_SVM_BIND_PRIORITY_SHIFT; - priority &= NOUVEAU_SVM_BIND_PRIORITY_MASK; - /* FIXME support CPU target ie all target value < GPU_VRAM */ target = args->header >> NOUVEAU_SVM_BIND_TARGET_SHIFT; target &= NOUVEAU_SVM_BIND_TARGET_MASK; @@ -926,15 +923,14 @@ nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm, unsigned long addr, u64 *pfns, unsigned long npages) { struct nouveau_pfnmap_args *args = nouveau_pfns_to_args(pfns); - int ret; args->p.addr = addr; args->p.size = npages << PAGE_SHIFT; mutex_lock(&svmm->mutex); - ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, - struct_size(args, p.phys, npages), NULL); + nvif_object_ioctl(&svmm->vmm->vmm.object, args, + struct_size(args, p.phys, npages), NULL); mutex_unlock(&svmm->mutex); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c index f36a359d4531..bd104a030243 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c @@ -218,7 +218,7 @@ nvkm_acr_lsfw_load_sig_image_desc_v2(struct nvkm_subdev *subdev, const struct firmware *hsbl; const struct nvfw_ls_hsbl_bin_hdr *hdr; const struct nvfw_ls_hsbl_hdr *hshdr; - u32 loc, sig, cnt, *meta; + u32 sig, cnt, *meta; ret = nvkm_firmware_load_name(subdev, path, "hs_bl_sig", ver, &hsbl); if (ret) @@ -227,7 +227,6 @@ nvkm_acr_lsfw_load_sig_image_desc_v2(struct nvkm_subdev *subdev, hdr = nvfw_ls_hsbl_bin_hdr(subdev, hsbl->data); hshdr = nvfw_ls_hsbl_hdr(subdev, hsbl->data + hdr->header_offset); meta = (u32 *)(hsbl->data + hshdr->meta_data_offset); - loc = *(u32 *)(hsbl->data + hshdr->patch_loc); sig = *(u32 *)(hsbl->data + hshdr->patch_sig); cnt = *(u32 *)(hsbl->data + hshdr->num_sig); diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 8f3783742208..b61abacd1b22 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -67,61 +67,25 @@ config DRM_PANEL_BOE_HIMAX8279D 24 bit RGB per pixel. It provides a MIPI DSI interface to the host and has a built-in LED backlight. -config DRM_PANEL_BOE_TV101WUM_NL6 - tristate "BOE TV101WUM and AUO KD101N80 45NA 1200x1920 panel" +config DRM_PANEL_BOE_TH101MB31UIG002_28A + tristate "Boe TH101MB31UIG002-28A panel" depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE help - Say Y here if you want to support for BOE TV101WUM and AUO KD101N80 - 45NA WUXGA PANEL DSI Video Mode panel + Say Y here if you want to enable support for Boe + TH101MB31UIG002-28A TFT-LCD modules. The panel has a 800x1280 + resolution and uses 24 bit RGB per pixel. It provides a MIPI DSI + interface to the host and has a built-in LED backlight. -config DRM_PANEL_DSI_CM - tristate "Generic DSI command mode panels" +config DRM_PANEL_BOE_TV101WUM_NL6 + tristate "BOE TV101WUM and AUO KD101N80 45NA 1200x1920 panel" depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE help - DRM panel driver for DSI command mode panels with support for - embedded and external backlights. - -config DRM_PANEL_LVDS - tristate "Generic LVDS panel driver" - depends on OF - depends on BACKLIGHT_CLASS_DEVICE - select VIDEOMODE_HELPERS - help - This driver supports LVDS panels that don't require device-specific - handling of power supplies or control signals. It implements automatic - backlight handling if the panel is attached to a backlight controller. - -config DRM_PANEL_SIMPLE - tristate "support for simple panels (other than eDP ones)" - depends on OF - depends on BACKLIGHT_CLASS_DEVICE - depends on PM - select VIDEOMODE_HELPERS - help - DRM panel driver for dumb non-eDP panels that need at most a regulator - and a GPIO to be powered up. Optionally a backlight can be attached so - that it can be automatically turned off when the panel goes into a - low power state. - -config DRM_PANEL_EDP - tristate "support for simple Embedded DisplayPort panels" - depends on OF - depends on BACKLIGHT_CLASS_DEVICE - depends on PM - select VIDEOMODE_HELPERS - select DRM_DISPLAY_DP_HELPER - select DRM_DISPLAY_HELPER - select DRM_DP_AUX_BUS - select DRM_KMS_HELPER - help - DRM panel driver for dumb eDP panels that need at most a regulator and - a GPIO to be powered up. Optionally a backlight can be attached so - that it can be automatically turned off when the panel goes into a - low power state. + Say Y here if you want to support for BOE TV101WUM and AUO KD101N80 + 45NA WUXGA PANEL DSI Video Mode panel config DRM_PANEL_EBBG_FT8719 tristate "EBBG FT8719 panel driver" @@ -162,6 +126,25 @@ config DRM_PANEL_FEIYANG_FY07024DI26A30D Say Y if you want to enable support for panels based on the Feiyang FY07024DI26A30-D MIPI-DSI interface. +config DRM_PANEL_DSI_CM + tristate "Generic DSI command mode panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + DRM panel driver for DSI command mode panels with support for + embedded and external backlights. + +config DRM_PANEL_LVDS + tristate "Generic LVDS panel driver" + depends on OF + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + This driver supports LVDS panels that don't require device-specific + handling of power supplies or control signals. It implements automatic + backlight handling if the panel is attached to a backlight controller. + config DRM_PANEL_HIMAX_HX8394 tristate "HIMAX HX8394 MIPI-DSI LCD panels" depends on OF @@ -251,17 +234,6 @@ config DRM_PANEL_JADARD_JD9365DA_H3 WXGA MIPI DSI panel. The panel support TFT dot matrix LCD with 800RGBx1280 dots at maximum. -config DRM_PANEL_JDI_LT070ME05000 - tristate "JDI LT070ME05000 WUXGA DSI panel" - depends on OF - depends on DRM_MIPI_DSI - depends on BACKLIGHT_CLASS_DEVICE - help - Say Y here if you want to enable support for JDI DSI video mode - panel as found in Google Nexus 7 (2013) devices. - The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses - 24 bit per pixel. - config DRM_PANEL_JDI_LPM102A188A tristate "JDI LPM102A188A DSI panel" depends on OF && GPIOLIB @@ -273,6 +245,17 @@ config DRM_PANEL_JDI_LPM102A188A The panel has a 2560×1800 resolution. It provides a MIPI DSI interface to the host. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI DSI video mode + panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit per pixel. + config DRM_PANEL_JDI_R63452 tristate "JDI R63452 Full HD DSI panel" depends on OF @@ -326,12 +309,6 @@ config DRM_PANEL_LEADTEK_LTK500HD1829 24 bit RGB per pixel. It provides a MIPI DSI interface to the host and has a built-in LED backlight. -config DRM_PANEL_SAMSUNG_LD9040 - tristate "Samsung LD9040 RGB/SPI panel" - depends on OF && SPI - depends on BACKLIGHT_CLASS_DEVICE - select VIDEOMODE_HELPERS - config DRM_PANEL_LG_LB035Q02 tristate "LG LB035Q024573 RGB panel" depends on GPIOLIB && OF && SPI @@ -359,6 +336,17 @@ config DRM_PANEL_MAGNACHIP_D53E6EA8966 with the Magnachip D53E6EA8966 panel IC. This panel receives video data via DSI but commands via 9-bit SPI using DBI. +config DRM_PANEL_MANTIX_MLAF057WE51 + tristate "Mantix MLAF057WE51-X MIPI-DSI LCD panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the Mantix + MLAF057WE51-X MIPI DSI panel as e.g. used in the Librem 5. It + has a resolution of 720x1440 pixels, a built in backlight and touch + controller. + config DRM_PANEL_NEC_NL8048HL11 tristate "NEC NL8048HL11 RGB panel" depends on GPIOLIB && OF && SPI @@ -438,6 +426,16 @@ config DRM_PANEL_NOVATEK_NT36672A around the Novatek NT36672A display controller, such as some Tianma panels used in a few Xiaomi Poco F1 mobile phones. +config DRM_PANEL_NOVATEK_NT36672E + tristate "Novatek NT36672E DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for Novatek NT36672E DSI Video Mode + LCD panel module. The panel has a resolution of 1080x2408 and uses 24 bit + RGB per pixel. + config DRM_PANEL_NOVATEK_NT39016 tristate "Novatek NT39016 RGB/SPI panel" depends on OF && SPI @@ -447,17 +445,6 @@ config DRM_PANEL_NOVATEK_NT39016 Say Y here if you want to enable support for the panels built around the Novatek NT39016 display controller. -config DRM_PANEL_MANTIX_MLAF057WE51 - tristate "Mantix MLAF057WE51-X MIPI-DSI LCD panel" - depends on OF - depends on DRM_MIPI_DSI - depends on BACKLIGHT_CLASS_DEVICE - help - Say Y here if you want to enable support for the Mantix - MLAF057WE51-X MIPI DSI panel as e.g. used in the Librem 5. It - has a resolution of 720x1440 pixels, a built in backlight and touch - controller. - config DRM_PANEL_OLIMEX_LCD_OLINUXINO tristate "Olimex LCD-OLinuXino panel" depends on OF @@ -554,6 +541,12 @@ config DRM_PANEL_RONBO_RB070D30 Say Y here if you want to enable support for Ronbo Electronics RB070D30 1024x600 DSI panel. +config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 + tristate "Samsung AMS452EF01 panel with S6E88A0 DSI video mode controller" + depends on OF + select DRM_MIPI_DSI + select VIDEOMODE_HELPERS + config DRM_PANEL_SAMSUNG_ATNA33XC20 tristate "Samsung ATNA33XC20 eDP panel" depends on OF @@ -577,6 +570,12 @@ config DRM_PANEL_SAMSUNG_DB7430 DB7430 DPI display controller used in such devices as the LMS397KF04 480x800 DPI panel. +config DRM_PANEL_SAMSUNG_LD9040 + tristate "Samsung LD9040 RGB/SPI panel" + depends on OF && SPI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + config DRM_PANEL_SAMSUNG_S6D16D0 tristate "Samsung S6D16D0 DSI video mode panel" depends on OF @@ -642,12 +641,6 @@ config DRM_PANEL_SAMSUNG_S6E63M0_DSI Say Y here if you want to be able to access the Samsung S6E63M0 panel using DSI. -config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 - tristate "Samsung AMS452EF01 panel with S6E88A0 DSI video mode controller" - depends on OF - select DRM_MIPI_DSI - select VIDEOMODE_HELPERS - config DRM_PANEL_SAMSUNG_S6E8AA0 tristate "Samsung S6E8AA0 DSI video mode panel" depends on OF @@ -746,15 +739,6 @@ config DRM_PANEL_SITRONIX_ST7789V Say Y here if you want to enable support for the Sitronix ST7789V controller for 240x320 LCD panels -config DRM_PANEL_SYNAPTICS_R63353 - tristate "Synaptics R63353-based panels" - depends on OF - depends on DRM_MIPI_DSI - depends on BACKLIGHT_CLASS_DEVICE - help - Say Y if you want to enable support for panels based on the - Synaptics R63353 controller. - config DRM_PANEL_SONY_ACX565AKM tristate "Sony ACX565AKM panel" depends on GPIOLIB && OF && SPI @@ -794,6 +778,43 @@ config DRM_PANEL_STARTEK_KD070FHFID015 with a resolution of 1024 x 600 pixels. It provides a MIPI DSI interface to the host, a built-in LED backlight and touch controller. +config DRM_PANEL_EDP + tristate "support for simple Embedded DisplayPort panels" + depends on OF + depends on BACKLIGHT_CLASS_DEVICE + depends on PM + select VIDEOMODE_HELPERS + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HELPER + select DRM_DP_AUX_BUS + select DRM_KMS_HELPER + help + DRM panel driver for dumb eDP panels that need at most a regulator and + a GPIO to be powered up. Optionally a backlight can be attached so + that it can be automatically turned off when the panel goes into a + low power state. + +config DRM_PANEL_SIMPLE + tristate "support for simple panels (other than eDP ones)" + depends on OF + depends on BACKLIGHT_CLASS_DEVICE + depends on PM + select VIDEOMODE_HELPERS + help + DRM panel driver for dumb non-eDP panels that need at most a regulator + and a GPIO to be powered up. Optionally a backlight can be attached so + that it can be automatically turned off when the panel goes into a + low power state. + +config DRM_PANEL_SYNAPTICS_R63353 + tristate "Synaptics R63353-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Synaptics R63353 controller. + config DRM_PANEL_TDO_TL070WSH30 tristate "TDO TL070WSH30 DSI panel" depends on OF @@ -837,6 +858,17 @@ config DRM_PANEL_TRULY_NT35597_WQXGA Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI Video Mode panel +config DRM_PANEL_VISIONOX_R66451 + tristate "Visionox R66451" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HELPER + help + Say Y here if you want to enable support for Visionox + R66451 1080x2340 AMOLED DSI panel. + config DRM_PANEL_VISIONOX_RM69299 tristate "Visionox RM69299" depends on OF @@ -854,17 +886,6 @@ config DRM_PANEL_VISIONOX_VTDR6130 Say Y here if you want to enable support for Visionox VTDR6130 1080x2400 AMOLED DSI panel. -config DRM_PANEL_VISIONOX_R66451 - tristate "Visionox R66451" - depends on OF - depends on DRM_MIPI_DSI - depends on BACKLIGHT_CLASS_DEVICE - select DRM_DISPLAY_DP_HELPER - select DRM_DISPLAY_HELPER - help - Say Y here if you want to enable support for Visionox - R66451 1080x2340 AMOLED DSI panel. - config DRM_PANEL_WIDECHIPS_WS2401 tristate "Widechips WS2401 DPI panel driver" depends on SPI && GPIOLIB diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index d94a644d0a6c..1c4f4e7f25bb 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596. obj-$(CONFIG_DRM_PANEL_AUO_A030JTN01) += panel-auo-a030jtn01.o obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o +obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o @@ -41,6 +42,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o +obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c b/drivers/gpu/drm/panel/panel-boe-himax8279d.c index 11b64acbe8a9..e225840b0d67 100644 --- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c +++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c @@ -854,26 +854,20 @@ static int panel_add(struct panel_info *pinfo) pinfo->pp18_gpio = devm_gpiod_get(dev, "pp18", GPIOD_OUT_HIGH); if (IS_ERR(pinfo->pp18_gpio)) { - ret = PTR_ERR(pinfo->pp18_gpio); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get pp18 gpio: %d\n", ret); - return ret; + return dev_err_probe(dev, PTR_ERR(pinfo->pp18_gpio), + "failed to get pp18 gpio\n"); } pinfo->pp33_gpio = devm_gpiod_get(dev, "pp33", GPIOD_OUT_HIGH); if (IS_ERR(pinfo->pp33_gpio)) { - ret = PTR_ERR(pinfo->pp33_gpio); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get pp33 gpio: %d\n", ret); - return ret; + return dev_err_probe(dev, PTR_ERR(pinfo->pp33_gpio), + "failed to get pp33 gpio\n"); } pinfo->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); if (IS_ERR(pinfo->enable_gpio)) { - ret = PTR_ERR(pinfo->enable_gpio); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get enable gpio: %d\n", ret); - return ret; + return dev_err_probe(dev, PTR_ERR(pinfo->enable_gpio), + "failed to get enable gpio\n"); } drm_panel_init(&pinfo->base, dev, &panel_funcs, diff --git a/drivers/gpu/drm/panel/panel-boe-th101mb31ig002-28a.c b/drivers/gpu/drm/panel/panel-boe-th101mb31ig002-28a.c new file mode 100644 index 000000000000..763e9f8342d3 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-boe-th101mb31ig002-28a.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023 Alexander Warnecke <awarnecke002@hotmail.com> + * Copyright (c) 2023 Manuel Traut <manut@mecka.net> + * Copyright (c) 2023 Dang Huynh <danct12@riseup.net> + */ + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/regulator/consumer.h> + +#include <drm/drm_connector.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +struct boe_th101mb31ig002 { + struct drm_panel panel; + + struct mipi_dsi_device *dsi; + + struct regulator *power; + struct gpio_desc *enable; + struct gpio_desc *reset; + + enum drm_panel_orientation orientation; +}; + +static void boe_th101mb31ig002_reset(struct boe_th101mb31ig002 *ctx) +{ + gpiod_direction_output(ctx->reset, 0); + usleep_range(10, 100); + gpiod_direction_output(ctx->reset, 1); + usleep_range(10, 100); + gpiod_direction_output(ctx->reset, 0); + usleep_range(5000, 6000); +} + +static int boe_th101mb31ig002_enable(struct drm_panel *panel) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + mipi_dsi_dcs_write_seq(dsi, 0xE0, 0xAB, 0xBA); + mipi_dsi_dcs_write_seq(dsi, 0xE1, 0xBA, 0xAB); + mipi_dsi_dcs_write_seq(dsi, 0xB1, 0x10, 0x01, 0x47, 0xFF); + mipi_dsi_dcs_write_seq(dsi, 0xB2, 0x0C, 0x14, 0x04, 0x50, 0x50, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0xB3, 0x56, 0x53, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xB4, 0x33, 0x30, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xB6, 0xB0, 0x00, 0x00, 0x10, 0x00, 0x10, + 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xB8, 0x05, 0x12, 0x29, 0x49, 0x48, 0x00, + 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xB9, 0x7C, 0x65, 0x55, 0x49, 0x46, 0x36, + 0x3B, 0x24, 0x3D, 0x3C, 0x3D, 0x5C, 0x4C, + 0x55, 0x47, 0x46, 0x39, 0x26, 0x06, 0x7C, + 0x65, 0x55, 0x49, 0x46, 0x36, 0x3B, 0x24, + 0x3D, 0x3C, 0x3D, 0x5C, 0x4C, 0x55, 0x47, + 0x46, 0x39, 0x26, 0x06); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0xFF, 0x87, 0x12, 0x34, 0x44, 0x44, + 0x44, 0x44, 0x98, 0x04, 0x98, 0x04, 0x0F, + 0x00, 0x00, 0xC1); + mipi_dsi_dcs_write_seq(dsi, 0xC1, 0x54, 0x94, 0x02, 0x85, 0x9F, 0x00, + 0x7F, 0x00, 0x54, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xC2, 0x17, 0x09, 0x08, 0x89, 0x08, 0x11, + 0x22, 0x20, 0x44, 0xFF, 0x18, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xC3, 0x86, 0x46, 0x05, 0x05, 0x1C, 0x1C, + 0x1D, 0x1D, 0x02, 0x1F, 0x1F, 0x1E, 0x1E, + 0x0F, 0x0F, 0x0D, 0x0D, 0x13, 0x13, 0x11, + 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xC4, 0x07, 0x07, 0x04, 0x04, 0x1C, 0x1C, + 0x1D, 0x1D, 0x02, 0x1F, 0x1F, 0x1E, 0x1E, + 0x0E, 0x0E, 0x0C, 0x0C, 0x12, 0x12, 0x10, + 0x10, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xC6, 0x2A, 0x2A); + mipi_dsi_dcs_write_seq(dsi, 0xC8, 0x21, 0x00, 0x31, 0x42, 0x34, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0xCA, 0xCB, 0x43); + mipi_dsi_dcs_write_seq(dsi, 0xCD, 0x0E, 0x4B, 0x4B, 0x20, 0x19, 0x6B, + 0x06, 0xB3); + mipi_dsi_dcs_write_seq(dsi, 0xD2, 0xE3, 0x2B, 0x38, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xD4, 0x00, 0x01, 0x00, 0x0E, 0x04, 0x44, + 0x08, 0x10, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xE6, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF); + mipi_dsi_dcs_write_seq(dsi, 0xF0, 0x12, 0x03, 0x20, 0x00, 0xFF); + mipi_dsi_dcs_write_seq(dsi, 0xF3, 0x00); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + + msleep(120); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set panel on: %d\n", ret); + return ret; + } + + return 0; +} + +static int boe_th101mb31ig002_disable(struct drm_panel *panel) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) + dev_err(dev, "Failed to set panel off: %d\n", ret); + + msleep(120); + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) + dev_err(dev, "Failed to enter sleep mode: %d\n", ret); + + return 0; +} + +static int boe_th101mb31ig002_unprepare(struct drm_panel *panel) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + + gpiod_set_value_cansleep(ctx->reset, 1); + gpiod_set_value_cansleep(ctx->enable, 0); + regulator_disable(ctx->power); + + return 0; +} + +static int boe_th101mb31ig002_prepare(struct drm_panel *panel) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = regulator_enable(ctx->power); + if (ret) { + dev_err(dev, "Failed to enable power supply: %d\n", ret); + return ret; + } + + gpiod_set_value_cansleep(ctx->enable, 1); + msleep(50); + boe_th101mb31ig002_reset(ctx); + boe_th101mb31ig002_enable(panel); + + return 0; +} + +static const struct drm_display_mode boe_th101mb31ig002_default_mode = { + .clock = 73500, + .hdisplay = 800, + .hsync_start = 800 + 64, + .hsync_end = 800 + 64 + 16, + .htotal = 800 + 64 + 16 + 64, + .vdisplay = 1280, + .vsync_start = 1280 + 2, + .vsync_end = 1280 + 2 + 4, + .vtotal = 1280 + 2 + 4 + 12, + .width_mm = 135, + .height_mm = 216, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static int boe_th101mb31ig002_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, + &boe_th101mb31ig002_default_mode); + if (!mode) { + dev_err(panel->dev, "Failed to add mode %ux%u@%u\n", + boe_th101mb31ig002_default_mode.hdisplay, + boe_th101mb31ig002_default_mode.vdisplay, + drm_mode_vrefresh(&boe_th101mb31ig002_default_mode)); + return -ENOMEM; + } + + drm_mode_set_name(mode); + + connector->display_info.bpc = 8; + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + + /* + * TODO: Remove once all drm drivers call + * drm_connector_set_orientation_from_panel() + */ + drm_connector_set_panel_orientation(connector, ctx->orientation); + + drm_mode_probed_add(connector, mode); + + return 1; +} + +static enum drm_panel_orientation +boe_th101mb31ig002_get_orientation(struct drm_panel *panel) +{ + struct boe_th101mb31ig002 *ctx = container_of(panel, + struct boe_th101mb31ig002, + panel); + + return ctx->orientation; +} + +static const struct drm_panel_funcs boe_th101mb31ig002_funcs = { + .prepare = boe_th101mb31ig002_prepare, + .unprepare = boe_th101mb31ig002_unprepare, + .disable = boe_th101mb31ig002_disable, + .get_modes = boe_th101mb31ig002_get_modes, + .get_orientation = boe_th101mb31ig002_get_orientation, +}; + +static int boe_th101mb31ig002_dsi_probe(struct mipi_dsi_device *dsi) +{ + struct boe_th101mb31ig002 *ctx; + int ret; + + ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + mipi_dsi_set_drvdata(dsi, ctx); + ctx->dsi = dsi; + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET | + MIPI_DSI_MODE_LPM; + + ctx->power = devm_regulator_get(&dsi->dev, "power"); + if (IS_ERR(ctx->power)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->power), + "Failed to get power regulator\n"); + + ctx->enable = devm_gpiod_get(&dsi->dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(ctx->enable)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->enable), + "Failed to get enable GPIO\n"); + + ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset)) + return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset), + "Failed to get reset GPIO\n"); + + ret = of_drm_get_panel_orientation(dsi->dev.of_node, + &ctx->orientation); + if (ret) + return dev_err_probe(&dsi->dev, ret, + "Failed to get orientation\n"); + + drm_panel_init(&ctx->panel, &dsi->dev, &boe_th101mb31ig002_funcs, + DRM_MODE_CONNECTOR_DSI); + + ret = drm_panel_of_backlight(&ctx->panel); + if (ret) + return ret; + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err_probe(&dsi->dev, ret, + "Failed to attach panel to DSI host\n"); + drm_panel_remove(&ctx->panel); + return ret; + } + + return 0; +} + +static void boe_th101mb31ig002_dsi_remove(struct mipi_dsi_device *dsi) +{ + struct boe_th101mb31ig002 *ctx = mipi_dsi_get_drvdata(dsi); + + mipi_dsi_detach(dsi); + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id boe_th101mb31ig002_of_match[] = { + { .compatible = "boe,th101mb31ig002-28a", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, boe_th101mb31ig002_of_match); + +static struct mipi_dsi_driver boe_th101mb31ig002_driver = { + .driver = { + .name = "boe-th101mb31ig002-28a", + .of_match_table = boe_th101mb31ig002_of_match, + }, + .probe = boe_th101mb31ig002_dsi_probe, + .remove = boe_th101mb31ig002_dsi_remove, +}; +module_mipi_dsi_driver(boe_th101mb31ig002_driver); + +MODULE_AUTHOR("Alexander Warnecke <awarnecke002@hotmail.com>"); +MODULE_DESCRIPTION("BOE TH101MB31IG002-28A MIPI-DSI LCD panel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index a189ce236328..18bd2ee71201 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -933,8 +933,7 @@ static int j606f_boe_init_sequence(struct panel_info *pinfo) static const struct drm_display_mode elish_boe_modes[] = { { - /* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */ - .clock = (1600 + 60 + 8 + 60) * (2560 + 26 + 4 + 168) * 104 / 1000, + .clock = (1600 + 60 + 8 + 60) * (2560 + 26 + 4 + 168) * 120 / 1000, .hdisplay = 1600, .hsync_start = 1600 + 60, .hsync_end = 1600 + 60 + 8, @@ -948,8 +947,7 @@ static const struct drm_display_mode elish_boe_modes[] = { static const struct drm_display_mode elish_csot_modes[] = { { - /* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */ - .clock = (1600 + 200 + 40 + 52) * (2560 + 26 + 4 + 168) * 104 / 1000, + .clock = (1600 + 200 + 40 + 52) * (2560 + 26 + 4 + 168) * 120 / 1000, .hdisplay = 1600, .hsync_start = 1600 + 200, .hsync_end = 1600 + 200 + 40, @@ -1270,6 +1268,8 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) return ret; } + pinfo->panel.prepare_prev_first = true; + if (pinfo->desc->has_dcs_backlight) { pinfo->panel.backlight = nt36523_create_backlight(dsi); if (IS_ERR(pinfo->panel.backlight)) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c new file mode 100644 index 000000000000..cb7406d74466 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +static const char * const regulator_names[] = { + "vddi", + "avdd", + "avee", +}; + +static const unsigned long regulator_enable_loads[] = { + 62000, + 100000, + 100000, +}; + +static const unsigned long regulator_disable_loads[] = { + 80, + 100, + 100, +}; + +struct panel_desc { + const struct drm_display_mode *display_mode; + u32 width_mm; + u32 height_mm; + unsigned long mode_flags; + enum mipi_dsi_pixel_format format; + unsigned int lanes; + const char *panel_name; + int (*init_sequence)(struct mipi_dsi_device *dsi); +}; + +struct nt36672e_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[3]; + const struct panel_desc *desc; +}; + +static inline struct nt36672e_panel *to_nt36672e_panel(struct drm_panel *panel) +{ + return container_of(panel, struct nt36672e_panel, panel); +} + +static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi) +{ + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02, + 0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7); + + mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66); + mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38); + mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83); + mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91); + mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64); + mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54); + mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64); + mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54); + mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64); + mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54); + mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64); + mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f); + mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e); + mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d); + mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c); + mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17); + mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15); + mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18); + mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f); + mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e); + mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d); + mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c); + mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15); + mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18); + mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f); + mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f); + mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30); + mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82); + mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f); + mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x87, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x90, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x92, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0x93, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x94, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x95, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x9c, 0xf4); + mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xa0, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0xa2, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0xa3, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0xa4, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xc0); + mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xd9, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xe9, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x18, 0x22); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0xe4); + mipi_dsi_dcs_write_seq(dsi, 0x21, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x66, 0xd8); + mipi_dsi_dcs_write_seq(dsi, 0x68, 0x50); + mipi_dsi_dcs_write_seq(dsi, 0x69, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x0d); + mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x48); + mipi_dsi_dcs_write_seq(dsi, 0x72, 0x41); + mipi_dsi_dcs_write_seq(dsi, 0x73, 0x4a); + mipi_dsi_dcs_write_seq(dsi, 0x74, 0xd0); + mipi_dsi_dcs_write_seq(dsi, 0x77, 0x62); + mipi_dsi_dcs_write_seq(dsi, 0x79, 0x7e); + mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x15); + mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x84, 0x4d); + mipi_dsi_dcs_write_seq(dsi, 0xcf, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xef, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x84); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x83, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x84, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0x85, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x86, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0x87, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0x8a, 0x1a); + mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x42); + mipi_dsi_dcs_write_seq(dsi, 0x8f, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x90, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x91, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x9a, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0x9b, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x9c, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x9e, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x01, 0x68); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x81); + mipi_dsi_dcs_write_seq(dsi, 0x21, 0x6a); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0x81); + mipi_dsi_dcs_write_seq(dsi, 0x26, 0x94); + mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x70, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x71, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x72, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x75, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x76, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x77, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x09); + mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x67); + mipi_dsi_dcs_write_seq(dsi, 0x80, 0x23); + mipi_dsi_dcs_write_seq(dsi, 0x82, 0x09); + mipi_dsi_dcs_write_seq(dsi, 0x83, 0x67); + mipi_dsi_dcs_write_seq(dsi, 0x88, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x89, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xa6, 0x23); + mipi_dsi_dcs_write_seq(dsi, 0xa7, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xd3); + mipi_dsi_dcs_write_seq(dsi, 0xeb, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0xec, 0x28); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x91); + mipi_dsi_dcs_write_seq(dsi, 0x03, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0x07, 0x50); + mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x11, 0xe0); + mipi_dsi_dcs_write_seq(dsi, 0x15, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0xa4); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x78); + mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x23); + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x3e); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x3e); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x3e); + mipi_dsi_dcs_write_seq(dsi, 0x28, 0xfd); + mipi_dsi_dcs_write_seq(dsi, 0x29, 0x12); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0xe1); + mipi_dsi_dcs_write_seq(dsi, 0x2d, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x30, 0x49); + mipi_dsi_dcs_write_seq(dsi, 0x33, 0x96); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0x35, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x36, 0xde); + mipi_dsi_dcs_write_seq(dsi, 0x37, 0xf9); + mipi_dsi_dcs_write_seq(dsi, 0x38, 0x45); + mipi_dsi_dcs_write_seq(dsi, 0x39, 0xd9); + mipi_dsi_dcs_write_seq(dsi, 0x3a, 0x49); + mipi_dsi_dcs_write_seq(dsi, 0x4a, 0xf0); + mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x09); + mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x7f, 0xf0); + mipi_dsi_dcs_write_seq(dsi, 0x83, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x84, 0xa4); + mipi_dsi_dcs_write_seq(dsi, 0x87, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x88, 0x78); + mipi_dsi_dcs_write_seq(dsi, 0x89, 0x23); + mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x7d); + mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x7d); + mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x7d); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00, + 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8); + mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01, + 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e); + mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03, + 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a); + mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00, + 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01, + 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03, + 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b); + mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00, + 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01, + 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03, + 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a); + mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00, + 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8); + mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01, + 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e); + mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03, + 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a); + mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00, + 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01, + 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03, + 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b); + mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00, + 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01, + 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03, + 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a); + mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03, + 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2c); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1f); + mipi_dsi_dcs_write_seq(dsi, 0x62, 0x1f); + mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x36); + mipi_dsi_dcs_write_seq(dsi, 0x53, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x54, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x55, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x56, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x58, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x59, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00); + + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x51, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0x53, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0x55, 0x01); + + return 0; +} + +static int nt36672e_power_on(struct nt36672e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret, i; + + for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) { + ret = regulator_set_load(ctx->supplies[i].consumer, + regulator_enable_loads[i]); + if (ret) { + dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n", + ctx->supplies[i].supply, ret); + return ret; + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) { + dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret); + return ret; + } + + /* + * Reset sequence of nt36672e panel requires the panel to be out of reset + * for 10ms, followed by being held in reset for 10ms and then out again. + */ + gpiod_set_value(ctx->reset_gpio, 1); + usleep_range(10000, 20000); + gpiod_set_value(ctx->reset_gpio, 0); + usleep_range(10000, 20000); + gpiod_set_value(ctx->reset_gpio, 1); + usleep_range(10000, 20000); + + return 0; +} + +static int nt36672e_power_off(struct nt36672e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret = 0; + int i; + + gpiod_set_value(ctx->reset_gpio, 0); + + for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) { + ret = regulator_set_load(ctx->supplies[i].consumer, + regulator_disable_loads[i]); + if (ret) { + dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n", + ctx->supplies[i].supply, ret); + return ret; + } + } + + ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret) + dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret); + + return ret; +} + +static int nt36672e_on(struct nt36672e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + const struct panel_desc *desc = ctx->desc; + int ret = 0; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + if (desc->init_sequence) { + ret = desc->init_sequence(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "panel init sequence failed: %d\n", ret); + return ret; + } + } + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + msleep(120); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to set display on: %d\n", ret); + return ret; + } + msleep(100); + + return 0; +} + +static int nt36672e_off(struct nt36672e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret = 0; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to set display off: %d\n", ret); + return ret; + } + msleep(20); + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret); + return ret; + } + msleep(60); + + return 0; +} + +static int nt36672e_panel_prepare(struct drm_panel *panel) +{ + struct nt36672e_panel *ctx = to_nt36672e_panel(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + int ret = 0; + + ret = nt36672e_power_on(ctx); + if (ret < 0) + return ret; + + ret = nt36672e_on(ctx); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to initialize panel: %d\n", ret); + if (nt36672e_power_off(ctx)) + dev_err(&dsi->dev, "power off failed\n"); + return ret; + } + + return 0; +} + +static int nt36672e_panel_unprepare(struct drm_panel *panel) +{ + struct nt36672e_panel *ctx = to_nt36672e_panel(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + int ret = 0; + + ret = nt36672e_off(ctx); + if (ret < 0) + dev_err(&dsi->dev, "Failed to un-initialize panel: %d\n", ret); + + ret = nt36672e_power_off(ctx); + if (ret < 0) + dev_err(&dsi->dev, "power off failed: %d\n", ret); + + return 0; +} + +static const struct drm_display_mode nt36672e_1080x2408_60hz = { + .name = "1080x2408", + .clock = 181690, + .hdisplay = 1080, + .hsync_start = 1080 + 76, + .hsync_end = 1080 + 76 + 12, + .htotal = 1080 + 76 + 12 + 56, + .vdisplay = 2408, + .vsync_start = 2408 + 46, + .vsync_end = 2408 + 46 + 10, + .vtotal = 2408 + 46 + 10 + 10, + .flags = 0, +}; + +static const struct panel_desc nt36672e_panel_desc = { + .display_mode = &nt36672e_1080x2408_60hz, + .width_mm = 74, + .height_mm = 131, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS, + .format = MIPI_DSI_FMT_RGB888, + .lanes = 4, + .panel_name = "nt36672e fhd plus panel", + .init_sequence = nt36672e_1080x2408_60hz_init, +}; + +static int nt36672e_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) +{ + struct nt36672e_panel *ctx = to_nt36672e_panel(panel); + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, ctx->desc->display_mode); + if (!mode) + return -ENOMEM; + + drm_mode_set_name(mode); + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + connector->display_info.width_mm = ctx->desc->width_mm; + connector->display_info.height_mm = ctx->desc->height_mm; + drm_mode_probed_add(connector, mode); + + return 1; +} + +static const struct drm_panel_funcs nt36672e_drm_funcs = { + .prepare = nt36672e_panel_prepare, + .unprepare = nt36672e_panel_unprepare, + .get_modes = nt36672e_panel_get_modes, +}; + +static int nt36672e_panel_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct nt36672e_panel *ctx; + int i, ret = 0; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->desc = of_device_get_match_data(dev); + if (!ctx->desc) { + dev_err(dev, "missing device configuration\n"); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) + ctx->supplies[i].supply = regulator_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), + ctx->supplies); + if (ret < 0) + return ret; + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = ctx->desc->lanes; + dsi->format = ctx->desc->format; + dsi->mode_flags = ctx->desc->mode_flags; + + drm_panel_init(&ctx->panel, dev, &nt36672e_drm_funcs, DRM_MODE_CONNECTOR_DSI); + + ret = drm_panel_of_backlight(&ctx->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + ctx->panel.prepare_prev_first = true; + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + goto err_dsi_attach; + } + + return 0; + +err_dsi_attach: + drm_panel_remove(&ctx->panel); + return ret; +} + +static void nt36672e_panel_remove(struct mipi_dsi_device *dsi) +{ + struct nt36672e_panel *ctx = mipi_dsi_get_drvdata(dsi); + + mipi_dsi_detach(ctx->dsi); + mipi_dsi_device_unregister(ctx->dsi); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id nt36672e_of_match[] = { + { + .compatible = "novatek,nt36672e", + .data = &nt36672e_panel_desc, + }, + { } +}; +MODULE_DEVICE_TABLE(of, nt36672e_of_match); + +static struct mipi_dsi_driver nt36672e_panel_driver = { + .driver = { + .name = "panel-novatek-nt36672e", + .of_match_table = nt36672e_of_match, + }, + .probe = nt36672e_panel_probe, + .remove = nt36672e_panel_remove, +}; +module_mipi_dsi_driver(nt36672e_panel_driver); + +MODULE_AUTHOR("Ritesh Kumar <quic_riteshk@quicinc.com>"); +MODULE_DESCRIPTION("Novatek NT36672E DSI Panel Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index d493ee735c73..7606cc68d96a 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1980,6 +1980,33 @@ static const struct panel_desc edt_etml0700y5dha = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing edt_etml1010g3dra_timing = { + .pixelclock = { 66300000, 72400000, 78900000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 12, 72, 132 }, + .hback_porch = { 86, 86, 86 }, + .hsync_len = { 2, 2, 2 }, + .vactive = { 800, 800, 800 }, + .vfront_porch = { 1, 15, 49 }, + .vback_porch = { 21, 21, 21 }, + .vsync_len = { 2, 2, 2 }, + .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH, +}; + +static const struct panel_desc edt_etml1010g3dra = { + .timings = &edt_etml1010g3dra_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 216, + .height = 135, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode edt_etmv570g2dhu_mode = { .clock = 25175, .hdisplay = 640, @@ -2754,21 +2781,21 @@ static const struct panel_desc lemaker_bl035_rgb_002 = { .bus_flags = DRM_BUS_FLAG_DE_LOW, }; -static const struct drm_display_mode lg_lb070wv8_mode = { - .clock = 33246, - .hdisplay = 800, - .hsync_start = 800 + 88, - .hsync_end = 800 + 88 + 80, - .htotal = 800 + 88 + 80 + 88, - .vdisplay = 480, - .vsync_start = 480 + 10, - .vsync_end = 480 + 10 + 25, - .vtotal = 480 + 10 + 25 + 10, +static const struct display_timing lg_lb070wv8_timing = { + .pixelclock = { 31950000, 33260000, 34600000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 88, 88, 88 }, + .hback_porch = { 88, 88, 88 }, + .hsync_len = { 80, 80, 80 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 10, 10, 10 }, + .vback_porch = { 10, 10, 10 }, + .vsync_len = { 25, 25, 25 }, }; static const struct panel_desc lg_lb070wv8 = { - .modes = &lg_lb070wv8_mode, - .num_modes = 1, + .timings = &lg_lb070wv8_timing, + .num_timings = 1, .bpc = 8, .size = { .width = 151, @@ -3516,14 +3543,15 @@ static const struct display_timing rocktech_rk043fn48h_timing = { .pixelclock = { 6000000, 9000000, 12000000 }, .hactive = { 480, 480, 480 }, .hback_porch = { 8, 43, 43 }, - .hfront_porch = { 2, 8, 8 }, + .hfront_porch = { 2, 8, 10 }, .hsync_len = { 1, 1, 1 }, .vactive = { 272, 272, 272 }, - .vback_porch = { 2, 12, 12 }, + .vback_porch = { 2, 12, 26 }, .vfront_porch = { 1, 4, 4 }, .vsync_len = { 1, 10, 10 }, .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW | - DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE | + DISPLAY_FLAGS_SYNC_POSEDGE, }; static const struct panel_desc rocktech_rk043fn48h = { @@ -4424,6 +4452,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "edt,etml0700y5dha", .data = &edt_etml0700y5dha, }, { + .compatible = "edt,etml1010g3dra", + .data = &edt_etml1010g3dra, + }, { .compatible = "edt,etmv570g2dhu", .data = &edt_etmv570g2dhu, }, { diff --git a/drivers/gpu/drm/panel/panel-visionox-r66451.c b/drivers/gpu/drm/panel/panel-visionox-r66451.c index fbb73464de33..493f2a6076f8 100644 --- a/drivers/gpu/drm/panel/panel-visionox-r66451.c +++ b/drivers/gpu/drm/panel/panel-visionox-r66451.c @@ -322,6 +322,7 @@ static int visionox_r66451_probe(struct mipi_dsi_device *dsi) dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; + ctx->panel.prepare_prev_first = true; drm_panel_init(&ctx->panel, dev, &visionox_r66451_funcs, DRM_MODE_CONNECTOR_DSI); ctx->panel.backlight = visionox_r66451_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index a23407b9f6fb..540099253e1b 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -287,6 +287,7 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; + ctx->panel.prepare_prev_first = true; drm_panel_init(&ctx->panel, dev, &visionox_vtdr6130_panel_funcs, DRM_MODE_CONNECTOR_DSI); diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig index ad24cdf1d992..20fe1d2c0aaf 100644 --- a/drivers/gpu/drm/pl111/Kconfig +++ b/drivers/gpu/drm/pl111/Kconfig @@ -9,7 +9,6 @@ config DRM_PL111 select DRM_GEM_DMA_HELPER select DRM_BRIDGE select DRM_PANEL_BRIDGE - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE help Choose this option for DRM support for the PL111 CLCD controller. If M is selected the module will be called pl111_drm. diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 06a58dad5f5c..1e46b0a6e478 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -66,7 +66,6 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain) pflag |= TTM_PL_FLAG_TOPDOWN; qbo->placement.placement = qbo->placements; - qbo->placement.busy_placement = qbo->placements; if (domain == QXL_GEM_DOMAIN_VRAM) { qbo->placements[c].mem_type = TTM_PL_VRAM; qbo->placements[c++].flags = pflag; @@ -86,7 +85,6 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain) qbo->placements[c++].flags = 0; } qbo->placement.num_placement = c; - qbo->placement.num_busy_placement = c; for (i = 0; i < c; ++i) { qbo->placements[i].fpfn = 0; qbo->placements[i].lpfn = 0; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 1a82629bce3f..765a144cea14 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -60,9 +60,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo, if (!qxl_ttm_bo_is_qxl_bo(bo)) { placement->placement = &placements; - placement->busy_placement = &placements; placement->num_placement = 1; - placement->num_busy_placement = 1; return; } qbo = to_qxl_bo(bo); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 10c0fbd9d2b4..a955f8a2f7fe 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -78,7 +78,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0, i; rbo->placement.placement = rbo->placements; - rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) { /* Try placing BOs which don't need CPU access outside of the * CPU accessible part of VRAM @@ -114,7 +113,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) } rbo->placement.num_placement = c; - rbo->placement.num_busy_placement = c; for (i = 0; i < c; ++i) { if ((rbo->flags & RADEON_GEM_CPU_ACCESS) && diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index de4e6d78f1e1..2078b0000e22 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -92,9 +92,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, if (!radeon_ttm_bo_is_radeon_bo(bo)) { placement->placement = &placements; - placement->busy_placement = &placements; placement->num_placement = 1; - placement->num_busy_placement = 1; return; } rbo = container_of(bo, struct radeon_bo, tbo); @@ -114,15 +112,11 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, */ radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT); - rbo->placement.num_busy_placement = 0; for (i = 0; i < rbo->placement.num_placement; i++) { if (rbo->placements[i].mem_type == TTM_PL_VRAM) { if (rbo->placements[i].fpfn < fpfn) rbo->placements[i].fpfn = fpfn; - } else { - rbo->placement.busy_placement = - &rbo->placements[i]; - rbo->placement.num_busy_placement = 1; + rbo->placements[0].flags |= TTM_PL_FLAG_DESIRED; } } } else diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index a2cda184b2b2..058a1c8451b2 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -324,7 +324,6 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo, rbo->placements[1].fpfn += (256 * 1024 * 1024) >> PAGE_SHIFT; rbo->placements[1].lpfn += (256 * 1024 * 1024) >> PAGE_SHIFT; rbo->placement.num_placement++; - rbo->placement.num_busy_placement++; } void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index d5d95c2dfeb7..1d2261643743 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -15,6 +15,7 @@ #include <linux/mutex.h> #include <linux/platform_device.h> +#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_edid.h> #include <drm/drm_of.h> diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 417fb884240a..09987e372e3e 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -24,6 +24,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_debugfs.h> +#include <drm/drm_edid.h> #include <drm/drm_eld.h> #include <drm/drm_file.h> #include <drm/drm_fourcc.h> diff --git a/drivers/gpu/drm/tests/drm_managed_test.c b/drivers/gpu/drm/tests/drm_managed_test.c index 1652dca11d30..76eb273c9b36 100644 --- a/drivers/gpu/drm/tests/drm_managed_test.c +++ b/drivers/gpu/drm/tests/drm_managed_test.c @@ -12,6 +12,7 @@ #define TEST_TIMEOUT_MS 100 struct managed_test_priv { + struct drm_device *drm; bool action_done; wait_queue_head_t action_wq; }; @@ -24,44 +25,88 @@ static void drm_action(struct drm_device *drm, void *ptr) wake_up_interruptible(&priv->action_wq); } -static void drm_test_managed_run_action(struct kunit *test) +/* + * The test verifies that the release action is called when + * drmm_release_action is called. + */ +static void drm_test_managed_release_action(struct kunit *test) { - struct managed_test_priv *priv; - struct drm_device *drm; - struct device *dev; + struct managed_test_priv *priv = test->priv; int ret; - priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); - init_waitqueue_head(&priv->action_wq); + ret = drmm_add_action_or_reset(priv->drm, drm_action, priv); + KUNIT_EXPECT_EQ(test, ret, 0); - dev = drm_kunit_helper_alloc_device(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + ret = drm_dev_register(priv->drm, 0); + KUNIT_ASSERT_EQ(test, ret, 0); + + drmm_release_action(priv->drm, drm_action, priv); + ret = wait_event_interruptible_timeout(priv->action_wq, priv->action_done, + msecs_to_jiffies(TEST_TIMEOUT_MS)); + KUNIT_EXPECT_GT(test, ret, 0); + + drm_dev_unregister(priv->drm); + drm_kunit_helper_free_device(test, priv->drm->dev); +} - drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm); +/* + * The test verifies that the release action is called automatically when the + * device is released. + */ +static void drm_test_managed_run_action(struct kunit *test) +{ + struct managed_test_priv *priv = test->priv; + int ret; - ret = drmm_add_action_or_reset(drm, drm_action, priv); + ret = drmm_add_action_or_reset(priv->drm, drm_action, priv); KUNIT_EXPECT_EQ(test, ret, 0); - ret = drm_dev_register(drm, 0); + ret = drm_dev_register(priv->drm, 0); KUNIT_ASSERT_EQ(test, ret, 0); - drm_dev_unregister(drm); - drm_kunit_helper_free_device(test, dev); + drm_dev_unregister(priv->drm); + drm_kunit_helper_free_device(test, priv->drm->dev); ret = wait_event_interruptible_timeout(priv->action_wq, priv->action_done, msecs_to_jiffies(TEST_TIMEOUT_MS)); KUNIT_EXPECT_GT(test, ret, 0); } +static int drm_managed_test_init(struct kunit *test) +{ + struct managed_test_priv *priv; + struct device *dev; + + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + init_waitqueue_head(&priv->action_wq); + + dev = drm_kunit_helper_alloc_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + /* + * DRM device can't be embedded in priv, since priv->action_done needs + * to remain allocated beyond both parent device and drm_device + * lifetime. + */ + priv->drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*priv->drm), 0, + DRIVER_MODESET); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); + + test->priv = priv; + + return 0; +} + static struct kunit_case drm_managed_tests[] = { + KUNIT_CASE(drm_test_managed_release_action), KUNIT_CASE(drm_test_managed_run_action), {} }; static struct kunit_suite drm_managed_test_suite = { - .name = "drm-test-managed", + .name = "drm_managed", + .init = drm_managed_test_init, .test_cases = drm_managed_tests }; diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index edf10618fe2b..ba3f09e2d7e6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -410,8 +410,8 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo, struct ttm_resource *hop_mem; int ret; - hop_placement.num_placement = hop_placement.num_busy_placement = 1; - hop_placement.placement = hop_placement.busy_placement = hop; + hop_placement.num_placement = 1; + hop_placement.placement = hop; /* find space in the bounce domain */ ret = ttm_bo_mem_space(bo, &hop_placement, &hop_mem, ctx); @@ -440,10 +440,9 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, dma_resv_assert_held(bo->base.resv); placement.num_placement = 0; - placement.num_busy_placement = 0; bdev->funcs->evict_flags(bo, &placement); - if (!placement.num_placement && !placement.num_busy_placement) { + if (!placement.num_placement) { ret = ttm_bo_wait_ctx(bo, ctx); if (ret) return ret; @@ -770,7 +769,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, * This function may sleep while waiting for space to become available. * Returns: * -EBUSY: No space available (only if no_wait == 1). - * -ENOMEM: Could not allocate memory for the buffer object, either due to + * -ENOSPC: Could not allocate space for the buffer object, either due to * fragmentation or concurrent allocators. * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. */ @@ -791,6 +790,9 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, const struct ttm_place *place = &placement->placement[i]; struct ttm_resource_manager *man; + if (place->flags & TTM_PL_FLAG_FALLBACK) + continue; + man = ttm_manager_type(bdev, place->mem_type); if (!man || !ttm_resource_manager_used(man)) continue; @@ -813,10 +815,13 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, return 0; } - for (i = 0; i < placement->num_busy_placement; ++i) { - const struct ttm_place *place = &placement->busy_placement[i]; + for (i = 0; i < placement->num_placement; ++i) { + const struct ttm_place *place = &placement->placement[i]; struct ttm_resource_manager *man; + if (place->flags & TTM_PL_FLAG_DESIRED) + continue; + man = ttm_manager_type(bdev, place->mem_type); if (!man || !ttm_resource_manager_used(man)) continue; @@ -830,7 +835,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, goto error; } - ret = -ENOMEM; + ret = -ENOSPC; if (!type_found) { pr_err(TTM_PFX "No compatible memory type found\n"); ret = -EINVAL; @@ -904,11 +909,11 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, /* * Remove the backing store if no placement is given. */ - if (!placement->num_placement && !placement->num_busy_placement) + if (!placement->num_placement) return ttm_bo_pipeline_gutting(bo); /* Check whether we need to move buffer. */ - if (bo->resource && ttm_resource_compat(bo->resource, placement)) + if (bo->resource && ttm_resource_compatible(bo->resource, placement)) return 0; /* Moving of pinned BOs is forbidden */ @@ -916,6 +921,9 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, return -EINVAL; ret = ttm_bo_move_buffer(bo, placement, ctx); + /* For backward compatibility with userspace */ + if (ret == -ENOSPC) + return -ENOMEM; if (ret) return ret; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index fd9fd3d15101..0b3f4267130c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -294,7 +294,13 @@ pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, enum ttm_caching caching; man = ttm_manager_type(bo->bdev, res->mem_type); - caching = man->use_tt ? bo->ttm->caching : res->bus.caching; + if (man->use_tt) { + caching = bo->ttm->caching; + if (bo->ttm->page_flags & TTM_TT_FLAG_DECRYPTED) + tmp = pgprot_decrypted(tmp); + } else { + caching = res->bus.caching; + } return ttm_prot_from_caching(caching, tmp); } @@ -337,6 +343,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, .no_wait_gpu = false }; struct ttm_tt *ttm = bo->ttm; + struct ttm_resource_manager *man = + ttm_manager_type(bo->bdev, bo->resource->mem_type); pgprot_t prot; int ret; @@ -346,7 +354,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, if (ret) return ret; - if (num_pages == 1 && ttm->caching == ttm_cached) { + if (num_pages == 1 && ttm->caching == ttm_cached && + !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) { /* * We're mapping a single page, and the desired * page protection is consistent with the bo. diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 02b96d23fdb9..fb14f7716cf8 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -291,37 +291,15 @@ bool ttm_resource_intersects(struct ttm_device *bdev, } /** - * ttm_resource_compatible - test for compatibility + * ttm_resource_compatible - check if resource is compatible with placement * - * @bdev: TTM device structure - * @res: The resource to test - * @place: The placement to test - * @size: How many bytes the new allocation needs. - * - * Test if @res compatible with @place and @size. + * @res: the resource to check + * @placement: the placement to check against * - * Returns true if the res placement compatible with @place and @size. + * Returns true if the placement is compatible. */ -bool ttm_resource_compatible(struct ttm_device *bdev, - struct ttm_resource *res, - const struct ttm_place *place, - size_t size) -{ - struct ttm_resource_manager *man; - - if (!res || !place) - return false; - - man = ttm_manager_type(bdev, res->mem_type); - if (!man->func->compatible) - return true; - - return man->func->compatible(man, res, place, size); -} - -static bool ttm_resource_places_compat(struct ttm_resource *res, - const struct ttm_place *places, - unsigned num_placement) +bool ttm_resource_compatible(struct ttm_resource *res, + struct ttm_placement *placement) { struct ttm_buffer_object *bo = res->bo; struct ttm_device *bdev = bo->bdev; @@ -330,44 +308,25 @@ static bool ttm_resource_places_compat(struct ttm_resource *res, if (res->placement & TTM_PL_FLAG_TEMPORARY) return false; - for (i = 0; i < num_placement; i++) { - const struct ttm_place *heap = &places[i]; + for (i = 0; i < placement->num_placement; i++) { + const struct ttm_place *place = &placement->placement[i]; + struct ttm_resource_manager *man; - if (!ttm_resource_compatible(bdev, res, heap, bo->base.size)) + if (res->mem_type != place->mem_type) + continue; + + man = ttm_manager_type(bdev, res->mem_type); + if (man->func->compatible && + !man->func->compatible(man, res, place, bo->base.size)) continue; - if ((res->mem_type == heap->mem_type) && - (!(heap->flags & TTM_PL_FLAG_CONTIGUOUS) || + if ((!(place->flags & TTM_PL_FLAG_CONTIGUOUS) || (res->placement & TTM_PL_FLAG_CONTIGUOUS))) return true; } return false; } -/** - * ttm_resource_compat - check if resource is compatible with placement - * - * @res: the resource to check - * @placement: the placement to check against - * - * Returns true if the placement is compatible. - */ -bool ttm_resource_compat(struct ttm_resource *res, - struct ttm_placement *placement) -{ - if (ttm_resource_places_compat(res, placement->placement, - placement->num_placement)) - return true; - - if ((placement->busy_placement != placement->placement || - placement->num_busy_placement > placement->num_placement) && - ttm_resource_places_compat(res, placement->busy_placement, - placement->num_busy_placement)) - return true; - - return false; -} - void ttm_resource_set_bo(struct ttm_resource *res, struct ttm_buffer_object *bo) { diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index d978dc539a9b..578a7c37f00b 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -31,11 +31,13 @@ #define pr_fmt(fmt) "[TTM] " fmt +#include <linux/cc_platform.h> #include <linux/sched.h> #include <linux/shmem_fs.h> #include <linux/file.h> #include <linux/module.h> #include <drm/drm_cache.h> +#include <drm/drm_device.h> #include <drm/drm_util.h> #include <drm/ttm/ttm_bo.h> #include <drm/ttm/ttm_tt.h> @@ -61,6 +63,7 @@ static atomic_long_t ttm_dma32_pages_allocated; int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) { struct ttm_device *bdev = bo->bdev; + struct drm_device *ddev = bo->base.dev; uint32_t page_flags = 0; dma_resv_assert_held(bo->base.resv); @@ -82,6 +85,15 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) pr_err("Illegal buffer object type\n"); return -EINVAL; } + /* + * When using dma_alloc_coherent with memory encryption the + * mapped TT pages need to be decrypted or otherwise the drivers + * will end up sending encrypted mem to the gpu. + */ + if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { + page_flags |= TTM_TT_FLAG_DECRYPTED; + drm_info(ddev, "TT memory decryption enabled."); + } bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags); if (unlikely(bo->ttm == NULL)) diff --git a/drivers/gpu/drm/tve200/Kconfig b/drivers/gpu/drm/tve200/Kconfig index 11e865be81c6..5121fed571a5 100644 --- a/drivers/gpu/drm/tve200/Kconfig +++ b/drivers/gpu/drm/tve200/Kconfig @@ -9,7 +9,6 @@ config DRM_TVE200 select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE help Choose this option for DRM support for the Faraday TV Encoder TVE200 Controller. diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index f05e2c95a60d..34f807ed1c31 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -35,6 +35,7 @@ #include <drm/display/drm_scdc_helper.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_edid.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> #include <linux/clk.h> diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c index ddf8373c1d77..6806c05e57f6 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.c +++ b/drivers/gpu/drm/vmwgfx/ttm_object.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** * - * Copyright (c) 2009-2022 VMware, Inc., Palo Alto, CA., USA + * Copyright (c) 2009-2023 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -648,7 +648,6 @@ out_unref: * @tfile: struct ttm_object_file identifying the caller * @size: The size of the dma_bufs we export. * @prime: The object to be initialized. - * @shareable: See ttm_base_object_init * @type: See ttm_base_object_init * @refcount_release: See ttm_base_object_init * @@ -656,10 +655,11 @@ out_unref: * for data sharing between processes and devices. */ int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size, - struct ttm_prime_object *prime, bool shareable, + struct ttm_prime_object *prime, enum ttm_object_type type, void (*refcount_release) (struct ttm_base_object **)) { + bool shareable = !!(type == VMW_RES_SURFACE); mutex_init(&prime->mutex); prime->size = PAGE_ALIGN(size); prime->real_type = type; diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h index e6b77ee33e55..573e038c0fab 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.h +++ b/drivers/gpu/drm/vmwgfx/ttm_object.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright (c) 2006-2022 VMware, Inc., Palo Alto, CA., USA + * Copyright (c) 2006-2023 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -288,7 +288,6 @@ extern void ttm_object_device_release(struct ttm_object_device **p_tdev); extern int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size, struct ttm_prime_object *prime, - bool shareable, enum ttm_object_type type, void (*refcount_release) (struct ttm_base_object **)); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 2bfac3aad7b7..bfd41ce3c8f4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -742,9 +742,21 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, vmw_resource_unbind_list(vbo); } +static u32 placement_flags(u32 domain, u32 desired, u32 fallback) +{ + if (desired & fallback & domain) + return 0; + + if (desired & domain) + return TTM_PL_FLAG_DESIRED; + + return TTM_PL_FLAG_FALLBACK; +} + static u32 -set_placement_list(struct ttm_place *pl, u32 domain) +set_placement_list(struct ttm_place *pl, u32 desired, u32 fallback) { + u32 domain = desired | fallback; u32 n = 0; /* @@ -752,35 +764,40 @@ set_placement_list(struct ttm_place *pl, u32 domain) */ if (domain & VMW_BO_DOMAIN_MOB) { pl[n].mem_type = VMW_PL_MOB; - pl[n].flags = 0; + pl[n].flags = placement_flags(VMW_BO_DOMAIN_MOB, desired, + fallback); pl[n].fpfn = 0; pl[n].lpfn = 0; n++; } if (domain & VMW_BO_DOMAIN_GMR) { pl[n].mem_type = VMW_PL_GMR; - pl[n].flags = 0; + pl[n].flags = placement_flags(VMW_BO_DOMAIN_GMR, desired, + fallback); pl[n].fpfn = 0; pl[n].lpfn = 0; n++; } if (domain & VMW_BO_DOMAIN_VRAM) { pl[n].mem_type = TTM_PL_VRAM; - pl[n].flags = 0; + pl[n].flags = placement_flags(VMW_BO_DOMAIN_VRAM, desired, + fallback); pl[n].fpfn = 0; pl[n].lpfn = 0; n++; } if (domain & VMW_BO_DOMAIN_WAITABLE_SYS) { pl[n].mem_type = VMW_PL_SYSTEM; - pl[n].flags = 0; + pl[n].flags = placement_flags(VMW_BO_DOMAIN_WAITABLE_SYS, + desired, fallback); pl[n].fpfn = 0; pl[n].lpfn = 0; n++; } if (domain & VMW_BO_DOMAIN_SYS) { pl[n].mem_type = TTM_PL_SYSTEM; - pl[n].flags = 0; + pl[n].flags = placement_flags(VMW_BO_DOMAIN_SYS, desired, + fallback); pl[n].fpfn = 0; pl[n].lpfn = 0; n++; @@ -806,7 +823,7 @@ void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain) u32 i; pl->placement = bo->places; - pl->num_placement = set_placement_list(bo->places, domain); + pl->num_placement = set_placement_list(bo->places, domain, busy_domain); if (drm_debug_enabled(DRM_UT_DRIVER) && bo->tbo.resource) { for (i = 0; i < pl->num_placement; ++i) { @@ -821,8 +838,6 @@ void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain) __func__, bo->tbo.resource->mem_type, domain); } - pl->busy_placement = bo->busy_places; - pl->num_busy_placement = set_placement_list(bo->busy_places, busy_domain); } void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 3cd5090dedfc..12efecc17df6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -942,7 +942,6 @@ vmw_is_cursor_bypass3_enabled(const struct vmw_private *dev_priv) extern const size_t vmw_tt_size; extern struct ttm_placement vmw_vram_placement; -extern struct ttm_placement vmw_vram_gmr_placement; extern struct ttm_placement vmw_sys_placement; extern struct ttm_device_funcs vmw_bo_driver; extern const struct vmw_sg_table * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 272141b6164c..cc3086e649eb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -447,7 +447,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < cotable_max; ++i) { res = vmw_context_cotable(ctx, i); - if (IS_ERR(res)) + if (IS_ERR_OR_NULL(res)) continue; ret = vmw_execbuf_res_val_add(sw_context, res, @@ -1266,6 +1266,8 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, return -EINVAL; cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY); + if (IS_ERR_OR_NULL(cotable_res)) + return cotable_res ? PTR_ERR(cotable_res) : -EINVAL; ret = vmw_cotable_notify(cotable_res, cmd->body.queryId); return ret; @@ -2484,6 +2486,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, return ret; res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->defined_id); if (unlikely(ret != 0)) return ret; @@ -2569,8 +2573,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv, so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); - if (IS_ERR(res)) - return PTR_ERR(res); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id); @@ -2689,6 +2693,8 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, return -EINVAL; res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.shaderId); if (ret) return ret; @@ -3010,6 +3016,8 @@ static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv, } res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.soid); if (ret) return ret; @@ -3603,6 +3611,8 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { &vmw_cmd_dx_bind_streamoutput, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE_V2, &vmw_cmd_dx_so_define, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE_V4, + &vmw_cmd_invalid, false, false, true), }; bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8589a1c3cc36..cd4925346ed4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -35,6 +35,7 @@ #include <drm/drm_fourcc.h> #include <drm/drm_rect.h> #include <drm/drm_sysfs.h> +#include <drm/drm_edid.h> void vmw_du_cleanup(struct vmw_display_unit *du) { @@ -184,13 +185,12 @@ static u32 vmw_du_cursor_mob_size(u32 w, u32 h) */ static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps) { - bool is_iomem; if (vps->surf) { if (vps->surf_mapped) return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo); return vps->surf->snooper.image; } else if (vps->bo) - return ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem); + return vmw_bo_map_and_cache(vps->bo); return NULL; } @@ -272,6 +272,7 @@ static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp, u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h); u32 i; u32 cursor_max_dim, mob_max_size; + struct vmw_fence_obj *fence = NULL; int ret; if (!dev_priv->has_mob || @@ -313,7 +314,15 @@ static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp, if (ret != 0) goto teardown; - vmw_bo_fence_single(&vps->cursor.bo->tbo, NULL); + ret = vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); + if (ret != 0) { + ttm_bo_unreserve(&vps->cursor.bo->tbo); + goto teardown; + } + + dma_fence_wait(&fence->base, false); + dma_fence_put(&fence->base); + ttm_bo_unreserve(&vps->cursor.bo->tbo); return 0; @@ -643,22 +652,12 @@ vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane, { struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane); struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); - bool is_iomem; if (vps->surf_mapped) { vmw_bo_unmap(vps->surf->res.guest_memory_bo); vps->surf_mapped = false; } - if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem)) { - const int ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL); - - if (likely(ret == 0)) { - ttm_bo_kunmap(&vps->bo->map); - ttm_bo_unreserve(&vps->bo->tbo); - } - } - vmw_du_cursor_plane_unmap_cm(vps); vmw_du_put_cursor_mob(vcp, vps); @@ -2282,107 +2281,6 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) connector_status_connected : connector_status_disconnected); } -static struct drm_display_mode vmw_kms_connector_builtin[] = { - /* 640x480@60Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, - 752, 800, 0, 480, 489, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 800x600@60Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, - 968, 1056, 0, 600, 601, 605, 628, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1024x768@60Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1152x864@75Hz */ - { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, - 1344, 1600, 0, 864, 865, 868, 900, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x720@60Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344, - 1472, 1664, 0, 720, 723, 728, 748, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x768@60Hz */ - { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, - 1472, 1664, 0, 768, 771, 778, 798, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x800@60Hz */ - { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, - 1480, 1680, 0, 800, 803, 809, 831, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x960@60Hz */ - { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, - 1488, 1800, 0, 960, 961, 964, 1000, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x1024@60Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, - 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1360x768@60Hz */ - { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, - 1536, 1792, 0, 768, 771, 777, 795, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x1050@60Hz */ - { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, - 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x900@60Hz */ - { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, - 1672, 1904, 0, 900, 903, 909, 934, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@60Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1680x1050@60Hz */ - { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, - 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1792x1344@60Hz */ - { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, - 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1853x1392@60Hz */ - { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, - 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@60Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 173000, 1920, 2048, - 2248, 2576, 0, 1080, 1083, 1088, 1120, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1200@60Hz */ - { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, - 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1440@60Hz */ - { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, - 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2560x1440@60Hz */ - { DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608, - 2640, 2720, 0, 1440, 1443, 1448, 1481, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2560x1600@60Hz */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, - 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2880x1800@60Hz */ - { DRM_MODE("2880x1800", DRM_MODE_TYPE_DRIVER, 337500, 2880, 2928, - 2960, 3040, 0, 1800, 1803, 1809, 1852, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 3840x2160@60Hz */ - { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 533000, 3840, 3888, - 3920, 4000, 0, 2160, 2163, 2168, 2222, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 3840x2400@60Hz */ - { DRM_MODE("3840x2400", DRM_MODE_TYPE_DRIVER, 592250, 3840, 3888, - 3920, 4000, 0, 2400, 2403, 2409, 2469, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* Terminate */ - { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, -}; - /** * vmw_guess_mode_timing - Provide fake timings for a * 60Hz vrefresh mode. @@ -2404,88 +2302,6 @@ void vmw_guess_mode_timing(struct drm_display_mode *mode) } -int vmw_du_connector_fill_modes(struct drm_connector *connector, - uint32_t max_width, uint32_t max_height) -{ - struct vmw_display_unit *du = vmw_connector_to_du(connector); - struct drm_device *dev = connector->dev; - struct vmw_private *dev_priv = vmw_priv(dev); - struct drm_display_mode *mode = NULL; - struct drm_display_mode *bmode; - struct drm_display_mode prefmode = { DRM_MODE("preferred", - DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) - }; - int i; - u32 assumed_bpp = 4; - - if (dev_priv->assume_16bpp) - assumed_bpp = 2; - - max_width = min(max_width, dev_priv->texture_max_width); - max_height = min(max_height, dev_priv->texture_max_height); - - /* - * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/ - * HEIGHT registers. - */ - if (dev_priv->active_display_unit == vmw_du_screen_target) { - max_width = min(max_width, dev_priv->stdu_max_width); - max_height = min(max_height, dev_priv->stdu_max_height); - } - - /* Add preferred mode */ - mode = drm_mode_duplicate(dev, &prefmode); - if (!mode) - return 0; - mode->hdisplay = du->pref_width; - mode->vdisplay = du->pref_height; - vmw_guess_mode_timing(mode); - drm_mode_set_name(mode); - - if (vmw_kms_validate_mode_vram(dev_priv, - mode->hdisplay * assumed_bpp, - mode->vdisplay)) { - drm_mode_probed_add(connector, mode); - } else { - drm_mode_destroy(dev, mode); - mode = NULL; - } - - if (du->pref_mode) { - list_del_init(&du->pref_mode->head); - drm_mode_destroy(dev, du->pref_mode); - } - - /* mode might be null here, this is intended */ - du->pref_mode = mode; - - for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { - bmode = &vmw_kms_connector_builtin[i]; - if (bmode->hdisplay > max_width || - bmode->vdisplay > max_height) - continue; - - if (!vmw_kms_validate_mode_vram(dev_priv, - bmode->hdisplay * assumed_bpp, - bmode->vdisplay)) - continue; - - mode = drm_mode_duplicate(dev, bmode); - if (!mode) - return 0; - - drm_mode_probed_add(connector, mode); - } - - drm_connector_list_update(connector); - /* Move the prefered mode first, help apps pick the right mode. */ - drm_mode_sort(&connector->modes); - - return 1; -} - /** * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl * @dev: drm device for the ioctl @@ -3026,3 +2842,91 @@ out_unref: vmw_validation_unref_lists(&val_ctx); return ret; } + +/** + * vmw_connector_mode_valid - implements drm_connector_helper_funcs.mode_valid callback + * + * @connector: the drm connector, part of a DU container + * @mode: drm mode to check + * + * Returns MODE_OK on success, or a drm_mode_status error code. + */ +enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_device *dev = connector->dev; + struct vmw_private *dev_priv = vmw_priv(dev); + u32 max_width = dev_priv->texture_max_width; + u32 max_height = dev_priv->texture_max_height; + u32 assumed_cpp = 4; + + if (dev_priv->assume_16bpp) + assumed_cpp = 2; + + if (dev_priv->active_display_unit == vmw_du_screen_target) { + max_width = min(dev_priv->stdu_max_width, max_width); + max_height = min(dev_priv->stdu_max_height, max_height); + } + + if (max_width < mode->hdisplay) + return MODE_BAD_HVALUE; + + if (max_height < mode->vdisplay) + return MODE_BAD_VVALUE; + + if (!vmw_kms_validate_mode_vram(dev_priv, + mode->hdisplay * assumed_cpp, + mode->vdisplay)) + return MODE_MEM; + + return MODE_OK; +} + +/** + * vmw_connector_get_modes - implements drm_connector_helper_funcs.get_modes callback + * + * @connector: the drm connector, part of a DU container + * + * Returns the number of added modes. + */ +int vmw_connector_get_modes(struct drm_connector *connector) +{ + struct vmw_display_unit *du = vmw_connector_to_du(connector); + struct drm_device *dev = connector->dev; + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_display_mode *mode = NULL; + struct drm_display_mode prefmode = { DRM_MODE("preferred", + DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) + }; + u32 max_width; + u32 max_height; + u32 num_modes; + + /* Add preferred mode */ + mode = drm_mode_duplicate(dev, &prefmode); + if (!mode) + return 0; + + mode->hdisplay = du->pref_width; + mode->vdisplay = du->pref_height; + vmw_guess_mode_timing(mode); + drm_mode_set_name(mode); + + drm_mode_probed_add(connector, mode); + drm_dbg_kms(dev, "preferred mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); + + /* Probe connector for all modes not exceeding our geom limits */ + max_width = dev_priv->texture_max_width; + max_height = dev_priv->texture_max_height; + + if (dev_priv->active_display_unit == vmw_du_screen_target) { + max_width = min(dev_priv->stdu_max_width, max_width); + max_height = min(dev_priv->stdu_max_height, max_height); + } + + num_modes = 1 + drm_add_modes_noedid(connector, max_width, max_height); + + return num_modes; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index db81e635dc06..a94947b588e8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -378,7 +378,6 @@ struct vmw_display_unit { unsigned pref_width; unsigned pref_height; bool pref_active; - struct drm_display_mode *pref_mode; /* * Gui positioning @@ -428,8 +427,6 @@ void vmw_du_connector_save(struct drm_connector *connector); void vmw_du_connector_restore(struct drm_connector *connector); enum drm_connector_status vmw_du_connector_detect(struct drm_connector *connector, bool force); -int vmw_du_connector_fill_modes(struct drm_connector *connector, - uint32_t max_width, uint32_t max_height); int vmw_kms_helper_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer *framebuffer, const struct drm_clip_rect *clips, @@ -438,6 +435,9 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv, int num_clips, int increment, struct vmw_kms_dirty *dirty); +enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); +int vmw_connector_get_modes(struct drm_connector *connector); void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv, struct drm_file *file_priv, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a82fa9700370..c4db4aecca6c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -304,7 +304,7 @@ static void vmw_ldu_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs vmw_legacy_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_ldu_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -313,6 +313,8 @@ static const struct drm_connector_funcs vmw_legacy_connector_funcs = { static const struct drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_connector_mode_valid }; static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, @@ -449,7 +451,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ldu->base.pref_active = (unit == 0); ldu->base.pref_width = dev_priv->initial_width; ldu->base.pref_height = dev_priv->initial_height; - ldu->base.pref_mode = NULL; /* * Remove this after enabling atomic because property values can diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 556a403b7eb5..30c3ad27b662 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -347,7 +347,7 @@ static void vmw_sou_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs vmw_sou_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_sou_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -357,6 +357,8 @@ static const struct drm_connector_funcs vmw_sou_connector_funcs = { static const struct drm_connector_helper_funcs vmw_sou_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_connector_mode_valid }; @@ -826,7 +828,6 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) sou->base.pref_active = (unit == 0); sou->base.pref_width = dev_priv->initial_width; sou->base.pref_height = dev_priv->initial_height; - sou->base.pref_mode = NULL; /* * Remove this after enabling atomic because property values can diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 6bc23bdf32c2..3c8414a13dba 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -835,7 +835,7 @@ static void vmw_stdu_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs vmw_stdu_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_stdu_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -845,6 +845,8 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = { static const struct drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_connector_mode_valid }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 10498725034c..e7a744dfcecf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -832,8 +832,6 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, srf->snooper.image = NULL; } - user_srf->prime.base.shareable = false; - user_srf->prime.base.tfile = NULL; if (drm_is_primary_client(file_priv)) user_srf->master = drm_file_get_master(file_priv); @@ -847,10 +845,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, goto out_unlock; /* - * A gb-aware client referencing a shared surface will - * expect a backup buffer to be present. + * A gb-aware client referencing a surface will expect a backup + * buffer to be present. */ - if (dev_priv->has_mob && req->shareable) { + if (dev_priv->has_mob) { struct vmw_bo_params params = { .domain = VMW_BO_DOMAIN_SYS, .busy_domain = VMW_BO_DOMAIN_SYS, @@ -869,8 +867,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } tmp = vmw_resource_reference(&srf->res); - ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime, - req->shareable, VMW_RES_SURFACE, + ret = ttm_prime_object_init(tfile, res->guest_memory_size, + &user_srf->prime, + VMW_RES_SURFACE, &vmw_user_surface_base_release); if (unlikely(ret != 0)) { @@ -1549,8 +1548,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev, tmp = vmw_resource_reference(res); ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime, - req->base.drm_surface_flags & - drm_vmw_surface_flag_shareable, VMW_RES_SURFACE, &vmw_user_surface_base_release); @@ -2052,8 +2049,6 @@ int vmw_gb_surface_define(struct vmw_private *dev_priv, } *srf_out = &user_srf->srf; - user_srf->prime.base.shareable = false; - user_srf->prime.base.tfile = NULL; srf = &user_srf->srf; srf->metadata = *req; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index af8562c95cc3..4d23d0a70bcb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -43,46 +43,14 @@ static const struct ttm_place sys_placement_flags = { .flags = 0 }; -static const struct ttm_place gmr_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_GMR, - .flags = 0 -}; - struct ttm_placement vmw_vram_placement = { .num_placement = 1, .placement = &vram_placement_flags, - .num_busy_placement = 1, - .busy_placement = &vram_placement_flags -}; - -static const struct ttm_place vram_gmr_placement_flags[] = { - { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_VRAM, - .flags = 0 - }, { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_GMR, - .flags = 0 - } -}; - -struct ttm_placement vmw_vram_gmr_placement = { - .num_placement = 2, - .placement = vram_gmr_placement_flags, - .num_busy_placement = 1, - .busy_placement = &gmr_placement_flags }; struct ttm_placement vmw_sys_placement = { .num_placement = 1, .placement = &sys_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_placement_flags }; const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt); diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 0b0e262e2166..de89f42247e1 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -38,22 +38,26 @@ static const struct ttm_place sys_placement_flags = { static struct ttm_placement sys_placement = { .num_placement = 1, .placement = &sys_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_placement_flags, }; -static const struct ttm_place tt_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = XE_PL_TT, - .flags = 0, +static const struct ttm_place tt_placement_flags[] = { + { + .fpfn = 0, + .lpfn = 0, + .mem_type = XE_PL_TT, + .flags = TTM_PL_FLAG_DESIRED, + }, + { + .fpfn = 0, + .lpfn = 0, + .mem_type = XE_PL_SYSTEM, + .flags = TTM_PL_FLAG_FALLBACK, + } }; static struct ttm_placement tt_placement = { - .num_placement = 1, - .placement = &tt_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_placement_flags, + .num_placement = 2, + .placement = tt_placement_flags, }; bool mem_type_is_vram(u32 mem_type) @@ -230,8 +234,6 @@ static int __xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo, bo->placement = (struct ttm_placement) { .num_placement = c, .placement = bo->placements, - .num_busy_placement = c, - .busy_placement = bo->placements, }; return 0; @@ -251,7 +253,6 @@ static void xe_evict_flags(struct ttm_buffer_object *tbo, /* Don't handle scatter gather BOs */ if (tbo->type == ttm_bo_type_sg) { placement->num_placement = 0; - placement->num_busy_placement = 0; return; } @@ -1353,8 +1354,6 @@ static int __xe_bo_fixed_placement(struct xe_device *xe, bo->placement = (struct ttm_placement) { .num_placement = 1, .placement = place, - .num_busy_placement = 1, - .busy_placement = place, }; return 0; @@ -2112,9 +2111,7 @@ int xe_bo_migrate(struct xe_bo *bo, u32 mem_type) xe_place_from_ttm_type(mem_type, &requested); placement.num_placement = 1; - placement.num_busy_placement = 1; placement.placement = &requested; - placement.busy_placement = &requested; /* * Stolen needs to be handled like below VRAM handling if we ever need diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 407bc07cec69..8a39b3accce5 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1166,7 +1166,7 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp) /* Choose clock source based on the DT clock handle. */ zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps, disp->dpsub->aud_clk_from_ps, - true); + disp->dpsub->vid_clk_from_ps); zynqmp_disp_avbuf_enable_channels(disp); zynqmp_disp_avbuf_enable_audio(disp); diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index a0606fab0e22..9f48e5bbcdec 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -1624,8 +1624,17 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) u32 status, mask; status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS); + /* clear status register as soon as we read it */ + zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK); - if (!(status & ~mask)) + + /* + * Status register may report some events, which corresponding interrupts + * have been disabled. Filter out those events against interrupts' mask. + */ + status &= ~mask; + + if (!status) return IRQ_NONE; /* dbg for diagnostic, but not much that the driver can do */ @@ -1634,8 +1643,6 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) if (status & ZYNQMP_DP_INT_CHBUF_OVERFLW_MASK) dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); - zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status); - if (status & ZYNQMP_DP_INT_VBLANK_START) zynqmp_dpsub_drm_handle_vblank(dp->dpsub); @@ -1721,6 +1728,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; bridge->type = DRM_MODE_CONNECTOR_DisplayPort; + bridge->of_node = dp->dev->of_node; dpsub->bridge = bridge; /* diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 2785935da497..558152575d10 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2091,9 +2091,6 @@ static int tc358743_probe(struct i2c_client *client) state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24; sd->dev = &client->dev; - err = v4l2_async_register_subdev(sd); - if (err < 0) - goto err_hdl; mutex_init(&state->confctl_mutex); @@ -2151,6 +2148,10 @@ static int tc358743_probe(struct i2c_client *client) if (err) goto err_work_queues; + err = v4l2_async_register_subdev(sd); + if (err < 0) + goto err_work_queues; + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); diff --git a/drivers/staging/sm750fb/Kconfig b/drivers/staging/sm750fb/Kconfig index ab3d9b057d56..08bcccdd0f1c 100644 --- a/drivers/staging/sm750fb/Kconfig +++ b/drivers/staging/sm750fb/Kconfig @@ -6,7 +6,6 @@ config FB_SM750 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VIDEO_NOMODESET help Frame buffer driver for the Silicon Motion SM750 chip with 2D acceleration and dual head support. diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index b694d7669d32..130ebccb8338 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -18,10 +18,7 @@ config STI_CORE STI refers to the HP "Standard Text Interface" which is a set of BIOS routines contained in a ROM chip in HP PA-RISC based machines. -config VIDEO_CMDLINE - bool - -config VIDEO_NOMODESET +config VIDEO bool default n diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 6bbc03950899..9eb5557911de 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -3,8 +3,7 @@ obj-$(CONFIG_APERTURE_HELPERS) += aperture.o obj-$(CONFIG_STI_CORE) += sticore.o obj-$(CONFIG_VGASTATE) += vgastate.o -obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o -obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o +obj-$(CONFIG_VIDEO) += cmdline.o nomodeset.o obj-$(CONFIG_HDMI) += hdmi.o obj-$(CONFIG_VT) += console/ diff --git a/drivers/video/cmdline.c b/drivers/video/cmdline.c index d3d257489c3d..49ee3fb4951a 100644 --- a/drivers/video/cmdline.c +++ b/drivers/video/cmdline.c @@ -80,6 +80,7 @@ const char *video_get_options(const char *name) } EXPORT_SYMBOL(video_get_options); +#if IS_ENABLED(CONFIG_FB_CORE) bool __video_get_options(const char *name, const char **options, bool is_of) { bool enabled = true; @@ -96,6 +97,7 @@ bool __video_get_options(const char *name, const char **options, bool is_of) return enabled; } EXPORT_SYMBOL(__video_get_options); +#endif /* * Process command line options for video adapters. This function is diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 2d0bcc1d786e..a61b8260b8f3 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -75,7 +75,6 @@ config FB_CIRRUS select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. @@ -95,7 +94,6 @@ config FB_PM2 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for cards based on the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. @@ -161,7 +159,6 @@ config FB_CYBER2000 tristate "CyberPro 2000/2010/5000 support" depends on FB && PCI && (BROKEN || !SPARC64) select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This enables support for the Integraphics CyberPro 20x0 and 5000 VGA chips used in the Rebel.com Netwinder and other machines. @@ -312,7 +309,6 @@ config FB_CT65550 bool "Chips 65550 display support" depends on (FB = y) && PPC32 && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Chips & Technologies 65550 graphics chip in PowerBooks. @@ -321,7 +317,6 @@ config FB_ASILIANT bool "Asiliant (Chips) 69000 display support" depends on (FB = y) && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Asiliant 69030 chipset @@ -331,7 +326,6 @@ config FB_IMSTT select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help The IMS Twin Turbo is a PCI-based frame buffer card bundled with many Macintosh and compatible computers. @@ -396,7 +390,6 @@ config FB_TGA select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for generic TGA and SFB+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, @@ -573,7 +566,6 @@ config FB_XVR500 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-500 and similar graphics cards based upon the 3DLABS Wildcat chipset. The driver @@ -585,7 +577,6 @@ config FB_XVR2500 bool "Sun XVR-2500 3DLABS Wildcat support" depends on (FB = y) && PCI && SPARC64 select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-2500 and similar graphics cards based upon the 3DLABS Wildcat chipset. The driver @@ -611,7 +602,6 @@ config FB_PVR2 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help Say Y here if you have a PowerVR 2 card in your box. If you plan to run linux on your Dreamcast, you will have to say Y here. @@ -674,7 +664,6 @@ config FB_NVIDIA select FB_IOMEM_FOPS select BITREVERSE select VGASTATE - select VIDEO_NOMODESET help This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use @@ -723,7 +712,6 @@ config FB_RIVA select FB_MODE_HELPERS select BITREVERSE select VGASTATE - select VIDEO_NOMODESET help This driver supports graphics boards with the nVidia Riva/Geforce chips. @@ -766,7 +754,6 @@ config FB_I740 select FB_IOMEM_HELPERS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET select FB_DDC help This driver supports graphics cards based on Intel740 chip. @@ -777,7 +764,6 @@ config FB_I810 select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports the on-board graphics built in to the Intel 810 and 815 chipsets. Say Y if you have and plan to use such a board. @@ -830,7 +816,6 @@ config FB_MATROX select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help Say Y here if you have a Matrox Millennium, Matrox Millennium II, Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox @@ -953,7 +938,6 @@ config FB_RADEON select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_MODE_HELPERS - select VIDEO_NOMODESET help Choose this option if you want to use an ATI Radeon graphics card as a framebuffer device. There are both PCI and AGP versions. You @@ -991,7 +975,6 @@ config FB_ATY128 select FB_BACKLIGHT if FB_ATY128_BACKLIGHT select FB_IOMEM_HELPERS select FB_MACMODES if PPC_PMAC - select VIDEO_NOMODESET help This driver supports graphics boards with the ATI Rage128 chips. Say Y if you have such a graphics board and read @@ -1017,7 +1000,6 @@ config FB_ATY select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_ATY_CT if SPARC64 && PCI - select VIDEO_NOMODESET help This driver supports graphics boards with the ATI Mach64 chips. Say Y if you have such a graphics board. @@ -1069,7 +1051,6 @@ config FB_S3 select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for graphics boards with S3 Trio / S3 Virge chip. @@ -1091,7 +1072,6 @@ config FB_SAVAGE select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports notebooks and computers with S3 Savage PCI/AGP chips. @@ -1131,7 +1111,6 @@ config FB_SIS select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_SIS_300 if !FB_SIS_315 - select VIDEO_NOMODESET help This is the frame buffer device driver for the SiS 300, 315, 330 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. @@ -1162,7 +1141,6 @@ config FB_VIA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select I2C_ALGOBIT - select VIDEO_NOMODESET help This is the frame buffer device driver for Graphics chips of VIA UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ @@ -1203,7 +1181,6 @@ config FB_NEOMAGIC select FB_IOMEM_FOPS select FB_MODE_HELPERS select VGASTATE - select VIDEO_NOMODESET help This driver supports notebooks with NeoMagic PCI chips. Say Y if you have such a graphics card. @@ -1215,7 +1192,6 @@ config FB_KYRO tristate "IMG Kyro support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here if you have a STG4000 / Kyro / PowerVR 3 based graphics board. @@ -1231,7 +1207,6 @@ config FB_3DFX select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS select FB_MODE_HELPERS - select VIDEO_NOMODESET help This driver supports graphics boards with the 3Dfx Banshee, Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have @@ -1260,7 +1235,6 @@ config FB_VOODOO1 depends on FB && PCI depends on FB_DEVICE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or Voodoo2 (cvg) based graphics card. @@ -1283,7 +1257,6 @@ config FB_VT8623 select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for CastleRock integrated graphics core in the @@ -1298,7 +1271,6 @@ config FB_TRIDENT select FB_DDC select FB_IOMEM_FOPS select FB_MODE_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for Trident PCI/AGP chipsets. Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D @@ -1323,7 +1295,6 @@ config FB_ARK select FB_TILEBLITTING select FB_SVGALIB select VGASTATE - select VIDEO_NOMODESET select FONT_8x16 if FRAMEBUFFER_CONSOLE help Driver for PCI graphics boards with ARK 2000PV chip @@ -1336,7 +1307,6 @@ config FB_PM3 select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_IOMEM_FOPS - select VIDEO_NOMODESET help This is the frame buffer device driver for the 3DLabs Permedia3 chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & @@ -1347,7 +1317,6 @@ config FB_CARMINE tristate "Fujitsu carmine frame buffer support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help This is the frame buffer device driver for the Fujitsu Carmine chip. The driver provides two independent frame buffer devices. @@ -1629,7 +1598,6 @@ config FB_IBM_GXT4500 tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" depends on FB select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Say Y here to enable support for the IBM GXT4000P/6000P and GXT4500P/6500P display adaptor based on Raster Engine RC1000, @@ -1747,7 +1715,6 @@ config FB_MB862XX depends on FB depends on PCI || (OF && PPC) select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. @@ -1813,7 +1780,6 @@ config FB_HYPERV depends on FB && HYPERV select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA select FB_IOMEM_HELPERS_DEFERRED - select VIDEO_NOMODESET help This framebuffer driver supports Microsoft Hyper-V Synthetic Video. @@ -1847,7 +1813,6 @@ config FB_SM712 tristate "Silicon Motion SM712 framebuffer support" depends on FB && PCI select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Frame buffer driver for the Silicon Motion SM710, SM712, SM721 and SM722 chips. diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig index 21053bf00dc5..db09fe87fcd4 100644 --- a/drivers/video/fbdev/core/Kconfig +++ b/drivers/video/fbdev/core/Kconfig @@ -4,7 +4,7 @@ # config FB_CORE - select VIDEO_CMDLINE + select VIDEO tristate config FB_NOTIFY diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index fc206755f5f6..48287366e0d4 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -645,7 +645,6 @@ int fb_new_modelist(struct fb_info *info) return 0; } -#if defined(CONFIG_VIDEO_NOMODESET) bool fb_modesetting_disabled(const char *drvname) { bool fwonly = video_firmware_drivers_only(); @@ -657,6 +656,5 @@ bool fb_modesetting_disabled(const char *drvname) return fwonly; } EXPORT_SYMBOL(fb_modesetting_disabled); -#endif MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig index 9a49916e0492..3b20420cc94d 100644 --- a/drivers/video/fbdev/geode/Kconfig +++ b/drivers/video/fbdev/geode/Kconfig @@ -14,7 +14,6 @@ config FB_GEODE_LX tristate "AMD Geode LX framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode LX processors. @@ -28,7 +27,6 @@ config FB_GEODE_GX tristate "AMD Geode GX framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode GX processors. @@ -42,7 +40,6 @@ config FB_GEODE_GX1 tristate "AMD Geode GX1 framebuffer support" depends on FB && FB_GEODE select FB_IOMEM_HELPERS - select VIDEO_NOMODESET help Framebuffer driver for the display controller integrated into the AMD Geode GX1 processor. diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index e39da5807ba7..ee12f829aaf7 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -558,6 +558,37 @@ struct drm_bridge_funcs { struct drm_connector *connector); /** + * @edid_read: + * + * Read the EDID data of the connected display. + * + * The @edid_read callback is the preferred way of reporting mode + * information for a display connected to the bridge output. Bridges + * that support reading EDID shall implement this callback and leave + * the @get_modes callback unimplemented. + * + * The caller of this operation shall first verify the output + * connection status and refrain from reading EDID from a disconnected + * output. + * + * This callback is optional. Bridges that implement it shall set the + * DRM_BRIDGE_OP_EDID flag in their &drm_bridge->ops. + * + * The connector parameter shall be used for the sole purpose of EDID + * retrieval, and shall not be stored internally by bridge drivers for + * future usage. + * + * RETURNS: + * + * An edid structure newly allocated with drm_edid_alloc() or returned + * from drm_edid_read() family of functions on success, or NULL + * otherwise. The caller is responsible for freeing the returned edid + * structure with drm_edid_free(). + */ + const struct drm_edid *(*edid_read)(struct drm_bridge *bridge, + struct drm_connector *connector); + + /** * @get_edid: * * Read and parse the EDID data of the connected display. @@ -888,8 +919,8 @@ drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge); int drm_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector); -struct edid *drm_bridge_get_edid(struct drm_bridge *bridge, - struct drm_connector *connector); +const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector); void drm_bridge_hpd_enable(struct drm_bridge *bridge, void (*cb)(void *data, enum drm_connector_status status), diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h index f1a66c048721..aa786b828a0a 100644 --- a/include/drm/drm_exec.h +++ b/include/drm/drm_exec.h @@ -18,7 +18,7 @@ struct drm_exec { /** * @flags: Flags to control locking behavior */ - uint32_t flags; + u32 flags; /** * @ticket: WW ticket used for acquiring locks @@ -135,7 +135,7 @@ static inline bool drm_exec_is_contended(struct drm_exec *exec) return !!exec->contended; } -void drm_exec_init(struct drm_exec *exec, uint32_t flags, unsigned nr); +void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr); void drm_exec_fini(struct drm_exec *exec); bool drm_exec_cleanup(struct drm_exec *exec); int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj); diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 9060f9fae6f1..00d4e43b76b6 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -518,7 +518,7 @@ struct drm_gpuvm_exec { /** * @flags: the flags for the struct drm_exec */ - uint32_t flags; + u32 flags; /** * @vm: the &drm_gpuvm to lock its DMA reservations diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h index ad08f834af40..f547b09ca023 100644 --- a/include/drm/drm_managed.h +++ b/include/drm/drm_managed.h @@ -45,6 +45,10 @@ int __must_check __drmm_add_action_or_reset(struct drm_device *dev, drmres_release_t action, void *data, const char *name); +void drmm_release_action(struct drm_device *dev, + drmres_release_t action, + void *data); + void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; /** diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h index e8d94fca2703..73fcb899a01d 100644 --- a/include/drm/drm_rect.h +++ b/include/drm/drm_rect.h @@ -129,7 +129,7 @@ static inline void drm_rect_adjust_size(struct drm_rect *r, int dw, int dh) /** * drm_rect_translate - translate the rectangle - * @r: rectangle to be tranlated + * @r: rectangle to be translated * @dx: horizontal translation * @dy: vertical translation * @@ -146,7 +146,7 @@ static inline void drm_rect_translate(struct drm_rect *r, int dx, int dy) /** * drm_rect_translate_to - translate the rectangle to an absolute position - * @r: rectangle to be tranlated + * @r: rectangle to be translated * @x: horizontal position * @y: vertical position * diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h index 8074d0f6cae5..b510a4812609 100644 --- a/include/drm/ttm/ttm_placement.h +++ b/include/drm/ttm/ttm_placement.h @@ -64,6 +64,12 @@ /* For multihop handling */ #define TTM_PL_FLAG_TEMPORARY (1 << 2) +/* Placement is never used during eviction */ +#define TTM_PL_FLAG_DESIRED (1 << 3) + +/* Placement is only used during eviction */ +#define TTM_PL_FLAG_FALLBACK (1 << 4) + /** * struct ttm_place * @@ -86,16 +92,12 @@ struct ttm_place { * * @num_placement: number of preferred placements * @placement: preferred placements - * @num_busy_placement: number of preferred placements when need to evict buffer - * @busy_placement: preferred placements when need to evict buffer * * Structure indicating the placement you request for an object. */ struct ttm_placement { unsigned num_placement; const struct ttm_place *placement; - unsigned num_busy_placement; - const struct ttm_place *busy_placement; }; #endif diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 78a226eba953..1afa13f0c22b 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -365,12 +365,8 @@ bool ttm_resource_intersects(struct ttm_device *bdev, struct ttm_resource *res, const struct ttm_place *place, size_t size); -bool ttm_resource_compatible(struct ttm_device *bdev, - struct ttm_resource *res, - const struct ttm_place *place, - size_t size); -bool ttm_resource_compat(struct ttm_resource *res, - struct ttm_placement *placement); +bool ttm_resource_compatible(struct ttm_resource *res, + struct ttm_placement *placement); void ttm_resource_set_bo(struct ttm_resource *res, struct ttm_buffer_object *bo); diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index a4eff85b1f44..2b9d856ff388 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -79,6 +79,12 @@ struct ttm_tt { * page_flags = TTM_TT_FLAG_EXTERNAL | * TTM_TT_FLAG_EXTERNAL_MAPPABLE; * + * TTM_TT_FLAG_DECRYPTED: The mapped ttm pages should be marked as + * not encrypted. The framework will try to match what the dma layer + * is doing, but note that it is a little fragile because ttm page + * fault handling abuses the DMA api a bit and dma_map_attrs can't be + * used to assure pgprot always matches. + * * TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. This is * set by TTM after ttm_tt_populate() has successfully returned, and is * then unset when TTM calls ttm_tt_unpopulate(). @@ -87,8 +93,9 @@ struct ttm_tt { #define TTM_TT_FLAG_ZERO_ALLOC BIT(1) #define TTM_TT_FLAG_EXTERNAL BIT(2) #define TTM_TT_FLAG_EXTERNAL_MAPPABLE BIT(3) +#define TTM_TT_FLAG_DECRYPTED BIT(4) -#define TTM_TT_FLAG_PRIV_POPULATED BIT(4) +#define TTM_TT_FLAG_PRIV_POPULATED BIT(5) uint32_t page_flags; /** @num_pages: Number of pages in the page array. */ uint32_t num_pages; diff --git a/include/linux/fb.h b/include/linux/fb.h index 05dc9624897d..2ce2f5c2fca9 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -840,14 +840,7 @@ extern int fb_find_mode(struct fb_var_screeninfo *var, const struct fb_videomode *default_mode, unsigned int default_bpp); -#if defined(CONFIG_VIDEO_NOMODESET) bool fb_modesetting_disabled(const char *drvname); -#else -static inline bool fb_modesetting_disabled(const char *drvname) -{ - return false; -} -#endif /* * Convenience logging macros diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index 9b162ac1e08e..5e1a9eafd10f 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -12,7 +12,6 @@ #include <linux/of_graph.h> #include <linux/hdmi.h> -#include <drm/drm_edid.h> #include <sound/asoundef.h> #include <sound/soc.h> #include <uapi/sound/asound.h> diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index 26549c86a91f..7d786a0cc835 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -1,6 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ /************************************************************************** * - * Copyright © 2009-2022 VMware, Inc., Palo Alto, CA., USA + * Copyright © 2009-2023 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -902,7 +903,8 @@ struct drm_vmw_shader_arg { /** * enum drm_vmw_surface_flags * - * @drm_vmw_surface_flag_shareable: Whether the surface is shareable + * @drm_vmw_surface_flag_shareable: Deprecated - all userspace surfaces are + * shareable. * @drm_vmw_surface_flag_scanout: Whether the surface is a scanout * surface. * @drm_vmw_surface_flag_create_buffer: Create a backup buffer if none is diff --git a/include/video/cmdline.h b/include/video/cmdline.h index 26b80cdaef79..76649465bb08 100644 --- a/include/video/cmdline.h +++ b/include/video/cmdline.h @@ -3,18 +3,14 @@ #ifndef VIDEO_CMDLINE_H #define VIDEO_CMDLINE_H +#include <linux/kconfig.h> #include <linux/types.h> -#if defined(CONFIG_VIDEO_CMDLINE) const char *video_get_options(const char *name); +#if IS_ENABLED(CONFIG_FB_CORE) /* exported for compatibility with fbdev; don't use in new code */ bool __video_get_options(const char *name, const char **option, bool is_of); -#else -static inline const char *video_get_options(const char *name) -{ - return NULL; -} #endif #endif |