[PATCH] drm/msm/dpu: make _dpu_core_perf_crtc_update_bus() void
This function does not need to return an error so make it return void. This fixes the following coccicheck warning: drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c:178:5-8: Unneeded variable: "ret". Return "0" on line 193 Signed-off-by: Jason Yan --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 11f2bebe3869..12df1955b1ef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -167,7 +167,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, return 0; } -static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, +static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, struct drm_crtc *crtc) { struct dpu_core_perf_params perf = { 0 }; @@ -175,7 +175,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, = dpu_crtc_get_client_type(crtc); struct drm_crtc *tmp_crtc; struct dpu_crtc_state *dpu_cstate; - int ret = 0; drm_for_each_crtc(tmp_crtc, crtc->dev) { if (tmp_crtc->enabled && @@ -190,7 +189,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, dpu_cstate->new_perf.bw_ctl); } } - return ret; } /** @@ -335,14 +333,8 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, trace_dpu_perf_crtc_update(crtc->base.id, new->bw_ctl, new->core_clk_rate, stop_req, update_bus, update_clk); - if (update_bus) { - ret = _dpu_core_perf_crtc_update_bus(kms, crtc); - if (ret) { - DPU_ERROR("crtc-%d: failed to update bus bw vote\n", - crtc->base.id); - return ret; - } - } + if (update_bus) + _dpu_core_perf_crtc_update_bus(kms, crtc); /* * Update the clock after bandwidth vote to ensure -- 2.21.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v3 PATCH 1/2] drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver
This adds support for TMP5P5 NT35596 1080x1920 video mode panel that can be found on some Asus Zenfone 2 Laser (Z00T) devices. This panel seems to only be found in this device and we have no straightforward way of actually getting the correct model number, as no schematics are released publicly. Signed-off-by: Konrad Dybcio --- drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-asus-z00t-tm5p5-n35596.c | 367 ++ 3 files changed, 378 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a1723c1b5fbf8..ad896a877d49f 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -18,6 +18,16 @@ config DRM_PANEL_ARM_VERSATILE reference designs. The panel is detected using special registers in the Versatile family syscon registers. +config DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 + tristate "ASUS Z00T TM5P5 NT35596 panel" + depends on GPIOLIB && OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the ASUS TMP5P5 + NT35596 1080x1920 video mode panel as found in some Asus + Zenfone 2 Laser Z00T devices. + config DRM_PANEL_BOE_HIMAX8279D tristate "Boe Himax8279d panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 96a883cd66305..3efc1de93aeeb 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o +obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o diff --git a/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c b/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c new file mode 100644 index 0..ec5599685a4c2 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct tm5p5_nt35596 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct regulator_bulk_data supplies[2]; + struct gpio_desc *reset_gpio; + bool prepared; +}; + +static inline struct tm5p5_nt35596 *to_tm5p5_nt35596(struct drm_panel *panel) +{ + return container_of(panel, struct tm5p5_nt35596, panel); +} + +#define dsi_generic_write_seq(dsi, seq...) do { \ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\ + if (ret < 0)\ + return ret; \ + } while (0) + +#define dsi_dcs_write_seq(dsi, seq...) do {\ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0)\ + return ret; \ + } while (0) + +static void tm5p5_nt35596_reset(struct tm5p5_nt35596 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(15000, 16000); +} + +static int tm5p5_nt35596_on(struct tm5p5_nt35596 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + dsi_generic_write_seq(dsi, 0xff, 0x05); + dsi_generic_write_seq(dsi, 0xfb, 0x01); + dsi_generic_write_seq(dsi, 0xc5, 0x31); + dsi_generic_write_seq(dsi, 0xff, 0x04); + dsi_generic_write_seq(dsi, 0x01, 0x84); + dsi_generic_write_seq(dsi, 0x05, 0x25); + dsi_generic_write_seq(dsi, 0x06, 0x01); + dsi_generic_write_seq(dsi, 0x07, 0x20); + dsi_generic_write_seq(dsi, 0x08, 0x06); + dsi_generic_write_seq(dsi, 0x09, 0x08); + dsi_generic_write_seq(dsi, 0x0a, 0x10); + dsi_generic_write_seq(dsi, 0x0b, 0x10); + dsi_generic_write_seq(dsi, 0x0c, 0x10); + dsi_generic_write_seq(dsi, 0x0d, 0x14); + dsi_generic_write_seq(dsi, 0x0e, 0x14); + dsi_generic_write_seq(dsi, 0x0f, 0x14); +
[PATCH] drm/amd/display: remove unused variable 'ret' in dm_suspend()
Fix the following coccicheck warning: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:1574:5-8: Unneeded variable: "ret". Return "0" on line 1586 Signed-off-by: Jason Yan --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 9c2a07626d2c..2b7588371170 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1571,7 +1571,6 @@ static int dm_suspend(void *handle) { struct amdgpu_device *adev = handle; struct amdgpu_display_manager *dm = >dm; - int ret = 0; WARN_ON(adev->dm.cached_state); adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev); @@ -1583,7 +1582,7 @@ static int dm_suspend(void *handle) dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); - return ret; + return 0; } static struct amdgpu_dm_connector * -- 2.21.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/3] drm/mediatek: mtk_dpi: Convert to bridge driver
Convert mtk_dpi to a bridge driver with built-in encoder support for compatibility with existing component drivers. Signed-off-by: Enric Balletbo i Serra --- drivers/gpu/drm/mediatek/mtk_dpi.c | 66 +++--- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 7112125dc3d1..baad198c69eb 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -61,6 +61,7 @@ enum mtk_dpi_out_color_format { struct mtk_dpi { struct mtk_ddp_comp ddp_comp; struct drm_encoder encoder; + struct drm_bridge bridge; struct drm_bridge *next_bridge; void __iomem *regs; struct device *dev; @@ -77,9 +78,9 @@ struct mtk_dpi { int refcount; }; -static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) +static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b) { - return container_of(e, struct mtk_dpi, encoder); + return container_of(b, struct mtk_dpi, bridge); } enum mtk_dpi_polarity { @@ -518,50 +519,44 @@ static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { .destroy = mtk_dpi_encoder_destroy, }; -static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, +enum drm_bridge_attach_flags flags) { - return true; + struct mtk_dpi *dpi = bridge_to_dpi(bridge); + + return drm_bridge_attach(bridge->encoder, dpi->next_bridge, +>bridge, flags); } -static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder, -struct drm_display_mode *mode, -struct drm_display_mode *adjusted_mode) +static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + struct mtk_dpi *dpi = bridge_to_dpi(bridge); drm_mode_copy(>mode, adjusted_mode); } -static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) +static void mtk_dpi_bridge_disable(struct drm_bridge *bridge) { - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + struct mtk_dpi *dpi = bridge_to_dpi(bridge); mtk_dpi_power_off(dpi); } -static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) +static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) { - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + struct mtk_dpi *dpi = bridge_to_dpi(bridge); mtk_dpi_power_on(dpi); mtk_dpi_set_display_mode(dpi, >mode); } -static int mtk_dpi_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - return 0; -} - -static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = { - .mode_fixup = mtk_dpi_encoder_mode_fixup, - .mode_set = mtk_dpi_encoder_mode_set, - .disable = mtk_dpi_encoder_disable, - .enable = mtk_dpi_encoder_enable, - .atomic_check = mtk_dpi_atomic_check, +static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = { + .attach = mtk_dpi_bridge_attach, + .mode_set = mtk_dpi_bridge_mode_set, + .disable = mtk_dpi_bridge_disable, + .enable = mtk_dpi_bridge_enable, }; static void mtk_dpi_start(struct mtk_ddp_comp *comp) @@ -602,16 +597,13 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) dev_err(dev, "Failed to initialize decoder: %d\n", ret); goto err_unregister; } - drm_encoder_helper_add(>encoder, _dpi_encoder_helper_funcs); /* Currently DPI0 is fixed to be driven by OVL1 */ dpi->encoder.possible_crtcs = BIT(1); - ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0); - if (ret) { - dev_err(dev, "Failed to attach bridge: %d\n", ret); + ret = drm_bridge_attach(>encoder, >bridge, NULL, 0); + if (ret) goto err_cleanup; - } dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; @@ -768,8 +760,15 @@ static int mtk_dpi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dpi); + dpi->bridge.funcs = _dpi_bridge_funcs; + dpi->bridge.of_node = dev->of_node; + dpi->bridge.type = DRM_MODE_CONNECTOR_DPI; + + drm_bridge_add(>bridge); + ret = component_add(dev, _dpi_component_ops); if
Re: [PATCH V2 00/11] Subject: Remove duplicated kmap code
On Mon, May 04, 2020 at 01:17:41PM -0700, Ira Weiny wrote: > > || * arm: much, much worse. We have several files that pull > > linux/highmem.h: > > || arch/arm/mm/cache-feroceon-l2.c, arch/arm/mm/cache-xsc3l2.c, > > || arch/arm/mm/copypage-*.c, arch/arm/mm/dma-mapping.c, arch/arm/mm/flush.c, > > || arch/arm/mm/highmem.c, arch/arm/probes/uprobes/core.c, > > || arch/arm/include/asm/kvm_mmu.h (kmap_atomic_pfn()). > > || Those are fine, but we also have this: > > || arch/arm/include/asm/pgtable.h:200:#define __pte_map(pmd) > > (pte_t *)kmap_atomic(pmd_page(*(pmd))) > > || arch/arm/include/asm/pgtable.h:208:#define pte_offset_map(pmd,addr) > > (__pte_map(pmd) + pte_index(addr)) > > || and sure as hell, asm/pgtable.h does *NOT* pull linux/highmem.h. > > It does not pull asm/highmem.h either... No, but the users of those macros need to be considered. > > || #define pte_offset_map(dir, addr) \ > > || ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) > > || One pte_offset_map user in arch/microblaze: > > || arch/microblaze/kernel/signal.c:207:ptep = pte_offset_map(pmdp, > > address); > > || Messy, but doesn't require any changes (we have asm/pgalloc.h included > > || there, and that pull linux/highmem.h). > > AFAICS asm/pgtable.h does not include asm/highmem.h here... > > So looks like arch/microblaze/kernel/signal.c will need linux/highmem.h See above - line 39 in there is #include and line 14 in arch/microblaze/include/asm/pgalloc.h is #include It's conditional upon CONFIG_MMU in there, but so's the use of pte_offset_map() in arch/microblaze/kernel/signal.c So it shouldn't be a problem. > > || * xtensa: users in arch/xtensa/kernel/pci-dma.c, > > arch/xtensa/mm/highmem.c, > > || arch/xtensa/mm/cache.c and arch/xtensa/platforms/iss/simdisk.c (all pull > > || linux/highmem.h). > > Actually > > arch/xtensa/mm/cache.c gets linux/highmem.h from linux/pagemap.h > > arch/xtensa/platforms/iss/simdisk.c may have an issue? > linux/blkdev.h -> CONFIG_BLOCK -> linux/pagemap.h -> linux/highmem.h > But simdisk.c requires BLK_DEV_SIMDISK -> CONFIG_BLOCK... > Yep - see above re major chain of indirect includes conditional upon CONFIG_BLOCK and its uses in places that only build with such configs. There's a plenty of similar considerations outside of arch/*, unfortunately... ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v2 PATCH 2/2] dt-bindings: display: Document ASUS Z00T TM5P5 NT35596 panel compatible
Signed-off-by: Konrad Dybcio --- .../display/panel/asus,z00t-tm5p5-n35596.yaml | 56 +++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml diff --git a/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml b/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml new file mode 100644 index 0..aa8940e493eb1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/tm5p5,nt35596.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASUS Z00T TM5P5 NT35596 5.5" 1080×1920 LCD Panel + +maintainers: + - Konrad Dybcio + +description: |+ + This panel seems to only be found in the Asus Z00T + smartphone and we have no straightforward way of + actually getting the correct model number, + as no schematics are released publicly. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: asus,z00t-tm5p5-n35596 + reg: true + reset-gpios: true + vdd-supply: + description: core voltage supply + vddio-supply: + description: vddio supply + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +dsi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +reg = <0>; + +compatible = "asus,z00t-tm5p5-n35596"; + +vdd-supply = <_l8>; +vddio-supply = <_l6>; +reset-gpios = < 25 GPIO_ACTIVE_HIGH>; +}; +}; -- 2.26.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/3] drm/mediatek: mtk_dpi: Rename bridge to next_bridge
This is really a cosmetic change just to make a bit more readable the code after convert the driver to drm_bridge. The bridge variable name will be used by the encoder drm_bridge, and the chained bridge will be named next_bridge. Signed-off-by: Enric Balletbo i Serra --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 7fbfa95bab09..7112125dc3d1 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -61,7 +61,7 @@ enum mtk_dpi_out_color_format { struct mtk_dpi { struct mtk_ddp_comp ddp_comp; struct drm_encoder encoder; - struct drm_bridge *bridge; + struct drm_bridge *next_bridge; void __iomem *regs; struct device *dev; struct clk *engine_clk; @@ -607,7 +607,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) /* Currently DPI0 is fixed to be driven by OVL1 */ dpi->encoder.possible_crtcs = BIT(1); - ret = drm_bridge_attach(>encoder, dpi->bridge, NULL, 0); + ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0); if (ret) { dev_err(dev, "Failed to attach bridge: %d\n", ret); goto err_cleanup; @@ -747,11 +747,11 @@ static int mtk_dpi_probe(struct platform_device *pdev) } ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, - NULL, >bridge); + NULL, >next_bridge); if (ret) return ret; - dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node); + dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node); comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); if (comp_id < 0) { -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/3] Convert mtk-dpi to drm_bridge API
The mtk-dpi driver still uses the drm_encoder API which is now somehow deprecated. We started to move all the Mediatek drivers to the drm_bridge API, like we did for the mtk-dsi driver [1], this is another small step to be able to fully convert the DRM Mediatek drivers to the drm_bridge API. A dummy drm_encoder is maintained in the mtk-dpi driver but the end goal is move all the dummy drm_encoder (mtk-dsi, mtk-dpi, etc) to the main mtk_drm_drv driver. Best regards, Enric [1] https://lore.kernel.org/patchwork/project/lkml/list/?series=441559 Enric Balletbo i Serra (3): drm/mediatek: mtk_dpi: Rename bridge to next_bridge drm/mediatek: mtk_dpi: Convert to bridge driver drm/mediatek: mtk_dpi: Use simple encoder drivers/gpu/drm/mediatek/mtk_dpi.c | 84 ++ 1 file changed, 39 insertions(+), 45 deletions(-) -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: ingenic-drm: add MODULE_DEVICE_TABLE
Hi Nikolaus, Le lun. 4 mai 2020 à 8:35, H. Nikolaus Schaller a écrit : so that the driver can load by matching the device tree if compiled as module. Cc: sta...@vger.kernel.org # v5.3+ Fixes: 90b86fcc47b4 ("DRM: Add KMS driver for the Ingenic JZ47xx SoCs") Signed-off-by: H. Nikolaus Schaller Applied, thanks. -Paul --- drivers/gpu/drm/ingenic/ingenic-drm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 9dfe7cb530e11..1754c05470690 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -843,6 +843,7 @@ static const struct of_device_id ingenic_drm_of_match[] = { { .compatible = "ingenic,jz4770-lcd", .data = _soc_info }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); static struct platform_driver ingenic_drm_driver = { .driver = { -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] nand: brcmnand: correctly verify erased pages
On 5/4/2020 2:29 AM, Álvaro Fernández Rojas wrote: > The current code checks that the whole OOB area is erased. > This is a problem when JFFS2 cleanmarkers are added to the OOB, since it will > fail due to the usable OOB bytes not being 0xff. > Correct this by only checking that the ECC aren't 0xff. > > Signed-off-by: Álvaro Fernández Rojas Can you provide a Fixes: tag for this change? > --- > drivers/mtd/nand/raw/brcmnand/brcmnand.c | 22 ++ > 1 file changed, 18 insertions(+), 4 deletions(-) > > diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c > b/drivers/mtd/nand/raw/brcmnand/brcmnand.c > index e4e3ceeac38f..546f0807b887 100644 > --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c > +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c > @@ -2018,6 +2018,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, > struct nand_chip *chip, > static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, > struct nand_chip *chip, void *buf, u64 addr) > { > + struct mtd_oob_region oobecc; > int i, sas; > void *oob = chip->oob_poi; > int bitflips = 0; > @@ -2035,11 +2036,24 @@ static int brcmstb_nand_verify_erased_page(struct > mtd_info *mtd, > if (ret) > return ret; > > - for (i = 0; i < chip->ecc.steps; i++, oob += sas) { > + for (i = 0; i < chip->ecc.steps; i++) { > ecc_chunk = buf + chip->ecc.size * i; > - ret = nand_check_erased_ecc_chunk(ecc_chunk, > - chip->ecc.size, > - oob, sas, NULL, 0, > + > + ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, > + NULL, 0, NULL, 0, > + chip->ecc.strength); > + if (ret < 0) > + return ret; > + > + bitflips = max(bitflips, ret); > + } > + > + for (i = 0; mtd->ooblayout->ecc(mtd, i, ) != -ERANGE; i++) > + { > + ret = nand_check_erased_ecc_chunk(NULL, 0, > + oob + oobecc.offset, > + oobecc.length, > + NULL, 0, > chip->ecc.strength); > if (ret < 0) > return ret; > -- Florian ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] nand: brcmnand: fix BBI in hamming oob layout
Small Page NAND uses byte 6 for BBI and Large Page NAND uses first 2 bytes. Signed-off-by: Álvaro Fernández Rojas --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 1bba309c7684..59c3241f4ea5 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1109,10 +1109,18 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, if (section < sectors) next += 6; - if (section) + if (section) { oobregion->offset = ((section - 1) * sas) + 9; - else - oobregion->offset = 1; /* BBI */ + } else { + if (cfg->page_size == 512) { + /* small page uses byte 6 for BBI */ + oobregion->offset = 0; + next--; + } else { + /* large page uses first 2 bytes for BBI */ + oobregion->offset = 2; + } + } oobregion->length = next - oobregion->offset; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: ti-sn65dsi86: Implement lane reordering + polarity
Quoting Douglas Anderson (2020-05-04 21:36:31) > The ti-sn65dsi86 MIPI DSI to eDP bridge chip supports arbitrary > remapping of eDP lanes and also polarity inversion. Both of these > features have been described in the device tree bindings for the > device since the beginning but were never implemented in the driver. > Implement both of them. > > Part of this change also allows you to (via the same device tree > bindings) specify to use fewer than the max number of DP lanes that > the panel reports. This could be useful if your display supports more > lanes but only a few are hooked up on your board. > > Signed-off-by: Douglas Anderson > --- Except for one thing below: Reviewed-by: Stephen Boyd > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > index 1a125423eb07..52cca54b525f 100644 > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > @@ -707,26 +716,20 @@ static void ti_sn_bridge_enable(struct drm_bridge > *bridge) > int dp_rate_idx; > unsigned int val; > int ret = -EINVAL; > + int max_dp_lanes; > > - /* > -* Run with the maximum number of lanes that the DP sink supports. > -* > -* Depending use cases, we might want to revisit this later because: > -* - It's plausible that someone may have run fewer lines to the > -* sink than the sink actually supports, assuming that the lines > -* will just be driven at a higher rate. > -* - The DP spec seems to indicate that it's more important to > minimize > -* the number of lanes than the link rate. > -* > -* If we do revisit, it would be important to measure the power > impact. > -*/ > - pdata->dp_lanes = ti_sn_get_max_lanes(pdata); > + max_dp_lanes = ti_sn_get_max_lanes(pdata); > + pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes); > > /* DSI_A lane config */ > val = CHA_DSI_LANES(4 - pdata->dsi->lanes); Not a problem in this patch, but maybe this can be SN_MAX_DP_LANES - pdata->dsi->lanes now. > regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, >CHA_DSI_LANES_MASK, val); > > + regmap_write(pdata->regmap, SN_LN_ASSIGN_REG, pdata->ln_assign); > + regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, LN_POLRS_MASK, > + pdata->ln_polrs << LN_POLRS_OFFSET); > + > /* set dsi clk frequency value */ > ti_sn_bridge_set_dsi_rate(pdata); > > @@ -1063,6 +1066,50 @@ static int ti_sn_setup_gpio_controller(struct > ti_sn_bridge *pdata) > return ret; > } > > +static void ti_sn_bridge_parse_lanes(struct ti_sn_bridge *pdata, > +struct device_node *np) > +{ > + u32 lane_assignments[SN_MAX_DP_LANES] = { 0, 1, 2, 3 }; > + u32 lane_polarities[SN_MAX_DP_LANES] = { }; > + struct device_node *endpoint; > + u8 ln_assign = 0; > + u8 ln_polrs = 0; Do we need to assign to 0 to start? Seems like no? > + int dp_lanes; > + int i; > + > + /* > +* Read config from the device tree about lane remapping and lane > +* polarities. These are optional and we assume identity map and > +* normal polarity if nothing is specified. It's OK to specify just > +* data-lanes but not lane-polarities but not vice versa. > +*/ > + endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); > + dp_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); > + if (dp_lanes > 0) { > + of_property_read_u32_array(endpoint, "data-lanes", > + lane_assignments, dp_lanes); > + of_property_read_u32_array(endpoint, "lane-polarities", > + lane_polarities, dp_lanes); > + } else { > + dp_lanes = SN_MAX_DP_LANES; > + } Needs an of_node_put(endpoint) here for the of_graph_get_endpoint_by_regs() above. > + > + /* > +* Convert into register format. Loop over all lanes even if > +* data-lanes had fewer elements so that we nicely initialize > +* the LN_ASSIGN register. > +*/ > + for (i = SN_MAX_DP_LANES - 1; i >= 0; i--) { > + ln_assign = ln_assign << LN_ASSIGN_WIDTH | > lane_assignments[i]; > + ln_polrs = ln_polrs << 1 | lane_polarities[i]; > + } > + > + /* Stash in our struct for when we power on */ > + pdata->dp_lanes = dp_lanes; > + pdata->ln_assign = ln_assign; > + pdata->ln_polrs = ln_polrs; > +} ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH] drm/i915: check to see if SIMD registers are available before using SIMD
From: Christoph Hellwig > Sent: 04 May 2020 17:03 > > On Sun, May 03, 2020 at 09:20:19PM +0100, Chris Wilson wrote: > > > Err, why does i915 implements its own uncached memcpy instead of relying > > > on core functionality to start with? > > > > What is this core functionality that provides movntqda? > > A sensible name might be memcpy_uncached or mempcy_nontemporal. > But the important point is that this should be arch code with a common > fallback rather than hacking it up in drivers. More the point, you are trying to do a copy where: 1) The kernel isn't expected to read the data - so can bypass the cache. and maybe: 2) The data needs flushing from the cache to actual memory. and maybe: 3) The cache lines need invalidating. The fallbacks depend on the required behaviour. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 3/3] drm/bridge: chrontel-ch7033: Add a new driver
On 04/05/2020 22:06, Sam Ravnborg wrote: > Hi Lubomir. > > Drivers looks good. I look forward to the day we have moved > connector stuff to the displaydriver - this will simplify this driver > even more. > > One Q in the following. > > Sam > > On Fri, Apr 24, 2020 at 11:35:39PM +0200, Lubomir Rintel wrote: >> This is a driver for video encoder with VGA and DVI/HDMI outputs. >> >> There is no documentation for the chip -- the operation was guessed from >> what was sniffed on a Dell Wyse 3020 ThinOS terminal, the register names >> come from the ch7035 driver in Mediatek's GPL code dump. >> >> Only bare minimum is implemented -- no fancy stuff, such as scaling. That >> would only worsen our misery. We don't load the firmware and we don't need >> to even bother enabling the MCU. There are probably no distributable >> firmware images anyway. >> >> Tested with a handful of monitors ranging from 1024x768@75 to 1400x1050@60, >> with VGA as well as DVI. >> >> Signed-off-by: Lubomir Rintel > Acked-by: Sam Ravnborg >> >> --- >> Changes since v4: >> - Removed the registration with the component framework and creation of >> drm_encoder. >> >> Changes since v3: >> - Cosmetic changes; drop ch7033_encoder_destroy() and use >> drm_encoder_cleanup() for drm_encoder_funcs.destroy callback >> directly. >> >> Changes since v1: >> - Sort the includes >> - Drop a useless model id read >> - Chain to the bridge-connector instead of dealing with the HPD/EDID >> readout machinery ourselves >> - Utilize regmap to access the registers >> >> drivers/gpu/drm/bridge/Kconfig | 10 + >> drivers/gpu/drm/bridge/Makefile | 1 + >> drivers/gpu/drm/bridge/chrontel-ch7033.c | 620 +++ >> 3 files changed, 631 insertions(+) >> create mode 100644 drivers/gpu/drm/bridge/chrontel-ch7033.c >> >> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig >> index aaed2347ace9..0ebc72d62a5b 100644 >> --- a/drivers/gpu/drm/bridge/Kconfig >> +++ b/drivers/gpu/drm/bridge/Kconfig >> @@ -27,6 +27,16 @@ config DRM_CDNS_DSI >>Support Cadence DPI to DSI bridge. This is an internal >>bridge and is meant to be directly embedded in a SoC. >> >> +config DRM_CHRONTEL_CH7033 >> +tristate "Chrontel CH7033 Video Encoder" >> +depends on OF >> +select DRM_KMS_HELPER >> +help >> + Enable support for the Chrontel CH7033 VGA/DVI/HDMI Encoder, as >> + found in the Dell Wyse 3020 thin client. >> + >> + If in doubt, say "N". >> + >> config DRM_DISPLAY_CONNECTOR >> tristate "Display connector support" >> depends on OF >> diff --git a/drivers/gpu/drm/bridge/Makefile >> b/drivers/gpu/drm/bridge/Makefile >> index 6fb062b5b0f0..a844315feddb 100644 >> --- a/drivers/gpu/drm/bridge/Makefile >> +++ b/drivers/gpu/drm/bridge/Makefile >> @@ -1,5 +1,6 @@ >> # SPDX-License-Identifier: GPL-2.0 >> obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o >> +obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o >> obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o >> obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o >> obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += >> megachips-stdp-ge-b850v3-fw.o >> diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c >> b/drivers/gpu/drm/bridge/chrontel-ch7033.c >> new file mode 100644 >> index ..f8675d82974b >> --- /dev/null >> +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c >> @@ -0,0 +1,620 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Chrontel CH7033 Video Encoder Driver >> + * >> + * Copyright (C) 2019,2020 Lubomir Rintel >> + */ >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* Page 0, Register 0x07 */ >> +enum { >> +DRI_PD = BIT(3), >> +IO_PD = BIT(5), >> +}; >> + >> +/* Page 0, Register 0x08 */ >> +enum { >> +DRI_PDDRI = GENMASK(7, 4), >> +PDDAC = GENMASK(3, 1), >> +PANEN = BIT(0), >> +}; >> + >> +/* Page 0, Register 0x09 */ >> +enum { >> +DPD = BIT(7), >> +GCKOFF = BIT(6), >> +TV_BP = BIT(5), >> +SCLPD = BIT(4), >> +SDPD= BIT(3), >> +VGA_PD = BIT(2), >> +HDBKPD = BIT(1), >> +HDMI_PD = BIT(0), >> +}; >> + >> +/* Page 0, Register 0x0a */ >> +enum { >> +MEMINIT = BIT(7), >> +MEMIDLE = BIT(6), >> +MEMPD = BIT(5), >> +STOP= BIT(4), >> +LVDS_PD = BIT(3), >> +HD_DVIB = BIT(2), >> +HDCP_PD = BIT(1), >> +MCU_PD = BIT(0), >> +}; >> + >> +/* Page 0, Register 0x18 */ >> +enum { >> +IDF = GENMASK(7, 4), >> +INTEN = BIT(3), >> +SWAP= GENMASK(2, 0), >> +}; >> + >> +enum { >> +BYTE_SWAP_RGB = 0, >> +BYTE_SWAP_RBG = 1, >> +BYTE_SWAP_GRB = 2, >> +
Re: [v2 PATCH 1/2] drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver
On 5/4/20 12:38 PM, Konrad Dybcio wrote: > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index a1723c1b5fbf8..3aa57a927c4bd 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -18,6 +18,16 @@ config DRM_PANEL_ARM_VERSATILE > reference designs. The panel is detected using special registers > in the Versatile family syscon registers. > > +config DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 > +tristate "ASUS Z00T TM5P5 NT35596 panel" > +depends on GPIOLIB && OF > +depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > +help > + Say Y here if you want to enable support for the ASUS TMP5P5 > + NT35596 1080x1920 video mode panel as found in some Asus > + Zenfone 2 Laser Z00T devices. > + > config DRM_PANEL_BOE_HIMAX8279D > tristate "Boe Himax8279d panel" > depends on OF Hi, Please clean up the config entry indentation. The keywords (tristate, depends, help) should all be indented with one tab (not spaces) and the help text should be indented with one tab + 2 spaces. thanks. -- ~Randy ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/17] drm/mgag200: Convert to atomic modesetting
> On May 4, 2020, at 8:39 AM, Thomas Zimmermann wrote: > > Hi John > > Am 30.04.20 um 02:11 schrieb John Donnelly: >> On 4/29/20 9:32 AM, Thomas Zimmermann wrote: >>> This patchset converts mgag200 to atomic modesetting. It uses simple >>> KMS helpers and SHMEM. >>> >>> Patches 1 to 4 simplifies the driver before the conversion. For example, >>> the HW cursor is not usable with the way universal planes work. A few >>> data structures can be cleaned up. >>> >>> Patches 5 to 15 untangle the existing modesetting code into smaller >>> functions. Specifically, mode setting and plane updates are being >>> separated from each other. >>> >>> Patch 16 converts mgag200 to simple KMS helpers and enables atomic >>> mode setting. >>> >>> As some HW seems to require a framebuffer offset of 0 within the video >>> memory, it does not work with atomic modesetting. Atomically switching >>> plane framebuffers, requires either source or target buffer to be located >>> at a non-0 offet. To resolve this problem, patch 17 converts mgag200 from >>> VRAM helpers to SHMEM helpers. During plane updates, the content of the >>> SHMEM BO is memcpy'd to VRAM. From my subjective obersation, performance >>> is not nuch different from the original code. >>> >>> The patchset has been tested on MGA G200EH hardware. >>> >>> Thomas Zimmermann (17): >>>drm/mgag200: Remove HW cursor >>>drm/mgag200: Remove unused fields from struct mga_device >>>drm/mgag200: Embed connector instance in struct mga_device >>>drm/mgag200: Use managed mode-config initialization >>>drm/mgag200: Clean up mga_set_start_address() >>>drm/mgag200: Clean up mga_crtc_do_set_base() >>>drm/mgag200: Move mode-setting code into separate helper function >>>drm/mgag200: Split MISC register update into PLL selection, SYNC and >>> I/O >>>drm/mgag200: Update mode registers after plane registers >>>drm/mgag200: Set pitch in a separate helper function >>>drm/mgag200: Set primary plane's format in separate helper function >>>drm/mgag200: Move TAGFIFO reset into separate function >>>drm/mgag200: Move hiprilvl setting into separate functions >>>drm/mgag200: Move register initialization into separate function >>>drm/mgag200: Remove waiting from DPMS code >>>drm/mgag200: Convert to simple KMS helper >>>drm/mgag200: Replace VRAM helpers with SHMEM helpers >>> >>> drivers/gpu/drm/mgag200/Kconfig | 4 +- >>> drivers/gpu/drm/mgag200/Makefile | 2 +- >>> drivers/gpu/drm/mgag200/mgag200_cursor.c | 319 >>> drivers/gpu/drm/mgag200/mgag200_drv.c| 51 +- >>> drivers/gpu/drm/mgag200/mgag200_drv.h| 43 +- >>> drivers/gpu/drm/mgag200/mgag200_main.c | 28 - >>> drivers/gpu/drm/mgag200/mgag200_mode.c | 948 --- >>> drivers/gpu/drm/mgag200/mgag200_reg.h| 5 +- >>> drivers/gpu/drm/mgag200/mgag200_ttm.c| 35 +- >>> 9 files changed, 563 insertions(+), 872 deletions(-) >>> delete mode 100644 drivers/gpu/drm/mgag200/mgag200_cursor.c >>> >>> -- >>> 2.26.0 >>> >> >> >> Hi Thomas , >> >> I would like to test this on hardware that uses this device integrated >> into as BMC ( iLo ) that I have ran into problems before. Can you post >> your staging URL so I can clone it ? > > I uploaded the patches at > > > https://gitlab.freedesktop.org/tzimmermann/linux/-/tree/mgag200-simplekms-20200504 > > You can clone them with > > git clone g...@gitlab.freedesktop.org:tzimmermann/linux.git > > and checkout the mgag200-simplekms-20200405 branch afterwards. > > Best regards > Thomas Got it . Thank you . ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v3 PATCH 0/2] Add support for ASUS Z00T TM5P5 NT35596 panel
changes since v2: - fix Kconfig indentation changes since v1: - make `backlight_properties props` constant - a couple of line breaks - change name and compatible to reflect ASUS being the vendor - remove a redundant TODO Konrad Dybcio (2): drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver dt-bindings: display: Document ASUS Z00T TM5P5 NT35596 panel compatible .../display/panel/asus,z00t-tm5p5-n35596.yaml | 56 +++ drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-asus-z00t-tm5p5-n35596.c | 367 ++ 4 files changed, 434 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml create mode 100644 drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c -- 2.26.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
linux-5.7-rc4/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c:1393: bad loop termination condition ?
Hello there, linux-5.7-rc4/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c:1393:63: style: Unsigned expression 'j' can't be negative so it is unnecessary to test it. [unsignedPositive] Source code is for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { but unsigned int i, j, closest_clk_lvl; so it looks like the loop never terminates. Suggest code rework. Regards David Binderman ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] nand: brcmnand: correctly verify erased pages
The current code checks that the whole OOB area is erased. This is a problem when JFFS2 cleanmarkers are added to the OOB, since it will fail due to the usable OOB bytes not being 0xff. Correct this by only checking that the ECC aren't 0xff. Signed-off-by: Álvaro Fernández Rojas --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 22 ++ 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index e4e3ceeac38f..546f0807b887 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -2018,6 +2018,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, struct nand_chip *chip, void *buf, u64 addr) { + struct mtd_oob_region oobecc; int i, sas; void *oob = chip->oob_poi; int bitflips = 0; @@ -2035,11 +2036,24 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, if (ret) return ret; - for (i = 0; i < chip->ecc.steps; i++, oob += sas) { + for (i = 0; i < chip->ecc.steps; i++) { ecc_chunk = buf + chip->ecc.size * i; - ret = nand_check_erased_ecc_chunk(ecc_chunk, - chip->ecc.size, - oob, sas, NULL, 0, + + ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, + NULL, 0, NULL, 0, + chip->ecc.strength); + if (ret < 0) + return ret; + + bitflips = max(bitflips, ret); + } + + for (i = 0; mtd->ooblayout->ecc(mtd, i, ) != -ERANGE; i++) + { + ret = nand_check_erased_ecc_chunk(NULL, 0, + oob + oobecc.offset, + oobecc.length, + NULL, 0, chip->ecc.strength); if (ret < 0) return ret; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v2 PATCH 1/2] drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver
This adds support for TMP5P5 NT35596 1080x1920 video mode panel that can be found on some Asus Zenfone 2 Laser (Z00T) devices. This panel seems to only be found in this device and we have no straightforward way of actually getting the correct model number, as no schematics are released publicly. Signed-off-by: Konrad Dybcio --- drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-asus-z00t-tm5p5-n35596.c | 367 ++ 3 files changed, 378 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a1723c1b5fbf8..3aa57a927c4bd 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -18,6 +18,16 @@ config DRM_PANEL_ARM_VERSATILE reference designs. The panel is detected using special registers in the Versatile family syscon registers. +config DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 +tristate "ASUS Z00T TM5P5 NT35596 panel" +depends on GPIOLIB && OF +depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE +help + Say Y here if you want to enable support for the ASUS TMP5P5 + NT35596 1080x1920 video mode panel as found in some Asus + Zenfone 2 Laser Z00T devices. + config DRM_PANEL_BOE_HIMAX8279D tristate "Boe Himax8279d panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 96a883cd66305..3efc1de93aeeb 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o +obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596.o obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o diff --git a/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c b/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c new file mode 100644 index 0..ec5599685a4c2 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct tm5p5_nt35596 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct regulator_bulk_data supplies[2]; + struct gpio_desc *reset_gpio; + bool prepared; +}; + +static inline struct tm5p5_nt35596 *to_tm5p5_nt35596(struct drm_panel *panel) +{ + return container_of(panel, struct tm5p5_nt35596, panel); +} + +#define dsi_generic_write_seq(dsi, seq...) do { \ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\ + if (ret < 0)\ + return ret; \ + } while (0) + +#define dsi_dcs_write_seq(dsi, seq...) do {\ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0)\ + return ret; \ + } while (0) + +static void tm5p5_nt35596_reset(struct tm5p5_nt35596 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(15000, 16000); +} + +static int tm5p5_nt35596_on(struct tm5p5_nt35596 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + dsi_generic_write_seq(dsi, 0xff, 0x05); + dsi_generic_write_seq(dsi, 0xfb, 0x01); + dsi_generic_write_seq(dsi, 0xc5, 0x31); + dsi_generic_write_seq(dsi, 0xff, 0x04); + dsi_generic_write_seq(dsi, 0x01, 0x84); + dsi_generic_write_seq(dsi, 0x05, 0x25); + dsi_generic_write_seq(dsi, 0x06, 0x01); + dsi_generic_write_seq(dsi, 0x07, 0x20); + dsi_generic_write_seq(dsi, 0x08, 0x06); + dsi_generic_write_seq(dsi, 0x09, 0x08); + dsi_generic_write_seq(dsi, 0x0a, 0x10); + dsi_generic_write_seq(dsi, 0x0b, 0x10); + dsi_generic_write_seq(dsi, 0x0c, 0x10); + dsi_generic_write_seq(dsi, 0x0d, 0x14); + dsi_generic_write_seq(dsi, 0x0e, 0x14); + dsi_generic_write_seq(dsi, 0x0f, 0x14); +
[PATCH -next] drm/radeon: fix unsigned comparison with 0
Fixes warning because pipe is unsigned long and can never be negtative vers/gpu/drm/radeon/radeon_kms.c:831:11: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] if (pipe < 0 || pipe >= rdev->num_crtc) { drivers/gpu/drm/radeon/radeon_kms.c:857:11: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] if (pipe < 0 || pipe >= rdev->num_crtc) { Reported-by: Hulk Robot Signed-off-by: ChenTao --- drivers/gpu/drm/radeon/radeon_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 372962358a18..c5d1dc9618a4 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -828,7 +828,7 @@ int radeon_enable_vblank_kms(struct drm_crtc *crtc) unsigned long irqflags; int r; - if (pipe < 0 || pipe >= rdev->num_crtc) { + if (pipe >= rdev->num_crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); return -EINVAL; } @@ -854,7 +854,7 @@ void radeon_disable_vblank_kms(struct drm_crtc *crtc) struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; - if (pipe < 0 || pipe >= rdev->num_crtc) { + if (pipe >= rdev->num_crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); return; } -- 2.22.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v1] drm/msm/dpu: update bandwidth threshold check
Maximum allowed bandwidth has no dependency on the type of panel used. Hence, cleanup the code to use max_bw_high as the threshold value for bandwidth checks. Update the maximum allowed bandwidth as 6.8Gbps for SC7180 target. Signed-off-by: Krishna Manikandan --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 23 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 11f2beb..7c230f7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -36,22 +36,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) return to_dpu_kms(priv->kms); } -static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc) -{ - struct drm_crtc *tmp_crtc; - - drm_for_each_crtc(tmp_crtc, crtc->dev) { - if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) && - tmp_crtc->enabled) { - DPU_DEBUG("video interface connected crtc:%d\n", - tmp_crtc->base.id); - return true; - } - } - - return false; -} - static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms, struct drm_crtc *crtc, struct drm_crtc_state *state, @@ -94,7 +78,6 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, u32 bw, threshold; u64 bw_sum_of_intfs = 0; enum dpu_crtc_client_type curr_client_type; - bool is_video_mode; struct dpu_crtc_state *dpu_cstate; struct drm_crtc *tmp_crtc; struct dpu_kms *kms; @@ -144,11 +127,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000); DPU_DEBUG("calculated bandwidth=%uk\n", bw); - is_video_mode = dpu_crtc_get_intf_mode(crtc) == INTF_MODE_VIDEO; - threshold = (is_video_mode || - _dpu_core_video_mode_intf_connected(crtc)) ? - kms->catalog->perf.max_bw_low : - kms->catalog->perf.max_bw_high; + threshold = kms->catalog->perf.max_bw_high; DPU_DEBUG("final threshold bw limit = %d\n", threshold); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index c567917..6ad7472 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -515,8 +515,8 @@ }; static const struct dpu_perf_cfg sc7180_perf_data = { - .max_bw_low = 390, - .max_bw_high = 550, + .max_bw_low = 680, + .max_bw_high = 680, .min_core_ib = 240, .min_llcc_ib = 80, .min_dram_ib = 80, -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[v3 PATCH 2/2] dt-bindings: display: Document ASUS Z00T TM5P5 NT35596 panel compatible
Signed-off-by: Konrad Dybcio --- .../display/panel/asus,z00t-tm5p5-n35596.yaml | 56 +++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml diff --git a/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml b/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml new file mode 100644 index 0..aa8940e493eb1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/tm5p5,nt35596.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASUS Z00T TM5P5 NT35596 5.5" 1080×1920 LCD Panel + +maintainers: + - Konrad Dybcio + +description: |+ + This panel seems to only be found in the Asus Z00T + smartphone and we have no straightforward way of + actually getting the correct model number, + as no schematics are released publicly. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: asus,z00t-tm5p5-n35596 + reg: true + reset-gpios: true + vdd-supply: + description: core voltage supply + vddio-supply: + description: vddio supply + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +dsi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +reg = <0>; + +compatible = "asus,z00t-tm5p5-n35596"; + +vdd-supply = <_l8>; +vddio-supply = <_l6>; +reset-gpios = < 25 GPIO_ACTIVE_HIGH>; +}; +}; -- 2.26.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/2] nand: brcmnand: improve hamming oob layout
The current code generates 8 oob sections: S1 1-5 ECC 6-8 S2 9-15 S3 16-21 ECC 22-24 S4 25-31 S5 32-37 ECC 38-40 S6 41-47 S7 48-53 ECC 54-56 S8 57-63 Change it by merging continuous sections: S1 1-5 ECC 6-8 S2 9-21 ECC 22-24 S3 25-37 ECC 38-40 S4 41-53 ECC 54-56 S5 57-63 Signed-off-by: Álvaro Fernández Rojas --- v2: keep original comment and fix correctly skip byte 6 for small-page nand drivers/mtd/nand/raw/brcmnand/brcmnand.c | 34 +--- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index e4e3ceeac38f..767343e0e6e7 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1100,30 +1100,32 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, struct brcmnand_cfg *cfg = >hwcfg; int sas = cfg->spare_area_size << cfg->sector_size_1k; int sectors = cfg->page_size / (512 << cfg->sector_size_1k); + u32 next; - if (section >= sectors * 2) + if (section > sectors) return -ERANGE; - oobregion->offset = (section / 2) * sas; + next = (section * sas); + if (section < sectors) + next += 6; - if (section & 1) { - oobregion->offset += 9; - oobregion->length = 7; + if (section) { + oobregion->offset = ((section - 1) * sas) + 9; } else { - oobregion->length = 6; - - /* First sector of each page may have BBI */ - if (!section) { - /* -* Small-page NAND use byte 6 for BBI while large-page -* NAND use byte 0. -*/ - if (cfg->page_size > 512) - oobregion->offset++; - oobregion->length--; + /* +* Small-page NAND use byte 6 for BBI while large-page +* NAND use byte 0. +*/ + if (cfg->page_size > 512) { + oobregion->offset = 1; + } else { + oobregion->offset = 0; + next--; } } + oobregion->length = next - oobregion->offset; + return 0; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 20/91] clk: bcm: rpi: Discover the firmware clocks
Hi Maxime, as always, thanks for the series! Some extra context, and comments below. On Fri, 2020-04-24 at 17:34 +0200, Maxime Ripard wrote: > The RaspberryPi4 firmware actually exposes more clocks than are currently > handled by the driver and we will need to change some of them directly > based on the pixel rate for the display related clocks, or the load for the > GPU. > > This rate change can have a number of side-effects, including adjusting the > various PLL voltages or the PLL parents. The firmware will also update > those clocks by itself for example if the SoC runs too hot. To complete this: RPi4's firmware implements DVFS. Clock frequency and SoC voltage are correlated, if you can determine all clocks are running below a maximum then it should be safe to lower the voltage. Currently, firmware actively monitors arm, core, h264, v3d, isp and hevc to determine what voltage can be reduced to, and if arm increases any of those clocks behind the firmware's back, when it has a lowered voltage, a crash is highly likely. As pointed out to me by RPi foundation engineers hsm/pixel aren't currently being monitored, as driving a high resolution display also requires a high core clock, which already sets an acceptable min voltage threshold. But that might change if needed. Ultimately, from the DVFS, the safe way to change clocks from arm would be to always use the firmware interface, which we're far from doing right now. On the other hand, AFAIK not all clocks have a firmware counterpart. Note that we could also have a word with the RPi foundation and see if disabling DVFS is possible (AFAIK it's not an option right now). Although I personally prefer to support this upstream, aside from the obvious benefits to battery powered use cases, not consuming power unnecessarily is always big plus. > In order to make Linux play as nice as possible with those constraints, it > makes sense to rely on the firmware clocks as much as possible. As I comment above, not as simple as it seems. I suggest, for now, we only register the clocks we're going to use and that are likely to be affected by DVFS. hsm being a contender here. As we'd be settling on a hybrid solution here, which isn't ideal to say the least, I'd like to gather some opinions on whether pushing towards a fully firmware based solution is something you'd like to see. > Fortunately,t he firmware has an interface to discover the clocks it > exposes. nit: wrongly placed space > Let's use it to discover, register the clocks in the clocks framework and > then expose them through the device tree for consumers to use them. > > Cc: Michael Turquette > Cc: Stephen Boyd > Cc: linux-...@vger.kernel.org > Signed-off-by: Maxime Ripard > --- > drivers/clk/bcm/clk-raspberrypi.c | 104 +++--- [...] > +static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, > +unsigned int parent, > +unsigned int id) > +{ > + struct raspberrypi_clk_data *data; > + struct clk_init_data init = {}; > + int ret; > + > + if (id == RPI_FIRMWARE_ARM_CLK_ID) { > + struct clk_hw *hw; > + > + hw = raspberrypi_register_pllb(rpi); > + if (IS_ERR(hw)) { > + dev_err(rpi->dev, "Failed to initialize pllb, %ld\n", > + PTR_ERR(hw)); > + return hw; > + } > + > + return raspberrypi_register_pllb_arm(rpi); > + } We shouldn't create a special case for pllb. My suggestion here is that we revert the commit that removed pllb from the mmio driver, in order to maintain a nice view of the clock tree, and register this as a regular fw-clk. The only user to this is RPi's the cpufreq driver, which shouldn't mind the change as long as you maintain the clk lookup creation. On that topic, now that the clocks are available in DT we could even move raspberrypi-cpufreq's registration there. But that's out of the scope of this series. > + > + data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return ERR_PTR(-ENOMEM); > + data->rpi = rpi; > + data->id = id; > + > + init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id); I'd really like more descriptive names here, sadly the firmware interface doesn't provide them, but they are set in stone nonetheless. Something like 'fw-clk-arm' and 'fw-clk-hsm' comes to mind (SCMI does provide naming BTW). See here for a list of all clocks: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#clocks > + init.ops = _firmware_clk_ops; > + init.flags = CLK_GET_RATE_NOCACHE; > + > + data->hw.init = > + > + ret = devm_clk_hw_register(rpi->dev, >hw); > + if (ret) > + return ERR_PTR(ret); > + > + return >hw; > +} > + > +static int raspberrypi_discover_clocks(struct raspberrypi_clk
[v2 PATCH 0/2] Add support for ASUS Z00T TM5P5 NT35596 panel
changes since v1: - make `backlight_properties props` constant - a couple of line breaks - change name and compatible to reflect ASUS being the vendor - remove a redundant TODO Konrad Dybcio (2): drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver dt-bindings: display: Document ASUS Z00T TM5P5 NT35596 panel compatible .../display/panel/asus,z00t-tm5p5-n35596.yaml | 56 +++ drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-asus-z00t-tm5p5-n35596.c | 367 ++ 4 files changed, 434 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-n35596.yaml create mode 100644 drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c -- 2.26.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] nand: brcmnand: improve hamming oob layout
The current code generates 8 oob sections: S1 1-5 ECC 6-8 S2 9-15 S3 16-21 ECC 22-24 S4 25-31 S5 32-37 ECC 38-40 S6 41-47 S7 48-53 ECC 54-56 S8 57-63 Change it by merging continuous sections: S1 1-5 ECC 6-8 S2 9-21 ECC 22-24 S3 25-37 ECC 38-40 S4 41-53 ECC 54-56 S5 57-63 Signed-off-by: Álvaro Fernández Rojas --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +--- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index e4e3ceeac38f..1bba309c7684 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1100,29 +1100,21 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, struct brcmnand_cfg *cfg = >hwcfg; int sas = cfg->spare_area_size << cfg->sector_size_1k; int sectors = cfg->page_size / (512 << cfg->sector_size_1k); + u32 next; - if (section >= sectors * 2) + if (section > sectors) return -ERANGE; - oobregion->offset = (section / 2) * sas; + next = (section * sas); + if (section < sectors) + next += 6; - if (section & 1) { - oobregion->offset += 9; - oobregion->length = 7; - } else { - oobregion->length = 6; + if (section) + oobregion->offset = ((section - 1) * sas) + 9; + else + oobregion->offset = 1; /* BBI */ - /* First sector of each page may have BBI */ - if (!section) { - /* -* Small-page NAND use byte 6 for BBI while large-page -* NAND use byte 0. -*/ - if (cfg->page_size > 512) - oobregion->offset++; - oobregion->length--; - } - } + oobregion->length = next - oobregion->offset; return 0; } -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/zte: remove unneeded semicolon
Fix the following coccicheck warning: drivers/gpu/drm/zte/zx_vga.c:158:2-3: Unneeded semicolon drivers/gpu/drm/zte/zx_vga.c:171:2-3: Unneeded semicolon drivers/gpu/drm/zte/zx_vga.c:179:2-3: Unneeded semicolon Signed-off-by: Jason Yan --- drivers/gpu/drm/zte/zx_vga.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c index a7ed7f5ca837..0f9bbb7e3b8d 100644 --- a/drivers/gpu/drm/zte/zx_vga.c +++ b/drivers/gpu/drm/zte/zx_vga.c @@ -155,7 +155,7 @@ static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga) if (ret) { DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret); return ret; - }; + } drm_encoder_helper_add(encoder, _vga_encoder_helper_funcs); @@ -168,7 +168,7 @@ static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga) if (ret) { DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret); goto clean_encoder; - }; + } drm_connector_helper_add(connector, _vga_connector_helper_funcs); @@ -176,7 +176,7 @@ static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga) if (ret) { DRM_DEV_ERROR(dev, "failed to attach encoder: %d\n", ret); goto clean_connector; - }; + } return 0; -- 2.21.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: ti-sn65dsi86: Fix off-by-one error in clock choice
Quoting Douglas Anderson (2020-05-04 21:32:29) > If the rate in our table is _equal_ to the rate we want then it's OK > to pick it. It doesn't need to be greater than the one we want. > > Fixes: a095f15c00e2 ("drm/bridge: add support for sn65dsi86 bridge driver") > Signed-off-by: Douglas Anderson > --- Reviewed-by: Stephen Boyd ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] sun6i: dsi: fix gcc-4.8
On Tue, Apr 28, 2020 at 11:50:51PM +0200, Arnd Bergmann wrote: > Older compilers warn about initializers with incorrect curly > braces: > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c: In function > 'sun6i_dsi_encoder_enable': > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:8: error: missing braces around > initializer [-Werror=missing-braces] > union phy_configure_opts opts = { 0 }; > ^ > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:8: error: (near initialization for > 'opts.mipi_dphy') [-Werror=missing-braces] > > Use the GNU empty initializer extension to avoid this. > > Fixes: bb3b6fcb6849 ("sun6i: dsi: Convert to generic phy handling") > Signed-off-by: Arnd Bergmann Applied, thanks! Maxime signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/vc4: make vc4_queue_seqno_cb() return void
No one uses the return value of this function, so make it return void. This fixes the following coccicheck warning: drivers/gpu/drm/vc4/vc4_gem.c:1029:5-8: Unneeded variable: "ret". Return "0" on line 1044 Signed-off-by: Jason Yan --- drivers/gpu/drm/vc4/vc4_drv.h | 6 +++--- drivers/gpu/drm/vc4/vc4_gem.c | 9 +++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 3b1f02efefbe..990b15b82e24 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -810,9 +810,9 @@ void vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec); int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, bool interruptible); void vc4_job_handle_completed(struct vc4_dev *vc4); -int vc4_queue_seqno_cb(struct drm_device *dev, - struct vc4_seqno_cb *cb, uint64_t seqno, - void (*func)(struct vc4_seqno_cb *cb)); +void vc4_queue_seqno_cb(struct drm_device *dev, + struct vc4_seqno_cb *cb, uint64_t seqno, + void (*func)(struct vc4_seqno_cb *cb)); int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index e1cfc3ccd05a..fbcb4fa4e80a 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -1021,12 +1021,11 @@ static void vc4_seqno_cb_work(struct work_struct *work) cb->func(cb); } -int vc4_queue_seqno_cb(struct drm_device *dev, - struct vc4_seqno_cb *cb, uint64_t seqno, - void (*func)(struct vc4_seqno_cb *cb)) +void vc4_queue_seqno_cb(struct drm_device *dev, + struct vc4_seqno_cb *cb, uint64_t seqno, + void (*func)(struct vc4_seqno_cb *cb)) { struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret = 0; unsigned long irqflags; cb->func = func; @@ -1040,8 +1039,6 @@ int vc4_queue_seqno_cb(struct drm_device *dev, schedule_work(>work); } spin_unlock_irqrestore(>job_lock, irqflags); - - return ret; } /* Scheduled when any job has been completed, this walks the list of -- 2.21.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] drm/mediatek: mtk_dpi: Use simple encoder
The mtk_dpi driver uses an empty implementation for its encoder. Replace the code with the generic simple encoder. Signed-off-by: Enric Balletbo i Serra --- drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index baad198c69eb..80778b2aac2a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "mtk_dpi_regs.h" #include "mtk_drm_ddp_comp.h" @@ -510,15 +511,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, return 0; } -static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { - .destroy = mtk_dpi_encoder_destroy, -}; - static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -591,8 +583,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) return ret; } - ret = drm_encoder_init(drm_dev, >encoder, _dpi_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); + ret = drm_simple_encoder_init(drm_dev, >encoder, + DRM_MODE_ENCODER_TMDS); if (ret) { dev_err(dev, "Failed to initialize decoder: %d\n", ret); goto err_unregister; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [v2 PATCH 1/2] drivers: drm: panel: Add ASUS TM5P5 NT35596 panel driver
I just sent out a v3. Hope it solves the issue. Konrad ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/nouveau/mmu: remove unneeded semicolon
Fix the following coccicheck warning: drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h:307:2-3: Unneeded semicolon drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c:583:2-3: Unneeded semicolon Signed-off-by: Jason Yan --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 41640e0584ac..199f94e15c5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -580,7 +580,7 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, it.pte[it.lvl]++; } } - }; + } nvkm_vmm_flush(); return ~0ULL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 5e55ecbd8005..d3f8f916d0db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -304,7 +304,7 @@ int tu102_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, FILL(VMM, PT, PTEI, _ptes, MAP, _addr);\ PTEI += _ptes; \ PTEN -= _ptes; \ - }; \ + } \ nvkm_done((PT)->memory); \ } while(0) -- 2.21.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/i915/gem: Fix inconsistent IS_ERR and PTR_ERR
… > The proper pointer to be passed as argument is ce. > > This bug was detected with the help of Coccinelle. My software development attention was caught also by your commit message. … > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c > @@ -1325,7 +1325,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, > > ce = intel_context_create(engine); > if (IS_ERR(ce)) { > - err = PTR_ERR(rq); > + err = PTR_ERR(ce); > goto err_unpin; > } > Are you looking for any more questionable identifier (or expression) combinations also at other places by the means of advanced source code analysis? Regards, Markus ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/2] nand: brcmnand: fix hamming oob layout
First 2 bytes are used in large-page nand. Signed-off-by: Álvaro Fernández Rojas --- v2: extend original comment drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 767343e0e6e7..0a1d76fde37b 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1114,10 +1114,10 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, } else { /* * Small-page NAND use byte 6 for BBI while large-page -* NAND use byte 0. +* NAND use bytes 0 and 1. */ if (cfg->page_size > 512) { - oobregion->offset = 1; + oobregion->offset = 2; } else { oobregion->offset = 0; next--; -- 2.26.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 0/3] drm: Add support for Chrontel CH7033 VGA/DVI Encoder
On 24/04/2020 23:35, Lubomir Rintel wrote: > Hi, > > chained to this message is another spin of a driver for CH7033. > > Compared to the previous submission, the integration with device > component framework and creation of an encoder on component bind has > been removed. This means that until the Armada driver won't work with > this driver until it's adjusted to look up the bridges like the other > drivers do. > > Thanks, > Lubo > > Applying to drm-misc-next Thanks for your work. Neil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/2] drm/client: Dual licence the header in GPL-2 and MIT
On Thu, Apr 30, 2020 at 05:33:46PM +0200, Emmanuel Vadot wrote: > Source file was dual licenced but the header was omitted, fix that. > Contributors for this file are: > Daniel Vetter > Matt Roper > Maxime Ripard > Noralf Trønnes > Thomas Zimmermann > > Acked-by: Noralf Trønnes > Acked-by: Matt Roper > Acked-by: Daniel Vetter > Acked-by: Maxime Ripard > Acked-by: Thomas Zimmermann > Signed-off-by: Emmanuel Vadot Looks like we have them all, applied. -Daniel > --- > include/drm/drm_client.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h > index 7402f852d3c4..eb259c2547af 100644 > --- a/include/drm/drm_client.h > +++ b/include/drm/drm_client.h > @@ -1,4 +1,4 @@ > -/* SPDX-License-Identifier: GPL-2.0 */ > +/* SPDX-License-Identifier: GPL-2.0 or MIT */ > > #ifndef _DRM_CLIENT_H_ > #define _DRM_CLIENT_H_ > -- > 2.25.1 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 18/25] drm: rcar-du: fix common struct sg_table related issues
Hi Marek, On Tue, May 5, 2020 at 10:48 AM Marek Szyprowski wrote: > The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the > numer of the created entries in the DMA address space. However the > subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be > called with the original number of the entries passed to dma_map_sg. The > sg_table->nents in turn holds the result of the dma_map_sg call as stated > in include/linux/scatterlist.h. A common mistake was to ignore a result > of the dma_map_sg function and don't use the sg_table->orig_nents at all. > > To avoid such issues, lets use common dma-mapping wrappers operating > directly on the struct sg_table objects and adjust references to the > nents and orig_nents respectively. > > Signed-off-by: Marek Szyprowski > --- > For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents > vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 For the modern lore-users: https://lore.kernel.org/r/20200505083926.28503-1-m.szyprow...@samsung.com/ Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: ti-sn65dsi86: Implement lane reordering + polarity
Hi Douglas, Thank you for the patch. On Mon, May 04, 2020 at 09:36:31PM -0700, Douglas Anderson wrote: > The ti-sn65dsi86 MIPI DSI to eDP bridge chip supports arbitrary > remapping of eDP lanes and also polarity inversion. Both of these > features have been described in the device tree bindings for the > device since the beginning but were never implemented in the driver. > Implement both of them. > > Part of this change also allows you to (via the same device tree > bindings) specify to use fewer than the max number of DP lanes that > the panel reports. This could be useful if your display supports more > lanes but only a few are hooked up on your board. > > Signed-off-by: Douglas Anderson > --- > This patch is based upon my my outstanding series[1] not because there > is any real requirement but simply to avoid merge conflicts. I > believe that my previous series is ready to land. If, however, you'd > prefer that I rebase this patch somewhere atop something else then > please shout. > > [1] https://lore.kernel.org/r/20200430194617.197510-1-diand...@chromium.org > > drivers/gpu/drm/bridge/ti-sn65dsi86.c | 75 ++- > 1 file changed, 62 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > index 1a125423eb07..52cca54b525f 100644 > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > @@ -50,8 +50,12 @@ > #define SN_CHA_VERTICAL_BACK_PORCH_REG 0x36 > #define SN_CHA_HORIZONTAL_FRONT_PORCH_REG0x38 > #define SN_CHA_VERTICAL_FRONT_PORCH_REG 0x3A > +#define SN_LN_ASSIGN_REG 0x59 > +#define LN_ASSIGN_WIDTH 2 > #define SN_ENH_FRAME_REG 0x5A > #define VSTREAM_ENABLE BIT(3) > +#define LN_POLRS_OFFSET 4 > +#define LN_POLRS_MASK 0xf0 > #define SN_DATA_FORMAT_REG 0x5B > #define BPP_18_RGB BIT(0) > #define SN_HPD_DISABLE_REG 0x5C > @@ -98,6 +102,7 @@ > > #define SN_REGULATOR_SUPPLY_NUM 4 > > +#define SN_MAX_DP_LANES 4 > #define SN_NUM_GPIOS 4 > > /** > @@ -115,6 +120,8 @@ > * @enable_gpio: The GPIO we toggle to enable the bridge. > * @supplies: Data for bulk enabling/disabling our regulators. > * @dp_lanes: Count of dp_lanes we're using. > + * @ln_assign:Value to program to the LN_ASSIGN register. > + * @ln_polr: Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG. > * > * @gchip:If we expose our GPIOs, this is used. > * @gchip_output: A cache of whether we've set GPIOs to output. This > @@ -140,6 +147,8 @@ struct ti_sn_bridge { > struct gpio_desc*enable_gpio; > struct regulator_bulk_data supplies[SN_REGULATOR_SUPPLY_NUM]; > int dp_lanes; > + u8 ln_assign; > + u8 ln_polrs; > > struct gpio_chipgchip; > DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS); > @@ -707,26 +716,20 @@ static void ti_sn_bridge_enable(struct drm_bridge > *bridge) > int dp_rate_idx; > unsigned int val; > int ret = -EINVAL; > + int max_dp_lanes; > > - /* > - * Run with the maximum number of lanes that the DP sink supports. > - * > - * Depending use cases, we might want to revisit this later because: > - * - It's plausible that someone may have run fewer lines to the > - * sink than the sink actually supports, assuming that the lines > - * will just be driven at a higher rate. > - * - The DP spec seems to indicate that it's more important to minimize > - * the number of lanes than the link rate. > - * > - * If we do revisit, it would be important to measure the power impact. > - */ > - pdata->dp_lanes = ti_sn_get_max_lanes(pdata); > + max_dp_lanes = ti_sn_get_max_lanes(pdata); > + pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes); > > /* DSI_A lane config */ > val = CHA_DSI_LANES(4 - pdata->dsi->lanes); > regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, > CHA_DSI_LANES_MASK, val); > > + regmap_write(pdata->regmap, SN_LN_ASSIGN_REG, pdata->ln_assign); > + regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, LN_POLRS_MASK, > +pdata->ln_polrs << LN_POLRS_OFFSET); > + > /* set dsi clk frequency value */ > ti_sn_bridge_set_dsi_rate(pdata); > > @@ -1063,6 +1066,50 @@ static int ti_sn_setup_gpio_controller(struct > ti_sn_bridge *pdata) > return ret; > } > > +static void ti_sn_bridge_parse_lanes(struct ti_sn_bridge *pdata, > + struct device_node *np) > +{ > + u32
Re: [PATCH] drm/msm: fix link error without CONFIG_DEBUG_FS
On Wed, Apr 8, 2020 at 9:15 PM Arnd Bergmann wrote: > I ran into a randconfig link error with debugfs disabled: > > arm-linux-gnueabi-ld: > drivers/gpu/drm/msm/msm_gpu.o: in function `should_dump': > msm_gpu.c:(.text+0x1cc): undefined reference to `rd_full' > > Change the helper to only look at this variable if debugfs is present. > > Fixes: e515af8d4a6f ("drm/msm: devcoredump should dump MSM_SUBMIT_BO_DUMP > buffers") > Signed-off-by: Arnd Bergmann This fixes a compilation error for me on the APQ8060. Tested-by: Linus Walleij Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse
Dear All, During the Exynos DRM GEM rework and fixing the issues in the drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most drivers in DRM framework incorrectly use nents and orig_nents entries of the struct sg_table. In case of the most DMA-mapping implementations exchanging those two entries or using nents for all loops on the scatterlist is harmless, because they both have the same value. There exists however a DMA-mapping implementations, for which such incorrect usage breaks things. The nents returned by dma_map_sg() might be lower than the nents passed as its parameter and this is perfectly fine. DMA framework or IOMMU is allowed to join consecutive chunks while mapping if such operation is supported by the underlying HW (bus, bridge, IOMMU, etc). Example of the case where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages is described here [2] The DMA-mapping framework documentation [3] states that dma_map_sg() returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of entries passed to dma_map_sg. The common pattern in DRM drivers were to assign the dma_map_sg() return value to sg_table->nents and use that value for the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also the code iterated over nents times to access the pages stored in the processed scatterlist, while it should use orig_nents as the numer of the page entries. I've tried to identify all such incorrect usage of sg_table->nents and this is a result of my research. It looks that the incorrect pattern has been copied over the many drivers mainly in the DRM subsystem. Too bad in most cases it even worked correctly if the system used simple, linear DMA-mapping implementation, for which swapping nents and orig_nents doesn't make any difference. To avoid similar issues in the future, I've introduced a common dma-mapping wrappers, which operate directly on the sg_table objects. The biggest TODO is DRM/i915 driver and I don't feel brave enough to fix it fully. The driver creatively uses sg_table->orig_nents to store the size of the allocate scatterlist and ignores the number of the entries returned by dma_map_sg function. In this patchset I only fixed the sg_table objects exported by dmabuf related functions. I hope that I didn't break anything there. Patches are based on top of Linux next-20200504. Best regards, Marek Szyprowski References: [1] https://lkml.org/lkml/2020/3/27/555 [2] https://lkml.org/lkml/2020/3/29/65 [3] Documentation/DMA-API-HOWTO.txt Changelog: v3: - introduce dma_*_sgtable_* wrappers and use them in all patches v2: https://lore.kernel.org/linux-iommu/c01c9766-9778-fd1f-f36e-2dc7bd376...@arm.com/T/ - dropped most of the changes to drm/i915 - added fixes for rcar-du, xen, media and ion - fixed a few issues pointed by kbuild test robot - added wide cc: list for each patch v1: https://lore.kernel.org/linux-iommu/c01c9766-9778-fd1f-f36e-2dc7bd376...@arm.com/T/ - initial version Patch summary: Marek Szyprowski (25): dma-mapping: add generic helpers for mapping sgtable objects drm: core: fix common struct sg_table related issues drm: amdgpu: fix common struct sg_table related issues drm: armada: fix common struct sg_table related issues drm: etnaviv: fix common struct sg_table related issues drm: exynos: fix common struct sg_table related issues drm: i915: fix common struct sg_table related issues drm: lima: fix common struct sg_table related issues drm: msm: fix common struct sg_table related issues drm: panfrost: fix common struct sg_table related issues drm: radeon: fix common struct sg_table related issues drm: rockchip: fix common struct sg_table related issues drm: tegra: fix common struct sg_table related issues drm: virtio: fix common struct sg_table related issues drm: vmwgfx: fix common struct sg_table related issues xen: gntdev: fix common struct sg_table related issues drm: host1x: fix common struct sg_table related issues drm: rcar-du: fix common struct sg_table related issues dmabuf: fix common struct sg_table related issues staging: ion: fix common struct sg_table related issues staging: tegra-vde: fix common struct sg_table related issues misc: fastrpc: fix common struct sg_table related issues rapidio: fix common struct sg_table related issues samples: vfio-mdev/mbochs: fix common struct sg_table related issues media: pci: fix common ALSA DMA-mapping related codes drivers/dma-buf/heaps/heap-helpers.c | 13 +- drivers/dma-buf/udmabuf.c| 7 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 6 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 +++ drivers/gpu/drm/armada/armada_gem.c | 10 drivers/gpu/drm/drm_cache.c | 2 +-
Re: Operating KMS UAPI (Re: RFC: Drm-connector properties managed by another driver / privacy screen support)
Refocusing on where I think we still have a bit a disconnnect. On Mon, May 04, 2020 at 03:22:28PM +0300, Pekka Paalanen wrote: > On Mon, 4 May 2020 13:00:02 +0200 > Daniel Vetter wrote: > > On Mon, May 4, 2020 at 11:49 AM Pekka Paalanen wrote: > > > On Thu, 30 Apr 2020 15:53:23 +0200 > > > Daniel Vetter wrote: > > I guess my point is, this is a lot bigger problem than just the > > default state. This = vt switching that doesn't look horrible and > > doesn't result in artifacts and issues on the new compositor. > > I am interested in getting reliably to the same hardware state as you > used to have before, either after reboots or after vt-switches. The > transition does not have to be guaranteed to be smooth, but at the same > time the restore policy should not exclude the possibility of a > smooth transition. So my point is kinda that if you want both, then the only way to get there to have a very clear set of what's allowed to be left behind be the outgoing compositor. For example: - only primary plane - only untiled - no color transform magic - ... Imo this is a related problem to the save/restore topic, since if one compositor does something the new one doesn't understand (e.g. tiled buffers with modifiers, and new compositor doesn't use getfb2), then it's going to break. Similar, if the old compositor sets a new color transform property that the new compositor doesn't understand, then you get a mess. Blind restore handles the permanent mess issue, but it doesn't handle the smooth transition issue. But both problems are of the "old compositor did something the new compositor doesn't understand", hence why I chuck them into the same bin. And the issue with a blind save/restore, or kernel defaults, or any of the solutions proposed here is that they pretty much guarantee non-smooth transitions, they only solve the permanent damange part of the problem. I think to solve both, we need some kind of proper compositor switching protocol, e.g. using logind: - old compositor transitions to the minimal config as specified somewhere - logind forces all other properties to "defaults", whether that's restoring boot-up defaults or defaults obtained from the kernel or something else is tbd - logind maybe even does a transition if there's multiple version of the protocol, e.g. v2 allows modifiers, v1 only untiled, so it'd need to do a blit to untiled if the new compositor only supports v1 switching protocol - new compositor takes over, and can continue the smooth transition since it's a well-defined starting state with limited feature usage, _and_ everything else is reset to "defaults" I fear that if we only solve the "resets to defaults" issue then we can draw ourselves into a corner for the smooth transition stuff, if e.g. the wrong entity in the above dance forces the reset to defaults. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm/meson: add mode selection limits against specific SoC revisions
On 28/04/2020 11:21, Neil Armstrong wrote: > The Amlogic S805X/Y uses the same die as the S905X, but with more > limited graphics capabilities. > > This adds a soc version detection adding specific limitations on the HDMI > mode selections. > > Here, we limit to HDMI 1.3a max HDMI PHY clock frequency. > > Changes sinces v1: > - Moved frequency check in the vclk code, and also checks DMT modes > > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/meson/meson_drv.c | 29 ++- > drivers/gpu/drm/meson/meson_drv.h | 6 ++ > drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- > drivers/gpu/drm/meson/meson_vclk.c| 16 ++- > drivers/gpu/drm/meson/meson_vclk.h| 3 ++- > 5 files changed, 52 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/meson/meson_drv.c > b/drivers/gpu/drm/meson/meson_drv.c > index 6f29fab79952..621f6de0f076 100644 > --- a/drivers/gpu/drm/meson/meson_drv.c > +++ b/drivers/gpu/drm/meson/meson_drv.c > @@ -11,6 +11,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -183,6 +184,24 @@ static void meson_remove_framebuffers(void) > kfree(ap); > } > > +struct meson_drm_soc_attr { > + struct meson_drm_soc_limits limits; > + const struct soc_device_attribute *attrs; > +}; > + > +static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { > + /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ > + { > + .limits = { > + .max_hdmi_phy_freq = 165, > + }, > + .attrs = (const struct soc_device_attribute []) { > + { .soc_id = "GXL (S805*)", }, > + { /* sentinel */ }, > + } > + }, > +}; > + > static int meson_drv_bind_master(struct device *dev, bool has_components) > { > struct platform_device *pdev = to_platform_device(dev); > @@ -191,7 +210,7 @@ static int meson_drv_bind_master(struct device *dev, bool > has_components) > struct drm_device *drm; > struct resource *res; > void __iomem *regs; > - int ret; > + int ret, i; > > /* Checks if an output connector is available */ > if (!meson_vpu_has_available_connectors(dev)) { > @@ -281,6 +300,14 @@ static int meson_drv_bind_master(struct device *dev, > bool has_components) > if (ret) > goto free_drm; > > + /* Assign limits per soc revision/package */ > + for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) { > + if (soc_device_match(meson_drm_soc_attrs[i].attrs)) { > + priv->limits = _drm_soc_attrs[i].limits; > + break; > + } > + } > + > /* Remove early framebuffers (ie. simplefb) */ > meson_remove_framebuffers(); > > diff --git a/drivers/gpu/drm/meson/meson_drv.h > b/drivers/gpu/drm/meson/meson_drv.h > index 04fdf3826643..5b23704a80d6 100644 > --- a/drivers/gpu/drm/meson/meson_drv.h > +++ b/drivers/gpu/drm/meson/meson_drv.h > @@ -30,6 +30,10 @@ struct meson_drm_match_data { > struct meson_afbcd_ops *afbcd_ops; > }; > > +struct meson_drm_soc_limits { > + unsigned int max_hdmi_phy_freq; > +}; > + > struct meson_drm { > struct device *dev; > enum vpu_compatible compat; > @@ -48,6 +52,8 @@ struct meson_drm { > struct drm_plane *primary_plane; > struct drm_plane *overlay_plane; > > + const struct meson_drm_soc_limits *limits; > + > /* Components Data */ > struct { > bool osd1_enabled; > diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c > b/drivers/gpu/drm/meson/meson_dw_hdmi.c > index e8c94915a4fc..5be963e9db05 100644 > --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c > +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c > @@ -695,7 +695,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, > dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", > __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); > > - return meson_vclk_vic_supported_freq(phy_freq, vclk_freq); > + return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); > } > > /* Encoder */ > diff --git a/drivers/gpu/drm/meson/meson_vclk.c > b/drivers/gpu/drm/meson/meson_vclk.c > index fdf26dac9fa8..0eb86943a358 100644 > --- a/drivers/gpu/drm/meson/meson_vclk.c > +++ b/drivers/gpu/drm/meson/meson_vclk.c > @@ -725,6 +725,13 @@ meson_vclk_dmt_supported_freq(struct meson_drm *priv, > unsigned int freq) > /* In DMT mode, path after PLL is always /10 */ > freq *= 10; > > + /* Check against soc revision/package limits */ > + if (priv->limits) { > + if (priv->limits->max_hdmi_phy_freq && > + freq > priv->limits->max_hdmi_phy_freq) > + return MODE_CLOCK_HIGH; > + } > + > if (meson_hdmi_pll_find_params(priv, freq, , , )) > return MODE_OK; > > @@ -762,7 +769,7 @@ static void
[PATCH v3 09/25] drm: msm: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/msm/msm_gem.c | 13 + drivers/gpu/drm/msm/msm_iommu.c | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 5a6a79f..ab952d6 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -53,11 +53,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj) struct device *dev = msm_obj->base.dev->dev; if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) { - dma_sync_sg_for_device(dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + dma_sync_sgtable_for_device(dev, msm_obj->sgt, + DMA_BIDIRECTIONAL); } else { - dma_map_sg(dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + dma_map_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL); } } @@ -66,11 +65,9 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj) struct device *dev = msm_obj->base.dev->dev; if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) { - dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + dma_sync_sgtable_for_cpu(dev, msm_obj->sgt, DMA_BIDIRECTIONAL); } else { - dma_unmap_sg(dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL); } } diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index ad58cfe..d322b39 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -43,7 +43,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; - ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); + ret = iommu_map_sgtable(iommu->domain, iova, sgt, prot); WARN_ON(!ret); return (ret == len) ? 0 : -EINVAL; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 22/25] misc: fastrpc: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/misc/fastrpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index e3e085e..0a3e02aa 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -518,7 +518,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( table = >sgt; - if (!dma_map_sg(attachment->dev, table->sgl, table->nents, dir)) + if (!dma_map_sgtable(attachment->dev, table, dir)) return ERR_PTR(-ENOMEM); return table; @@ -528,7 +528,7 @@ static void fastrpc_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *table, enum dma_data_direction dir) { - dma_unmap_sg(attach->dev, table->sgl, table->nents, dir); + dma_unmap_sgtable(attach->dev, table, dir); } static void fastrpc_release(struct dma_buf *dmabuf) -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 12/25] drm: rockchip: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 0d18846..9df7d7d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -36,8 +36,8 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) rk_obj->dma_addr = rk_obj->mm.start; - ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl, - rk_obj->sgt->nents, prot); + ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, + prot); if (ret < rk_obj->base.size) { DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", ret, rk_obj->base.size); @@ -98,11 +98,10 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) * TODO: Replace this by drm_clflush_sg() once it can be implemented * without relying on symbols that are not exported. */ - for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i) + for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i) sg_dma_address(s) = sg_phys(s); - dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents, - DMA_TO_DEVICE); + dma_sync_sgtable_for_device(drm->dev, rk_obj->sgt, DMA_TO_DEVICE); return 0; @@ -350,8 +349,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj) if (private->domain) { rockchip_gem_iommu_unmap(rk_obj); } else { - dma_unmap_sg(drm->dev, rk_obj->sgt->sgl, -rk_obj->sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(drm->dev, rk_obj->sgt, + DMA_BIDIRECTIONAL); } drm_prime_gem_destroy(obj, rk_obj->sgt); } else { @@ -493,15 +492,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt, struct sg_table *sg, struct rockchip_gem_object *rk_obj) { - int count = dma_map_sg(drm->dev, sg->sgl, sg->nents, - DMA_BIDIRECTIONAL); - if (!count) - return -EINVAL; + int err = dma_map_sgtable(drm->dev, sg, DMA_BIDIRECTIONAL); + if (err) + return err; - if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) { + if (rockchip_sg_get_contiguous_size(sg, sg->nents) < + attach->dmabuf->size) { DRM_ERROR("failed to map sg_table to contiguous linear address.\n"); - dma_unmap_sg(drm->dev, sg->sgl, sg->nents, -DMA_BIDIRECTIONAL); + dma_unmap_sgtable(drm->dev, sg, DMA_BIDIRECTIONAL); return -EINVAL; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 18/25] drm: rcar-du: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/media/platform/vsp1/vsp1_drm.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index a4a45d6..8a2624b 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -912,8 +912,9 @@ int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt) * skip cache sync. This will need to be revisited when support for * non-coherent buffers will be added to the DU driver. */ - return dma_map_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents, - DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); + return dma_map_sgtable_attrs(vsp1->bus_master, sgt, DMA_TO_DEVICE, +DMA_ATTR_SKIP_CPU_SYNC); + return sgt->nents; } EXPORT_SYMBOL_GPL(vsp1_du_map_sg); @@ -921,8 +922,8 @@ void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); - dma_unmap_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents, - DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable_attrs(vsp1->bus_master, sgt, DMA_TO_DEVICE, + DMA_ATTR_SKIP_CPU_SYNC); } EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 17/25] drm: host1x: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/host1x/job.c | 22 -- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index a10643a..850115e 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -166,11 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); - if (!err) { - err = -ENOMEM; + err = dma_map_sgtable(dev, sgt, dir); + if (err) goto unpin; - } job->unpins[job->num_unpins].dev = dev; job->unpins[job->num_unpins].dir = dir; @@ -217,7 +215,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) } if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { - for_each_sg(sgt->sgl, sg, sgt->nents, j) + for_each_sg(sgt->sgl, sg, sgt->orig_nents, j) gather_size += sg->length; gather_size = iova_align(>iova, gather_size); @@ -229,9 +227,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - err = iommu_map_sg(host->domain, + err = iommu_map_sgtable(host->domain, iova_dma_addr(>iova, alloc), - sgt->sgl, sgt->nents, IOMMU_READ); + sgt, IOMMU_READ); if (err == 0) { __free_iova(>iova, alloc); err = -EINVAL; @@ -241,12 +239,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) job->unpins[job->num_unpins].size = gather_size; phys_addr = iova_dma_addr(>iova, alloc); } else if (sgt) { - err = dma_map_sg(host->dev, sgt->sgl, sgt->nents, -DMA_TO_DEVICE); - if (!err) { - err = -ENOMEM; + err = dma_map_sgtable(host->dev, sgt, DMA_TO_DEVICE); + if (err) goto unpin; - } job->unpins[job->num_unpins].dir = DMA_TO_DEVICE; job->unpins[job->num_unpins].dev = host->dev; @@ -647,8 +642,7 @@ void host1x_job_unpin(struct host1x_job *job) } if (unpin->dev && sgt) - dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents, -unpin->dir); + dma_unmap_sgtable(unpin->dev, sgt, unpin->dir); host1x_bo_unpin(dev, unpin->bo, sgt); host1x_bo_put(unpin->bo); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 08/25] drm: lima: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/lima/lima_gem.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index 5404e0d..fca359d 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -69,8 +69,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) return ret; if (bo->base.sgt) { - dma_unmap_sg(dev, bo->base.sgt->sgl, -bo->base.sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev, bo->base.sgt, DMA_BIDIRECTIONAL); sg_free_table(bo->base.sgt); } else { bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); @@ -80,7 +79,13 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) } } - dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL); + ret = dma_map_sgtable(dev, , DMA_BIDIRECTIONAL); + if (ret) { + sg_free_table(); + kfree(bo->base.sgt); + bo->base.sgt = NULL; + return ret; + } *bo->base.sgt = sgt; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 24/25] samples: vfio-mdev/mbochs: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. While touching this code, also add missing call to dma_unmap_sgtable. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- samples/vfio-mdev/mbochs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 3cc5e59..f2c62e0 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -846,7 +846,7 @@ static struct sg_table *mbochs_map_dmabuf(struct dma_buf_attachment *at, if (sg_alloc_table_from_pages(sg, dmabuf->pages, dmabuf->pagecount, 0, dmabuf->mode.size, GFP_KERNEL) < 0) goto err2; - if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) + if (dma_map_sgtable(at->dev, sg, direction)) goto err3; return sg; @@ -868,6 +868,7 @@ static void mbochs_unmap_dmabuf(struct dma_buf_attachment *at, dev_dbg(dev, "%s: %d\n", __func__, dmabuf->id); + dma_unmap_sgtable(at->dev, sg, direction); sg_free_table(sg); kfree(sg); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 21/25] staging: tegra-vde: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/staging/media/tegra-vde/iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/tegra-vde/iommu.c b/drivers/staging/media/tegra-vde/iommu.c index 6af863d..adf8dc7 100644 --- a/drivers/staging/media/tegra-vde/iommu.c +++ b/drivers/staging/media/tegra-vde/iommu.c @@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde, addr = iova_dma_addr(>iova, iova); - size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents, - IOMMU_READ | IOMMU_WRITE); + size = iommu_map_sgtable(vde->domain, addr, sgt, +IOMMU_READ | IOMMU_WRITE); if (!size) { __free_iova(>iova, iova); return -ENXIO; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 19/25] dmabuf: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/dma-buf/heaps/heap-helpers.c | 13 ++--- drivers/dma-buf/udmabuf.c| 7 +++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c index 9f964ca..be9523a 100644 --- a/drivers/dma-buf/heaps/heap-helpers.c +++ b/drivers/dma-buf/heaps/heap-helpers.c @@ -140,13 +140,12 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heaps_attachment *a = attachment->priv; - struct sg_table *table; - - table = >table; + struct sg_table *table = >table; + int ret; - if (!dma_map_sg(attachment->dev, table->sgl, table->nents, - direction)) - table = ERR_PTR(-ENOMEM); + ret = dma_map_sgtable(attachment->dev, table, direction); + if (ret) + table = ERR_PTR(ret); return table; } @@ -154,7 +153,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *table, enum dma_data_direction direction) { - dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); + dma_unmap_sgtable(attachment->dev, table, direction); } static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index acb26c6..5bcbf7a 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -63,10 +63,9 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, GFP_KERNEL); if (ret < 0) goto err; - if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) { - ret = -EINVAL; + ret = dma_map_sgtable(dev, sg, direction); + if (ret < 0) goto err; - } return sg; err: @@ -78,7 +77,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, static void put_sg_table(struct device *dev, struct sg_table *sg, enum dma_data_direction direction) { - dma_unmap_sg(dev, sg->sgl, sg->nents, direction); + dma_unmap_sgtable(dev, sg, direction); sg_free_table(sg); kfree(sg); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 04/25] drm: armada: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/armada/armada_gem.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 976685f..5b4f48c 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -407,8 +407,8 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, sg_set_page(sg, page, PAGE_SIZE, 0); } - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) { - num = sgt->nents; + if (dma_map_sgtable(attach->dev, sgt, dir)) { + num = count; goto release; } } else if (dobj->page) { @@ -418,7 +418,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0); - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) + if (dma_map_sgtable(attach->dev, sgt, dir)) goto free_table; } else if (dobj->linear) { /* Single contiguous physical region - no struct page */ @@ -449,11 +449,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, int i; if (!dobj->linear) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sgtable(attach->dev, sgt, dir); if (dobj->obj.filp) { struct scatterlist *sg; - for_each_sg(sgt->sgl, sg, sgt->nents, i) + for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) put_page(sg_page(sg)); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 23/25] rapidio: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/rapidio/devices/rio_mport_cdev.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 4029637..df7dba8 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -574,8 +574,7 @@ static void dma_req_free(struct kref *ref) struct mport_cdev_priv *priv = req->priv; unsigned int i; - dma_unmap_sg(req->dmach->device->dev, -req->sgt.sgl, req->sgt.nents, req->dir); + dma_unmap_sgtable(req->dmach->device->dev, req->sgt, req->dir); sg_free_table(>sgt); if (req->page_list) { for (i = 0; i < req->nr_pages; i++) @@ -927,9 +926,8 @@ static int do_dma_request(struct mport_dma_req *req, xfer->offset, xfer->length); } - nents = dma_map_sg(chan->device->dev, - req->sgt.sgl, req->sgt.nents, dir); - if (nents == 0) { + ret = dma_map_sgtable(chan->device->dev, req->sgt, dir); + if (ret) { rmcd_error("Failed to map SG list"); ret = -EFAULT; goto err_pg; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 06/25] drm: exynos: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index fcee33a..6a655d3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -395,8 +395,8 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d, return; out: - dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl, - g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt, + DMA_BIDIRECTIONAL); pages = frame_vector_pages(g2d_userptr->vec); if (!IS_ERR(pages)) { @@ -511,10 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, g2d_userptr->sgt = sgt; - if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents, - DMA_BIDIRECTIONAL)) { + ret = dma_map_sgtable(to_dma_dev(g2d->drm_dev), sgt, DMA_BIDIRECTIONAL); + if (ret) { DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n"); - ret = -ENOMEM; goto err_sg_free_table; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 13/25] drm: tegra: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/tegra/gem.c | 27 ++- drivers/gpu/drm/tegra/plane.c | 15 +-- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 6237681..4554fbb 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo, * the SG table needs to be copied to avoid overwriting any * other potential users of the original SG table. */ - err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents, -GFP_KERNEL); + err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, +obj->sgt->orig_nents, GFP_KERNEL); if (err < 0) goto free; } else { @@ -196,8 +196,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) bo->iova = bo->mm->start; - bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl, - bo->sgt->nents, prot); + bo->size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); if (!bo->size) { dev_err(tegra->drm->dev, "failed to map buffer\n"); err = -ENOMEM; @@ -264,8 +263,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) { if (bo->pages) { - dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, -DMA_FROM_DEVICE); + dma_unmap_sgtable(drm->dev, bo->sgt, DMA_FROM_DEVICE); drm_gem_put_pages(>gem, bo->pages, true, true); sg_free_table(bo->sgt); kfree(bo->sgt); @@ -290,12 +288,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) goto put_pages; } - err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, -DMA_FROM_DEVICE); - if (err == 0) { - err = -EFAULT; + err = dma_map_sgtable(drm->dev, bo->sgt, DMA_FROM_DEVICE); + if (err) goto free_sgt; - } return 0; @@ -571,7 +566,7 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) goto free; } - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) + if (dma_map_sgtable(attach->dev, sgt, dir)) goto free; return sgt; @@ -590,7 +585,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, struct tegra_bo *bo = to_tegra_bo(gem); if (bo->pages) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sgtable(attach->dev, sgt, dir); sg_free_table(sgt); kfree(sgt); @@ -609,8 +604,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf, struct drm_device *drm = gem->dev; if (bo->pages) - dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents, - DMA_FROM_DEVICE); + dma_sync_sgtable_for_cpu(drm->dev, bo->sgt, DMA_FROM_DEVICE); return 0; } @@ -623,8 +617,7 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf, struct drm_device *drm = gem->dev; if (bo->pages) - dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents, - DMA_TO_DEVICE); + dma_sync_sgtable_for_device(drm->dev, bo->sgt, DMA_TO_DEVICE); return 0; } diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 9ccfb56..4b1c2ae6 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -130,12 +130,9 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) } if
[PATCH v3 10/25] drm: panfrost: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/panfrost/panfrost_gem.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_mmu.c | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 17b654e..95d7e80 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -41,8 +41,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) for (i = 0; i < n_sgt; i++) { if (bo->sgts[i].sgl) { - dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl, -bo->sgts[i].nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(pfdev->dev, >sgts[i], + DMA_BIDIRECTIONAL); sg_free_table(>sgts[i]); } } diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index ed28aeb..9926111 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -517,10 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, if (ret) goto err_pages; - if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) { - ret = -EINVAL; + ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL); + if (ret) goto err_map; - } mmu_map_sg(pfdev, bomapping->mmu, addr, IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 14/25] drm: virtio: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/virtio/virtgpu_object.c | 17 - drivers/gpu/drm/virtio/virtgpu_vq.c | 10 -- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 6ccbd01..5fe153c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -72,9 +72,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) if (shmem->pages) { if (shmem->mapped) { - dma_unmap_sg(vgdev->vdev->dev.parent, -shmem->pages->sgl, shmem->mapped, -DMA_TO_DEVICE); + dma_unmap_sgtable(vgdev->vdev->dev.parent, +shmem->pages, DMA_TO_DEVICE); shmem->mapped = 0; } @@ -157,13 +156,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, } if (use_dma_api) { - shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent, - shmem->pages->sgl, - shmem->pages->nents, - DMA_TO_DEVICE); - *nents = shmem->mapped; + ret = dma_map_sgtable(vgdev->vdev->dev.parent, + shmem->pages, DMA_TO_DEVICE); + if (ret) + return ret; + *nents = shmem->mapped = shmem->pages->nents; } else { - *nents = shmem->pages->nents; + *nents = shmem->pages->orig_nents; } *ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry), diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 9e663a5..c329147 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -603,9 +603,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo); if (use_dma_api) - dma_sync_sg_for_device(vgdev->vdev->dev.parent, - shmem->pages->sgl, shmem->pages->nents, - DMA_TO_DEVICE); + dma_sync_sgtable_for_device(vgdev->vdev->dev.parent, + shmem->pages, DMA_TO_DEVICE); cmd_p = virtio_gpu_alloc_cmd(vgdev, , sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); @@ -1019,9 +1018,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo); if (use_dma_api) - dma_sync_sg_for_device(vgdev->vdev->dev.parent, - shmem->pages->sgl, shmem->pages->nents, - DMA_TO_DEVICE); + dma_sync_sgtable_for_device(vgdev->vdev->dev.parent, + shmem->pages, DMA_TO_DEVICE); cmd_p = virtio_gpu_alloc_cmd(vgdev, , sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 03/25] drm: amdgpu: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 +++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 43d8ed7..eca5628 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -307,8 +307,8 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, if (IS_ERR(sgt)) return sgt; - if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC)) + if (dma_map_sgtable_attrs(attach->dev, sgt, dir, + DMA_ATTR_SKIP_CPU_SYNC)) goto error_free; break; @@ -349,7 +349,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach, struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); if (sgt->sgl->page_link) { - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sgtable(attach->dev, sgt, dir); sg_free_table(sgt); kfree(sgt); } else { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index eff1f73..f71f97f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) { struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; - unsigned nents; int r; int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); @@ -1058,9 +1057,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) goto release_sg; /* Map SG to device */ - r = -ENOMEM; - nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); - if (nents == 0) + r = dma_map_sgtable(adev->dev, ttm->sg, direction); + if (r) goto release_sg; /* convert SG to linear array of pages and dma addresses */ @@ -1091,8 +1089,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) return; /* unmap the pages mapped to the device */ - dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); - + dma_unmap_sgtable(adev->dev, ttm->sg, direction); sg_free_table(ttm->sg); #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 07/25] drm: i915: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. This driver creatively uses sg_table->orig_nents to store the size of the allocate scatterlist and ignores the number of the entries returned by dma_map_sg function. The sg_table->orig_nents is (mis)used to properly free the (over)allocated scatterlist. This patch only introduces common dma-mapping wrappers operating directly on the struct sg_table objects to the dmabuf related functions, so the other drivers, which might share buffers with i915 could rely on the properly set nents and orig_nents values. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 13 + drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c | 7 +++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 7db5a79..7e8583e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -48,12 +48,10 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme src = sg_next(src); } - if (!dma_map_sg_attrs(attachment->dev, - st->sgl, st->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC)) { - ret = -ENOMEM; + ret = dma_map_sgtable_attrs(attachment->dev, st, dir, + DMA_ATTR_SKIP_CPU_SYNC); + if (ret) goto err_free_sg; - } return st; @@ -73,9 +71,8 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, { struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); - dma_unmap_sg_attrs(attachment->dev, - sg->sgl, sg->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable_attrs(attachment->dev, sg, dir, + DMA_ATTR_SKIP_CPU_SYNC); sg_free_table(sg); kfree(sg); diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c index debaf7b..756cb76 100644 --- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c @@ -28,10 +28,9 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment, sg = sg_next(sg); } - if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { - err = -ENOMEM; + err = dma_map_sgtable(attachment->dev, st, dir); + if (err) goto err_st; - } return st; @@ -46,7 +45,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *st, enum dma_data_direction dir) { - dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir); + dma_unmap_sgtable(attachment->dev, st, dir); sg_free_table(st); kfree(st); } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 11/25] drm: radeon: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/radeon/radeon_ttm.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 5d50c9e..166f84e 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) { struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); struct radeon_ttm_tt *gtt = (void *)ttm; - unsigned pinned = 0, nents; + unsigned pinned = 0; int r; int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); @@ -521,9 +521,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) if (r) goto release_sg; - r = -ENOMEM; - nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); - if (nents == 0) + r = dma_map_sgtable(rdev->dev, ttm->sg, direction); + if (r) goto release_sg; drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, @@ -554,9 +553,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) return; /* free the sg table and pages again */ - dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); + dma_unmap_sgtable(rdev->dev, ttm->sg, direction); - for_each_sg_page(ttm->sg->sgl, _iter, ttm->sg->nents, 0) { + for_each_sg_page(ttm->sg->sgl, _iter, ttm->sg->orig_nents, 0) { struct page *page = sg_page_iter_page(_iter); if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) set_page_dirty(page); -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 05/25] drm: etnaviv: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index dc9ef30..340026b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -27,7 +27,7 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj) * because display controller, GPU, etc. are not coherent. */ if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK) - dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); + dma_map_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL); } static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj) @@ -51,7 +51,7 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj * discard those writes. */ if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK) - dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL); } /* called with etnaviv_obj->lock held */ @@ -404,9 +404,8 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, } if (etnaviv_obj->flags & ETNA_BO_CACHED) { - dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl, - etnaviv_obj->sgt->nents, - etnaviv_op_to_dma_dir(op)); + dma_sync_sgtable_for_cpu(dev->dev, etnaviv_obj->sgt, +etnaviv_op_to_dma_dir(op)); etnaviv_obj->last_cpu_prep_op = op; } @@ -421,8 +420,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj) if (etnaviv_obj->flags & ETNA_BO_CACHED) { /* fini without a prep is almost certainly a userspace error */ WARN_ON(etnaviv_obj->last_cpu_prep_op == 0); - dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl, - etnaviv_obj->sgt->nents, + dma_sync_sgtable_for_device(dev->dev, etnaviv_obj->sgt, etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op)); etnaviv_obj->last_cpu_prep_op = 0; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 25/25] media: pci: fix common ALSA DMA-mapping related codes
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. Adapt the code to obey those rules. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/media/pci/cx23885/cx23885-alsa.c | 2 +- drivers/media/pci/cx25821/cx25821-alsa.c | 2 +- drivers/media/pci/cx88/cx88-alsa.c | 2 +- drivers/media/pci/saa7134/saa7134-alsa.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index df44ed7..3f366e4 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -129,7 +129,7 @@ static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; } diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 3016164..c40304d 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -193,7 +193,7 @@ static int cx25821_alsa_dma_unmap(struct cx25821_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; } diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 7d7acee..3c6fe6c 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -332,7 +332,7 @@ static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev) if (!buf->sglen) return 0; - dma_unmap_sg(>pci->dev, buf->sglist, buf->sglen, + dma_unmap_sg(>pci->dev, buf->sglist, buf->nr_pages, PCI_DMA_FROMDEVICE); buf->sglen = 0; return 0; diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 544ca57..398c47f 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -313,7 +313,7 @@ static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev) if (!dma->sglen) return 0; - dma_unmap_sg(>pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE); + dma_unmap_sg(>pci->dev, dma->sglist, dma->nr_pages, PCI_DMA_FROMDEVICE); dma->sglen = 0; return 0; } -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 01/25] dma-mapping: add generic helpers for mapping sgtable objects
struct sg_table is a common structure used for describing a memory buffer. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA pages (nents entry). It turned out that it was a common mistake to misuse nents and orig_nents entries, call dma-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg function. To avoid such issues, lets introduce a common wrappers operating directly on the struct sg_table objects, which take care of the proper use of the nents and orig_nents entries. Signed-off-by: Marek Szyprowski --- include/linux/dma-mapping.h | 32 include/linux/iommu.h | 6 ++ 2 files changed, 38 insertions(+) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index b43116a..8364c20d 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -609,6 +609,36 @@ static inline void dma_sync_single_range_for_device(struct device *dev, return dma_sync_single_for_device(dev, addr + offset, size, dir); } +static inline int dma_map_sgtable_attrs(struct device *dev, + struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs) +{ + int n = dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); + + if (n > 0) { + sgt->nents = n; + return 0; + } + return -EINVAL; +} + +static inline void dma_unmap_sgtable_attrs(struct device *dev, + struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs) +{ + dma_unmap_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); +} + +static inline void dma_sync_sgtable_for_cpu(struct device *dev, + struct sg_table *sgt, enum dma_data_direction dir) +{ + dma_sync_sg_for_cpu(dev, sgt->sgl, sgt->orig_nents, dir); +} + +static inline void dma_sync_sgtable_for_device(struct device *dev, + struct sg_table *sgt, enum dma_data_direction dir) +{ + dma_sync_sg_for_device(dev, sgt->sgl, sgt->orig_nents, dir); +} + #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0) #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0) #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0) @@ -617,6 +647,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, #define dma_unmap_page(d, a, s, r) dma_unmap_page_attrs(d, a, s, r, 0) #define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0) #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0) +#define dma_map_sgtable(d, s, r) dma_map_sgtable_attrs(d, s, r, 0) +#define dma_unmap_sgtable(d, s, r) dma_unmap_sgtable_attrs(d, s, r, 0) extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7ef8b0b..5106b65 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -466,6 +466,12 @@ extern size_t iommu_map_sg_atomic(struct iommu_domain *domain, extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); +static inline size_t iommu_map_sgtable(struct iommu_domain *domain, + unsigned long iova, struct sg_table *sgt, int prot) +{ + return iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, prot); +} + extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); extern void generic_iommu_put_resv_regions(struct device *dev, -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 20/25] staging: ion: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/staging/android/ion/ion.c | 25 +++-- drivers/staging/android/ion/ion_heap.c| 6 +++--- drivers/staging/android/ion/ion_system_heap.c | 2 +- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 38b51ea..9274298 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -147,14 +147,14 @@ static struct sg_table *dup_sg_table(struct sg_table *table) if (!new_table) return ERR_PTR(-ENOMEM); - ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); + ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL); if (ret) { kfree(new_table); return ERR_PTR(-ENOMEM); } new_sg = new_table->sgl; - for_each_sg(table->sgl, sg, table->nents, i) { + for_each_sg(table->sgl, sg, table->orig_nents, i) { memcpy(new_sg, sg, sizeof(*sg)); new_sg->dma_address = 0; new_sg = sg_next(new_sg); @@ -224,12 +224,13 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, { struct ion_dma_buf_attachment *a = attachment->priv; struct sg_table *table; + int ret; table = a->table; - if (!dma_map_sg(attachment->dev, table->sgl, table->nents, - direction)) - return ERR_PTR(-ENOMEM); + ret = dma_map_sgtable(attachment->dev, table, direction); + if (ret) + return ERR_PTR(ret); return table; } @@ -238,7 +239,7 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *table, enum dma_data_direction direction) { - dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); + dma_unmap_sgtable(attachment->dev, table, direction); } static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) @@ -296,10 +297,8 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, } mutex_lock(>lock); - list_for_each_entry(a, >attachments, list) { - dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, - direction); - } + list_for_each_entry(a, >attachments, list) + dma_sync_sgtable_for_cpu(a->dev, a->table, direction); unlock: mutex_unlock(>lock); @@ -319,10 +318,8 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, } mutex_lock(>lock); - list_for_each_entry(a, >attachments, list) { - dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, - direction); - } + list_for_each_entry(a, >attachments, list) + dma_sync_sgtable_for_device(a->dev, a->table, direction); mutex_unlock(>lock); return 0; diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 0755b11..f2f7ca7 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -38,7 +38,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap, else pgprot = pgprot_writecombine(PAGE_KERNEL); - for_each_sg(table->sgl, sg, table->nents, i) { + for_each_sg(table->sgl, sg, table->orig_nents, i) { int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; struct page *page = sg_page(sg); @@ -71,7 +71,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, int i; int ret; - for_each_sg(table->sgl, sg, table->nents, i) { + for_each_sg(table->sgl, sg, table->orig_nents, i) { struct page *page = sg_page(sg); unsigned long remainder = vma->vm_end - addr; unsigned long len = sg->length; @@ -142,7 +142,7 @@ int ion_heap_buffer_zero(struct ion_buffer *buffer) else
[PATCH v3 15/25] drm: vmwgfx: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 17 - 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index bf0bc46..e50ae8b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -362,8 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt) { struct device *dev = vmw_tt->dev_priv->dev->dev; - dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents, - DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev, vmw_tt->sgt, DMA_BIDIRECTIONAL); vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents; } @@ -383,16 +382,8 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt) static int vmw_ttm_map_for_dma(struct vmw_ttm_tt *vmw_tt) { struct device *dev = vmw_tt->dev_priv->dev->dev; - int ret; - - ret = dma_map_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents, -DMA_BIDIRECTIONAL); - if (unlikely(ret == 0)) - return -ENOMEM; - vmw_tt->sgt.nents = ret; - - return 0; + return dma_map_sgtable(dev, vmw_tt->sgt, DMA_BIDIRECTIONAL); } /** @@ -449,10 +440,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt) if (unlikely(ret != 0)) goto out_sg_alloc_fail; - if (vsgt->num_pages > vmw_tt->sgt.nents) { + if (vsgt->num_pages > vmw_tt->sgt.orig_nents) { uint64_t over_alloc = sgl_size * (vsgt->num_pages - - vmw_tt->sgt.nents); + vmw_tt->sgt.orig_nents); ttm_mem_global_free(glob, over_alloc); vmw_tt->sg_alloc_size -= over_alloc; -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 02/25] drm: core: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/gpu/drm/drm_cache.c| 2 +- drivers/gpu/drm/drm_gem_shmem_helper.c | 14 +- drivers/gpu/drm/drm_prime.c| 13 +++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 03e01b0..63bd497 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[], struct sg_page_iter sg_iter; mb(); /*CLFLUSH is ordered only by using memory barriers*/ - for_each_sg_page(st->sgl, _iter, st->nents, 0) + for_each_sg_page(st->sgl, _iter, st->orig_nents, 0) drm_clflush_page(sg_page_iter_page(_iter)); mb(); /*Make sure that all cache line entry is flushed*/ diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index df31e57..cfcfc0d 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -117,8 +117,8 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj) kvfree(shmem->pages); } else { if (shmem->sgt) { - dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl, -shmem->sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, + DMA_BIDIRECTIONAL); sg_free_table(shmem->sgt); kfree(shmem->sgt); } @@ -395,8 +395,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj) WARN_ON(!drm_gem_shmem_is_purgeable(shmem)); - dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl, -shmem->sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(obj->dev->dev, shmem->sgt, DMA_BIDIRECTIONAL); sg_free_table(shmem->sgt); kfree(shmem->sgt); shmem->sgt = NULL; @@ -623,12 +622,17 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj) goto err_put_pages; } /* Map the pages for use by the h/w. */ - dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); + ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL); + if (ret) + goto err_free_sgt; shmem->sgt = sgt; return sgt; +err_free_sgt: + sg_free_table(sgt); + kfree(sgt); err_put_pages: drm_gem_shmem_put_pages(shmem); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 282774e..3e7cb02 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -617,6 +617,7 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, { struct drm_gem_object *obj = attach->dmabuf->priv; struct sg_table *sgt; + int ret; if (WARN_ON(dir == DMA_NONE)) return ERR_PTR(-EINVAL); @@ -626,11 +627,12 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, else sgt = obj->dev->driver->gem_prime_get_sg_table(obj); - if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC)) { + ret = dma_map_sgtable_attrs(attach->dev, sgt, dir, + DMA_ATTR_SKIP_CPU_SYNC); + if (ret) { sg_free_table(sgt); kfree(sgt); - sgt = ERR_PTR(-ENOMEM); + sgt = ERR_PTR(ret); } return sgt; @@ -652,8 +654,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, if (!sgt) return; - dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable_attrs(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC); sg_free_table(sgt); kfree(sgt); } @@ -975,7 +976,7 @@ int
[PATCH v3 16/25] xen: gntdev: fix common struct sg_table related issues
The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the numer of the created entries in the DMA address space. However the subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be called with the original number of the entries passed to dma_map_sg. The sg_table->nents in turn holds the result of the dma_map_sg call as stated in include/linux/scatterlist.h. A common mistake was to ignore a result of the dma_map_sg function and don't use the sg_table->orig_nents at all. To avoid such issues, lets use common dma-mapping wrappers operating directly on the struct sg_table objects and adjust references to the nents and orig_nents respectively. Signed-off-by: Marek Szyprowski --- For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187 --- drivers/xen/gntdev-dmabuf.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c index 75d3bb9..4b22785 100644 --- a/drivers/xen/gntdev-dmabuf.c +++ b/drivers/xen/gntdev-dmabuf.c @@ -247,8 +247,7 @@ static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf, if (sgt) { if (gntdev_dmabuf_attach->dir != DMA_NONE) - dma_unmap_sg_attrs(attach->dev, sgt->sgl, - sgt->nents, + dma_unmap_sgtable_attrs(attach->dev, sgt, gntdev_dmabuf_attach->dir, DMA_ATTR_SKIP_CPU_SYNC); sg_free_table(sgt); @@ -288,7 +287,7 @@ static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf, sgt = dmabuf_pages_to_sgt(gntdev_dmabuf->pages, gntdev_dmabuf->nr_pages); if (!IS_ERR(sgt)) { - if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, + if (dma_map_sgtable_attrs(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC)) { sg_free_table(sgt); kfree(sgt); @@ -625,7 +624,7 @@ static struct gntdev_dmabuf *dmabuf_imp_alloc_storage(int count) /* Now convert sgt to array of pages and check for page validity. */ i = 0; - for_each_sg_page(sgt->sgl, _iter, sgt->nents, 0) { + for_each_sg_page(sgt->sgl, _iter, sgt->orig_nents, 0) { struct page *page = sg_page_iter_page(_iter); /* * Check if page is valid: this can happen if we are given -- 1.9.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: Replace drm_modeset_lock/unlock_all with DRM_MODESET_LOCK_ALL_* helpers
On Tue, May 05, 2020 at 07:55:00AM +0200, Michał Orzeł wrote: > > > On 04.05.2020 13:53, Daniel Vetter wrote: > > On Fri, May 01, 2020 at 05:49:33PM +0200, Michał Orzeł wrote: > >> > >> > >> On 30.04.2020 20:30, Daniel Vetter wrote: > >>> On Thu, Apr 30, 2020 at 5:38 PM Sean Paul wrote: > > On Wed, Apr 29, 2020 at 4:57 AM Jani Nikula > wrote: > > > > On Tue, 28 Apr 2020, Michal Orzel wrote: > >> As suggested by the TODO list for the kernel DRM subsystem, replace > >> the deprecated functions that take/drop modeset locks with new helpers. > >> > >> Signed-off-by: Michal Orzel > >> --- > >> drivers/gpu/drm/drm_mode_object.c | 10 ++ > >> 1 file changed, 6 insertions(+), 4 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/drm_mode_object.c > >> b/drivers/gpu/drm/drm_mode_object.c > >> index 35c2719..901b078 100644 > >> --- a/drivers/gpu/drm/drm_mode_object.c > >> +++ b/drivers/gpu/drm/drm_mode_object.c > >> @@ -402,12 +402,13 @@ int drm_mode_obj_get_properties_ioctl(struct > >> drm_device *dev, void *data, > >> { > >> struct drm_mode_obj_get_properties *arg = data; > >> struct drm_mode_object *obj; > >> + struct drm_modeset_acquire_ctx ctx; > >> int ret = 0; > >> > >> if (!drm_core_check_feature(dev, DRIVER_MODESET)) > >> return -EOPNOTSUPP; > >> > >> - drm_modeset_lock_all(dev); > >> + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); > > > > I cry a little every time I look at the DRM_MODESET_LOCK_ALL_BEGIN and > > DRM_MODESET_LOCK_ALL_END macros. :( > > > > Currently only six users... but there are ~60 calls to > > drm_modeset_lock_all{,_ctx} that I presume are to be replaced. I wonder > > if this will come back and haunt us. > > > > What's the alternative? Seems like the options without the macros is > to use incorrect scope or have a bunch of retry/backoff cargo-cult > everywhere (and hope the copy source is done correctly). > >>> > >>> Yeah Sean & me had a bunch of bikesheds and this is the least worst > >>> option we could come up with. You can't make it a function because of > >>> the control flow. You don't want to open code this because it's tricky > >>> to get right, if all you want is to just grab all locks. But it is > >>> magic hidden behind a macro, which occasionally ends up hurting. > >>> -Daniel > >> So what are we doing with this problem? Should we replace at once approx. > >> 60 calls? > > > > I'm confused by your question - dradual conversion is entirely orthogonal > > to what exactly we're converting too. All I added here is that we've > > discussed this at length, and the macro is the best thing we've come up > > with. I still think it's the best compromise. > > > > Flag-day conversion for over 60 calls doesn't work, no matter what. > > -Daniel > > > I agree with that. All I wanted to ask was whether I should add something > additional to this patch or not. Patch looks good and passed CI, so I went ahead and applied it. Thanks, Daniel > > Thanks, > Michal > >> > >> Michal > >>> > Sean > > > BR, > > Jani. > > > > > >> > >> obj = drm_mode_object_find(dev, file_priv, arg->obj_id, > >> arg->obj_type); > >> if (!obj) { > >> @@ -427,7 +428,7 @@ int drm_mode_obj_get_properties_ioctl(struct > >> drm_device *dev, void *data, > >> out_unref: > >> drm_mode_object_put(obj); > >> out: > >> - drm_modeset_unlock_all(dev); > >> + DRM_MODESET_LOCK_ALL_END(ctx, ret); > >> return ret; > >> } > >> > >> @@ -449,12 +450,13 @@ static int set_property_legacy(struct > >> drm_mode_object *obj, > >> { > >> struct drm_device *dev = prop->dev; > >> struct drm_mode_object *ref; > >> + struct drm_modeset_acquire_ctx ctx; > >> int ret = -EINVAL; > >> > >> if (!drm_property_change_valid_get(prop, prop_value, )) > >> return -EINVAL; > >> > >> - drm_modeset_lock_all(dev); > >> + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); > >> switch (obj->type) { > >> case DRM_MODE_OBJECT_CONNECTOR: > >> ret = drm_connector_set_obj_prop(obj, prop, prop_value); > >> @@ -468,7 +470,7 @@ static int set_property_legacy(struct > >> drm_mode_object *obj, > >> break; > >> } > >> drm_property_change_valid_put(prop, ref); > >> - drm_modeset_unlock_all(dev); > >> + DRM_MODESET_LOCK_ALL_END(ctx, ret); > >> > >> return ret; > >> } > > > > -- > > Jani Nikula, Intel Open Source Graphics Center > >>> > >>> > >>> > > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel
[PATCH 1/5] drm/mgag200: Convert struct drm_device to struct mga_device with macro
Mgag200 used dev_private to look up struct mga_device for instances of struct drm_device. Use of dev_private is deprecated, so hide it in the macro to_mga_device(). Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 4 ++-- drivers/gpu/drm/mgag200/mgag200_drv.c| 2 +- drivers/gpu/drm/mgag200/mgag200_drv.h| 1 + drivers/gpu/drm/mgag200/mgag200_i2c.c| 10 +- drivers/gpu/drm/mgag200/mgag200_main.c | 4 ++-- drivers/gpu/drm/mgag200/mgag200_mode.c | 18 +- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index d491edd317ff3..aebc9ce43d551 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -260,7 +260,7 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; - struct mga_device *mdev = (struct mga_device *)dev->dev_private; + struct mga_device *mdev = to_mga_device(dev); struct drm_gem_object *obj; struct drm_gem_vram_object *gbo = NULL; int ret; @@ -307,7 +307,7 @@ int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { - struct mga_device *mdev = (struct mga_device *)crtc->dev->dev_private; + struct mga_device *mdev = to_mga_device(crtc->dev); /* Our origin is at (64,64) */ x += 64; diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 3298b7ef18b03..c2f0e4b40b052 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -120,7 +120,7 @@ int mgag200_driver_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) { - struct mga_device *mdev = dev->dev_private; + struct mga_device *mdev = to_mga_device(dev); unsigned long pg_align; if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 9691252d6233f..632bbb50465c9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -96,6 +96,7 @@ #define to_mga_crtc(x) container_of(x, struct mga_crtc, base) #define to_mga_connector(x) container_of(x, struct mga_connector, base) +#define to_mga_device(x) ((struct mga_device *)(x)->dev_private) struct mga_crtc { struct drm_crtc base; diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 9f4635916d322..09731e614e46d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -61,34 +61,34 @@ static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) static void mga_gpio_setsda(void *data, int state) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = i2c->dev->dev_private; + struct mga_device *mdev = to_mga_device(i2c->dev); mga_i2c_set(mdev, i2c->data, state); } static void mga_gpio_setscl(void *data, int state) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = i2c->dev->dev_private; + struct mga_device *mdev = to_mga_device(i2c->dev); mga_i2c_set(mdev, i2c->clock, state); } static int mga_gpio_getsda(void *data) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = i2c->dev->dev_private; + struct mga_device *mdev = to_mga_device(i2c->dev); return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0; } static int mga_gpio_getscl(void *data) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = i2c->dev->dev_private; + struct mga_device *mdev = to_mga_device(i2c->dev); return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; } struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev) { - struct mga_device *mdev = dev->dev_private; + struct mga_device *mdev = to_mga_device(dev); struct mga_i2c_chan *i2c; int ret; int data, clock; diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index b680cf47cbb94..b705b7776d2fc 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -92,7 +92,7 @@ static int mga_vram_init(struct mga_device *mdev) static int mgag200_device_init(struct drm_device *dev, uint32_t flags) { - struct mga_device *mdev = dev->dev_private; + struct mga_device *mdev = to_mga_device(dev); int ret, option; mdev->flags = mgag200_flags_from_driver_data(flags); @@ -195,7
[PATCH 2/5] drm/mgag200: Integrate init function into load function
Done to simplify initialization code before embedding the DRM device instance in struct mga_device. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_main.c | 67 ++ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index b705b7776d2fc..3830d3f3c9fa2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -89,12 +89,23 @@ static int mga_vram_init(struct mga_device *mdev) return 0; } -static int mgag200_device_init(struct drm_device *dev, - uint32_t flags) +/* + * Functions here will be called by the core once it's bound the driver to + * a PCI device + */ + + +int mgag200_driver_load(struct drm_device *dev, unsigned long flags) { - struct mga_device *mdev = to_mga_device(dev); + struct mga_device *mdev; int ret, option; + mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); + if (mdev == NULL) + return -ENOMEM; + dev->dev_private = (void *)mdev; + mdev->dev = dev; + mdev->flags = mgag200_flags_from_driver_data(flags); mdev->type = mgag200_type_from_driver_data(flags); @@ -110,7 +121,7 @@ static int mgag200_device_init(struct drm_device *dev, if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, mdev->rmmio_size, "mgadrmfb_mmio")) { - DRM_ERROR("can't reserve mmio registers\n"); + drm_err(dev, "can't reserve mmio registers\n"); return -ENOMEM; } @@ -121,8 +132,8 @@ static int mgag200_device_init(struct drm_device *dev, /* stash G200 SE model number for later use */ if (IS_G200_SE(mdev)) { mdev->unique_rev_id = RREG32(0x1e24); - DRM_DEBUG("G200 SE unique revision id is 0x%x\n", - mdev->unique_rev_id); + drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", + mdev->unique_rev_id); } ret = mga_vram_init(mdev); @@ -133,33 +144,9 @@ static int mgag200_device_init(struct drm_device *dev, mdev->bpp_shifts[1] = 1; mdev->bpp_shifts[2] = 0; mdev->bpp_shifts[3] = 2; - return 0; -} -/* - * Functions here will be called by the core once it's bound the driver to - * a PCI device - */ - - -int mgag200_driver_load(struct drm_device *dev, unsigned long flags) -{ - struct mga_device *mdev; - int r; - - mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); - if (mdev == NULL) - return -ENOMEM; - dev->dev_private = (void *)mdev; - mdev->dev = dev; - - r = mgag200_device_init(dev, flags); - if (r) { - dev_err(>pdev->dev, "Fatal error during GPU init: %d\n", r); - return r; - } - r = mgag200_mm_init(mdev); - if (r) + ret = mgag200_mm_init(mdev); + if (ret) goto err_mm; drm_mode_config_init(dev); @@ -170,16 +157,15 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) dev->mode_config.preferred_depth = 32; dev->mode_config.prefer_shadow = 1; - r = mgag200_modeset_init(mdev); - if (r) { - dev_err(>pdev->dev, "Fatal error during modeset init: %d\n", r); + ret = mgag200_modeset_init(mdev); + if (ret) { + drm_err(dev, "Fatal error during modeset init: %d\n", ret); goto err_modeset; } - r = mgag200_cursor_init(mdev); - if (r) - dev_warn(>pdev->dev, - "Could not initialize cursors. Not doing hardware cursors.\n"); + ret = mgag200_cursor_init(mdev); + if (ret) + drm_err(dev, "Could not initialize cursors. Not doing hardware cursors.\n"); return 0; @@ -189,8 +175,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) mgag200_mm_fini(mdev); err_mm: dev->dev_private = NULL; - - return r; + return ret; } void mgag200_driver_unload(struct drm_device *dev) -- 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/5] drm/mgag200: Embed DRM device in struct mga_device
After receiving reviews on the conversion of mgag200 to atomic mode setting, I thought it would make sense to embed the DRM device in struct mga_device first. Several comments in the atomic-conversion reviews refer to that. Patches 1 to 3 do some cleanups and preparation work. Patch 4 changes the the init functions to allocate struct mga_device before struct drm_device. Patch 5 does the conversion. I did not switch over struct mga_device to the new managed release code. I found that this justifies another round of cleanup patches, which I did not want to put into this patchset. The patches were tested on mgag200 hardware. Thomas Zimmermann (5): drm/mgag200: Convert struct drm_device to struct mga_device with macro drm/mgag200: Integrate init function into load function drm/mgag200: Remove several references to struct mga_device.dev drm/mgag200: Init and finalize devices in mgag200_device_{init,fini}() drm/mgag200: Embed DRM device instance in struct mga_device drivers/gpu/drm/mgag200/mgag200_cursor.c | 10 +- drivers/gpu/drm/mgag200/mgag200_drv.c| 29 +++--- drivers/gpu/drm/mgag200/mgag200_drv.h| 8 +- drivers/gpu/drm/mgag200/mgag200_i2c.c| 10 +- drivers/gpu/drm/mgag200/mgag200_main.c | 114 +++ drivers/gpu/drm/mgag200/mgag200_mode.c | 35 +++ drivers/gpu/drm/mgag200/mgag200_ttm.c| 4 +- 7 files changed, 101 insertions(+), 109 deletions(-) -- 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/5] drm/mgag200: Init and finalize devices in mgag200_device_{init, fini}()
Device initialization is now done in mgag200_device_init(). Specifically, the function allocates the DRM device and sets up the respective fields in struct mga_device. A call to mgag200_device_fini() finalizes struct mga_device. The old function mgag200_driver_load() and mgag200_driver_unload() were left over from the DRM driver's load callbacks and have now been removed. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.c | 27 ++-- drivers/gpu/drm/mgag200/mgag200_drv.h | 5 ++-- drivers/gpu/drm/mgag200/mgag200_main.c | 34 -- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index c2f0e4b40b052..ad12c1b7c66cc 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -51,6 +51,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist); static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct mga_device *mdev; struct drm_device *dev; int ret; @@ -60,31 +61,28 @@ static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - dev = drm_dev_alloc(, >dev); - if (IS_ERR(dev)) { - ret = PTR_ERR(dev); + mdev = devm_kzalloc(>dev, sizeof(*mdev), GFP_KERNEL); + if (!mdev) { + ret = -ENOMEM; goto err_pci_disable_device; } - dev->pdev = pdev; - pci_set_drvdata(pdev, dev); - - ret = mgag200_driver_load(dev, ent->driver_data); + ret = mgag200_device_init(mdev, , pdev, ent->driver_data); if (ret) - goto err_drm_dev_put; + goto err_pci_disable_device; + + dev = mdev->dev; ret = drm_dev_register(dev, ent->driver_data); if (ret) - goto err_mgag200_driver_unload; + goto err_mgag200_device_fini; drm_fbdev_generic_setup(dev, 0); return 0; -err_mgag200_driver_unload: - mgag200_driver_unload(dev); -err_drm_dev_put: - drm_dev_put(dev); +err_mgag200_device_fini: + mgag200_device_fini(mdev); err_pci_disable_device: pci_disable_device(pdev); return ret; @@ -93,9 +91,10 @@ static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static void mga_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct mga_device *mdev = to_mga_device(dev); drm_dev_unregister(dev); - mgag200_driver_unload(dev); + mgag200_device_fini(mdev); drm_dev_put(dev); } diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 632bbb50465c9..1ce0386669ffa 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -200,8 +200,9 @@ int mgag200_modeset_init(struct mga_device *mdev); void mgag200_modeset_fini(struct mga_device *mdev); /* mgag200_main.c */ -int mgag200_driver_load(struct drm_device *dev, unsigned long flags); -void mgag200_driver_unload(struct drm_device *dev); +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, + struct pci_dev *pdev, unsigned long flags); +void mgag200_device_fini(struct mga_device *mdev); /* mgag200_i2c.c */ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 010b309c01fc4..070ff1f433df2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -11,6 +11,7 @@ #include #include +#include #include #include "mgag200_drv.h" @@ -96,17 +97,21 @@ static int mga_vram_init(struct mga_device *mdev) */ -int mgag200_driver_load(struct drm_device *dev, unsigned long flags) +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, + struct pci_dev *pdev, unsigned long flags) { - struct mga_device *mdev; + struct drm_device *dev = mdev->dev; int ret, option; - mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); - if (mdev == NULL) - return -ENOMEM; + dev = drm_dev_alloc(drv, >dev); + if (IS_ERR(dev)) + return PTR_ERR(dev); dev->dev_private = (void *)mdev; mdev->dev = dev; + dev->pdev = pdev; + pci_set_drvdata(pdev, dev); + mdev->flags = mgag200_flags_from_driver_data(flags); mdev->type = mgag200_type_from_driver_data(flags); @@ -123,12 +128,15 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) if (!devm_request_mem_region(dev->dev, mdev->rmmio_base, mdev->rmmio_size, "mgadrmfb_mmio")) {
[PATCH 5/5] drm/mgag200: Embed DRM device instance in struct mga_device
As it is best practice now, the DRM device instance is now embedded in struct mga_device. All references to dev_private have been removed. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_cursor.c | 6 +++--- drivers/gpu/drm/mgag200/mgag200_drv.c| 2 +- drivers/gpu/drm/mgag200/mgag200_drv.h| 4 ++-- drivers/gpu/drm/mgag200/mgag200_main.c | 16 ++-- drivers/gpu/drm/mgag200/mgag200_mode.c | 4 ++-- drivers/gpu/drm/mgag200/mgag200_ttm.c| 4 ++-- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index aebc9ce43d551..e3c717c0cffc0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -15,7 +15,7 @@ static bool warn_palette = true; static int mgag200_cursor_update(struct mga_device *mdev, void *dst, void *src, unsigned int width, unsigned int height) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; unsigned int i, row, col; uint32_t colour_set[16]; uint32_t *next_space = _set[0]; @@ -119,7 +119,7 @@ static void mgag200_cursor_set_base(struct mga_device *mdev, u64 address) static int mgag200_show_cursor(struct mga_device *mdev, void *src, unsigned int width, unsigned int height) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; struct drm_gem_vram_object *gbo; void *dst; s64 off; @@ -196,7 +196,7 @@ static void mgag200_move_cursor(struct mga_device *mdev, int x, int y) int mgag200_cursor_init(struct mga_device *mdev) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; size_t ncursors = ARRAY_SIZE(mdev->cursor.gbo); size_t size; int ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ad12c1b7c66cc..fc0775694c097 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -71,7 +71,7 @@ static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_pci_disable_device; - dev = mdev->dev; + dev = >base; ret = drm_dev_register(dev, ent->driver_data); if (ret) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 1ce0386669ffa..fb2797d6ff690 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -96,7 +96,7 @@ #define to_mga_crtc(x) container_of(x, struct mga_crtc, base) #define to_mga_connector(x) container_of(x, struct mga_connector, base) -#define to_mga_device(x) ((struct mga_device *)(x)->dev_private) +#define to_mga_device(x) container_of(x, struct mga_device, base) struct mga_crtc { struct drm_crtc base; @@ -153,7 +153,7 @@ enum mga_type { #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) struct mga_device { - struct drm_device *dev; + struct drm_device base; unsigned long flags; resource_size_t rmmio_base; diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 070ff1f433df2..ca3ed463c2d41 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -67,7 +67,7 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem) /* Map the framebuffer from the card and configure the core */ static int mga_vram_init(struct mga_device *mdev) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; void __iomem *mem; /* BAR 0 is VRAM */ @@ -100,14 +100,12 @@ static int mga_vram_init(struct mga_device *mdev) int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, struct pci_dev *pdev, unsigned long flags) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; int ret, option; - dev = drm_dev_alloc(drv, >dev); - if (IS_ERR(dev)) - return PTR_ERR(dev); - dev->dev_private = (void *)mdev; - mdev->dev = dev; + ret = drm_dev_init(dev, drv, >dev); + if (ret) + return ret; dev->pdev = pdev; pci_set_drvdata(pdev, dev); @@ -185,17 +183,15 @@ int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, err_drm_dev_put: drm_dev_put(dev); err_mm: - dev->dev_private = NULL; return ret; } void mgag200_device_fini(struct mga_device *mdev) { - struct drm_device *dev = mdev->dev; + struct drm_device *dev = >base; mgag200_modeset_fini(mdev); drm_mode_config_cleanup(dev); mgag200_cursor_fini(mdev);
[PATCH 3/5] drm/mgag200: Remove several references to struct mga_device.dev
Done in preparation of embedding the DRM device in struct mga_device. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_main.c | 21 +++-- drivers/gpu/drm/mgag200/mgag200_mode.c | 17 + 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 3830d3f3c9fa2..010b309c01fc4 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -66,25 +66,26 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem) /* Map the framebuffer from the card and configure the core */ static int mga_vram_init(struct mga_device *mdev) { + struct drm_device *dev = mdev->dev; void __iomem *mem; /* BAR 0 is VRAM */ - mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0); - mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0); + mdev->mc.vram_base = pci_resource_start(dev->pdev, 0); + mdev->mc.vram_window = pci_resource_len(dev->pdev, 0); - if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window, - "mgadrmfb_vram")) { + if (!devm_request_mem_region(dev->dev, mdev->mc.vram_base, +mdev->mc.vram_window, "mgadrmfb_vram")) { DRM_ERROR("can't reserve VRAM\n"); return -ENXIO; } - mem = pci_iomap(mdev->dev->pdev, 0, 0); + mem = pci_iomap(dev->pdev, 0, 0); if (!mem) return -ENOMEM; mdev->mc.vram_size = mga_probe_vram(mdev, mem); - pci_iounmap(mdev->dev->pdev, mem); + pci_iounmap(dev->pdev, mem); return 0; } @@ -116,11 +117,11 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) mdev->has_sdram = !(option & (1 << 14)); /* BAR 0 is the framebuffer, BAR 1 contains registers */ - mdev->rmmio_base = pci_resource_start(mdev->dev->pdev, 1); - mdev->rmmio_size = pci_resource_len(mdev->dev->pdev, 1); + mdev->rmmio_base = pci_resource_start(dev->pdev, 1); + mdev->rmmio_size = pci_resource_len(dev->pdev, 1); - if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, mdev->rmmio_size, - "mgadrmfb_mmio")) { + if (!devm_request_mem_region(dev->dev, mdev->rmmio_base, +mdev->rmmio_size, "mgadrmfb_mmio")) { drm_err(dev, "can't reserve mmio registers\n"); return -ENOMEM; } diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index fa91869c0db52..aaa73b29b04f0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1433,6 +1433,7 @@ static const struct drm_crtc_helper_funcs mga_helper_funcs = { /* CRTC setup */ static void mga_crtc_init(struct mga_device *mdev) { + struct drm_device *dev = mdev->dev; struct mga_crtc *mga_crtc; mga_crtc = kzalloc(sizeof(struct mga_crtc) + @@ -1442,7 +1443,7 @@ static void mga_crtc_init(struct mga_device *mdev) if (mga_crtc == NULL) return; - drm_crtc_init(mdev->dev, _crtc->base, _crtc_funcs); + drm_crtc_init(dev, _crtc->base, _crtc_funcs); drm_mode_crtc_set_gamma_size(_crtc->base, MGAG200_LUT_SIZE); mdev->mode_info.crtc = mga_crtc; @@ -1617,30 +1618,30 @@ static struct drm_connector *mga_vga_init(struct drm_device *dev) int mgag200_modeset_init(struct mga_device *mdev) { + struct drm_device *dev = mdev->dev; struct drm_encoder *encoder = >encoder; struct drm_connector *connector; int ret; mdev->mode_info.mode_config_initialized = true; - mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH; - mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT; + dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH; + dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT; - mdev->dev->mode_config.fb_base = mdev->mc.vram_base; + dev->mode_config.fb_base = mdev->mc.vram_base; mga_crtc_init(mdev); - ret = drm_simple_encoder_init(mdev->dev, encoder, - DRM_MODE_ENCODER_DAC); + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); if (ret) { - drm_err(mdev->dev, + drm_err(dev, "drm_simple_encoder_init() failed, error %d\n", ret); return ret; } encoder->possible_crtcs = 0x1; - connector = mga_vga_init(mdev->dev); + connector = mga_vga_init(dev); if (!connector) { DRM_ERROR("mga_vga_init failed\n"); return -1; -- 2.26.0 ___ dri-devel mailing list
Re: [PATCH 2/3] drm/mediatek: mtk_dpi: Convert to bridge driver
Hi, Enric: Enric Balletbo i Serra 於 2020年5月4日 週一 下午10:14寫道: > > Convert mtk_dpi to a bridge driver with built-in encoder support for > compatibility with existing component drivers. Reviewed-by: Chun-Kuang Hu > > Signed-off-by: Enric Balletbo i Serra > --- > > drivers/gpu/drm/mediatek/mtk_dpi.c | 66 +++--- > 1 file changed, 34 insertions(+), 32 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index 7112125dc3d1..baad198c69eb 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -61,6 +61,7 @@ enum mtk_dpi_out_color_format { > struct mtk_dpi { > struct mtk_ddp_comp ddp_comp; > struct drm_encoder encoder; > + struct drm_bridge bridge; > struct drm_bridge *next_bridge; > void __iomem *regs; > struct device *dev; > @@ -77,9 +78,9 @@ struct mtk_dpi { > int refcount; > }; > > -static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) > +static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b) > { > - return container_of(e, struct mtk_dpi, encoder); > + return container_of(b, struct mtk_dpi, bridge); > } > > enum mtk_dpi_polarity { > @@ -518,50 +519,44 @@ static const struct drm_encoder_funcs > mtk_dpi_encoder_funcs = { > .destroy = mtk_dpi_encoder_destroy, > }; > > -static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder, > - const struct drm_display_mode *mode, > - struct drm_display_mode *adjusted_mode) > +static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, > +enum drm_bridge_attach_flags flags) > { > - return true; > + struct mtk_dpi *dpi = bridge_to_dpi(bridge); > + > + return drm_bridge_attach(bridge->encoder, dpi->next_bridge, > +>bridge, flags); > } > > -static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder, > -struct drm_display_mode *mode, > -struct drm_display_mode *adjusted_mode) > +static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge, > + const struct drm_display_mode *mode, > + const struct drm_display_mode *adjusted_mode) > { > - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); > + struct mtk_dpi *dpi = bridge_to_dpi(bridge); > > drm_mode_copy(>mode, adjusted_mode); > } > > -static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) > +static void mtk_dpi_bridge_disable(struct drm_bridge *bridge) > { > - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); > + struct mtk_dpi *dpi = bridge_to_dpi(bridge); > > mtk_dpi_power_off(dpi); > } > > -static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) > +static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) > { > - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); > + struct mtk_dpi *dpi = bridge_to_dpi(bridge); > > mtk_dpi_power_on(dpi); > mtk_dpi_set_display_mode(dpi, >mode); > } > > -static int mtk_dpi_atomic_check(struct drm_encoder *encoder, > - struct drm_crtc_state *crtc_state, > - struct drm_connector_state *conn_state) > -{ > - return 0; > -} > - > -static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = { > - .mode_fixup = mtk_dpi_encoder_mode_fixup, > - .mode_set = mtk_dpi_encoder_mode_set, > - .disable = mtk_dpi_encoder_disable, > - .enable = mtk_dpi_encoder_enable, > - .atomic_check = mtk_dpi_atomic_check, > +static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = { > + .attach = mtk_dpi_bridge_attach, > + .mode_set = mtk_dpi_bridge_mode_set, > + .disable = mtk_dpi_bridge_disable, > + .enable = mtk_dpi_bridge_enable, > }; > > static void mtk_dpi_start(struct mtk_ddp_comp *comp) > @@ -602,16 +597,13 @@ static int mtk_dpi_bind(struct device *dev, struct > device *master, void *data) > dev_err(dev, "Failed to initialize decoder: %d\n", ret); > goto err_unregister; > } > - drm_encoder_helper_add(>encoder, _dpi_encoder_helper_funcs); > > /* Currently DPI0 is fixed to be driven by OVL1 */ > dpi->encoder.possible_crtcs = BIT(1); > > - ret = drm_bridge_attach(>encoder, dpi->next_bridge, NULL, 0); > - if (ret) { > - dev_err(dev, "Failed to attach bridge: %d\n", ret); > + ret = drm_bridge_attach(>encoder, >bridge, NULL, 0); > + if (ret) > goto err_cleanup; > - } > > dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; > dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; > @@ -768,8 +760,15 @@ static int mtk_dpi_probe(struct
Re: [PATCH 4/5] drm/mgag200: Init and finalize devices in mgag200_device_{init,fini}()
On Tue, May 05, 2020 at 11:56:48AM +0200, Thomas Zimmermann wrote: > Device initialization is now done in mgag200_device_init(). Specifically, > the function allocates the DRM device and sets up the respective fields > in struct mga_device. > > A call to mgag200_device_fini() finalizes struct mga_device. > > The old function mgag200_driver_load() and mgag200_driver_unload() were > left over from the DRM driver's load callbacks and have now been removed. > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/mgag200/mgag200_drv.c | 27 ++-- > drivers/gpu/drm/mgag200/mgag200_drv.h | 5 ++-- > drivers/gpu/drm/mgag200/mgag200_main.c | 34 -- > 3 files changed, 37 insertions(+), 29 deletions(-) > > diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c > b/drivers/gpu/drm/mgag200/mgag200_drv.c > index c2f0e4b40b052..ad12c1b7c66cc 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_drv.c > +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c > @@ -51,6 +51,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist); > > static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id > *ent) > { > + struct mga_device *mdev; > struct drm_device *dev; > int ret; > > @@ -60,31 +61,28 @@ static int mga_pci_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > if (ret) > return ret; > > - dev = drm_dev_alloc(, >dev); > - if (IS_ERR(dev)) { > - ret = PTR_ERR(dev); > + mdev = devm_kzalloc(>dev, sizeof(*mdev), GFP_KERNEL); > + if (!mdev) { > + ret = -ENOMEM; > goto err_pci_disable_device; > } > > - dev->pdev = pdev; > - pci_set_drvdata(pdev, dev); > - > - ret = mgag200_driver_load(dev, ent->driver_data); > + ret = mgag200_device_init(mdev, , pdev, ent->driver_data); > if (ret) > - goto err_drm_dev_put; > + goto err_pci_disable_device; > + > + dev = mdev->dev; > > ret = drm_dev_register(dev, ent->driver_data); > if (ret) > - goto err_mgag200_driver_unload; > + goto err_mgag200_device_fini; > > drm_fbdev_generic_setup(dev, 0); > > return 0; > > -err_mgag200_driver_unload: > - mgag200_driver_unload(dev); > -err_drm_dev_put: > - drm_dev_put(dev); Moving the drm_dev_put away from here will make the conversion to devm_drm_dev_alloc a bit more tricky I think. I'm not sure whether this is actually better than just directly going to devm_drm_dev_alloc and then cleaning up the fallout, that's at least what I've done in the conversions I've attempted thus far. Either way, this looks correct. Reviewed-by: Daniel Vetter > +err_mgag200_device_fini: > + mgag200_device_fini(mdev); > err_pci_disable_device: > pci_disable_device(pdev); > return ret; > @@ -93,9 +91,10 @@ static int mga_pci_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > static void mga_pci_remove(struct pci_dev *pdev) > { > struct drm_device *dev = pci_get_drvdata(pdev); > + struct mga_device *mdev = to_mga_device(dev); > > drm_dev_unregister(dev); > - mgag200_driver_unload(dev); > + mgag200_device_fini(mdev); > drm_dev_put(dev); > } > > diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h > b/drivers/gpu/drm/mgag200/mgag200_drv.h > index 632bbb50465c9..1ce0386669ffa 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_drv.h > +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h > @@ -200,8 +200,9 @@ int mgag200_modeset_init(struct mga_device *mdev); > void mgag200_modeset_fini(struct mga_device *mdev); > > /* mgag200_main.c */ > -int mgag200_driver_load(struct drm_device *dev, unsigned long flags); > -void mgag200_driver_unload(struct drm_device *dev); > +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, > + struct pci_dev *pdev, unsigned long flags); > +void mgag200_device_fini(struct mga_device *mdev); > > /* mgag200_i2c.c */ > struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); > diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c > b/drivers/gpu/drm/mgag200/mgag200_main.c > index 010b309c01fc4..070ff1f433df2 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_main.c > +++ b/drivers/gpu/drm/mgag200/mgag200_main.c > @@ -11,6 +11,7 @@ > #include > > #include > +#include > #include > > #include "mgag200_drv.h" > @@ -96,17 +97,21 @@ static int mga_vram_init(struct mga_device *mdev) > */ > > > -int mgag200_driver_load(struct drm_device *dev, unsigned long flags) > +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, > + struct pci_dev *pdev, unsigned long flags) > { > - struct mga_device *mdev; > + struct drm_device *dev = mdev->dev; > int ret, option; > > - mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); > - if (mdev == NULL) > -
[PATCH] amdgpu: fix integer overflow on 32-bit architectures
Multiplying 10 by four overruns a 'long' variable, as clang points out: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:4160:53: error: overflow in expression; result is -294967296 with type 'long' [-Werror,-Winteger-overflow] expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4L; ^ Make this a 'long long' constant instead. Fixes: 3f12acc8d6d4 ("drm/amdgpu: put the audio codec into suspend state before gpu reset V3") Signed-off-by: Arnd Bergmann --- I'm not sure the ktime_get_mono_fast_ns() call is necessary here either. Is it intentional because ktime_get_ns() doesn't work during a driver suspend, or just a mistake? --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6f93af972b0a..2e07e3e6b036 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4157,7 +4157,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) * the audio controller default autosuspend delay setting. * 4S used here is guaranteed to cover that. */ - expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4L; + expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4LL; while (!pm_runtime_status_suspended(&(p->dev))) { if (!pm_runtime_suspend(&(p->dev))) -- 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/ast: Don't check new mode if CRTC is being disabled
On Mon, 4 May 2020 at 13:07, Thomas Zimmermann wrote: > > Hi Emil > > Am 01.05.20 um 15:20 schrieb Emil Velikov: > > Hi Thomas, > > > > Couple of fly-by ideas/suggestions. > > > > On Thu, 30 Apr 2020 at 10:13, Thomas Zimmermann wrote: > >> > >> Suspending failed because there's no mode if the CRTC is being > >> disabled. Early-out in this case. This fixes runtime PM for ast. > >> > >> Signed-off-by: Thomas Zimmermann > >> --- > >> drivers/gpu/drm/ast/ast_mode.c | 3 +++ > >> 1 file changed, 3 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/ast/ast_mode.c > >> b/drivers/gpu/drm/ast/ast_mode.c > >> index 7a9f20a2fd303..089b7d9a0cf3f 100644 > >> --- a/drivers/gpu/drm/ast/ast_mode.c > >> +++ b/drivers/gpu/drm/ast/ast_mode.c > >> @@ -801,6 +801,9 @@ static int ast_crtc_helper_atomic_check(struct > >> drm_crtc *crtc, > >> return -EINVAL; > > Unrelated: > > This feels quite dirty. If AST1180 does not support atomic modeset > > simply remove the DRIVER_ATOMIC bit. > > You can do that at runtime, via drm_device::driver_features in say, > > ast_detect_chip()? > > The line you commented on dates back to non-atomic modesetting, but I > don't know what the story behind AST1180 is. It is explicitly disabled > in the list of PCI IDs, but the driver has plenty of code for it. It > looks as if the chip can only do pageflipping with a pre-set video mode. > > As it is right now, the AST1180 code could probably be deleted entirely. > No modeset support at all? Ouch. Removing is one option a shorter/simpler one will be to expose zero connectors. So any crazy^W brave soul can reinstate AST1180 support. In either way - it's something for another day/series. > > > > The drm_driver::driver_features is immutable, or it ought to be. > > > >> } > >> > >> + if (!state->enable) > >> + return 0; /* no checks required if CRTC is being disabled > >> */ > >> + > > I cannot think of a reason why a driver would need to perform > > crtc_atomic_check, if the crtc is being disabled. > > Can you spot any? If not, this should be better served in core, which > > calls this callback. > > Correct? > Ast is a bit of a special case, because it tests the incoming mode > against a list of re-defined modes. With the crtc being disabled, the > incoming mode is 0 in all fields. Obviously that's not a valid mode, and > we need that additional test here. > > In the general case, I'd see 'crtc check' as part of the larger atomic > infrastructure. I can imagine that configurations require the CRTC to be > enabled before other HW blocks work. So a driver might have a reason to > run crtc's check even for disabled crtcs (at least to verify that the > crtc is not disabled). I don't think this can be handled in the core easily. > Ack, makes sense. Thanks Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/amdgpu/dc: don't pass -mhard-float to clang
Clang does not appear to care, and instead prints a warning: clang: warning: argument unused during compilation: '-mhard-float' [-Wunused-command-line-argument] Signed-off-by: Arnd Bergmann --- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 5 +++-- drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 5 +++-- drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 5 +++-- drivers/gpu/drm/amd/display/dc/dml/Makefile | 5 +++-- drivers/gpu/drm/amd/display/dc/dsc/Makefile | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 4674aca8f206..64195cacf6fc 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -26,14 +26,15 @@ # ifdef CONFIG_X86 -calcs_ccflags := -mhard-float -msse +calcs_ccflags := -msse endif ifdef CONFIG_PPC64 -calcs_ccflags := -mhard-float -maltivec +calcs_ccflags := -maltivec endif ifdef CONFIG_CC_IS_GCC +calcs_ccflags += -mhard-float ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index 5fcaf78334ff..0d3ce716c753 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -10,14 +10,15 @@ DCN20 = dcn20_resource.o dcn20_init.o dcn20_hwseq.o dcn20_dpp.o dcn20_dpp_cm.o d DCN20 += dcn20_dsc.o ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -msse endif ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -maltivec endif ifdef CONFIG_CC_IS_GCC +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -mhard-float ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile index 07684d3e375a..fd209d1cf6bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile @@ -6,14 +6,15 @@ DCN21 = dcn21_init.o dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o \ dcn21_hwseq.o dcn21_link_encoder.o ifdef CONFIG_X86 -CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse +CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -msse endif ifdef CONFIG_PPC64 -CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec +CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -maltivec endif ifdef CONFIG_CC_IS_GCC +CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -mhard-float ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 7ee8b8460a9b..fb74e79e15a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -26,14 +26,15 @@ # subcomponents. ifdef CONFIG_X86 -dml_ccflags := -mhard-float -msse +dml_ccflags := -msse endif ifdef CONFIG_PPC64 -dml_ccflags := -mhard-float -maltivec +dml_ccflags := -maltivec endif ifdef CONFIG_CC_IS_GCC +dml_ccflags += -mhard-float ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index 3f66868df171..b0077f5c318d 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -3,14 +3,15 @@ # Makefile for the 'dsc' sub-component of DAL. ifdef CONFIG_X86 -dsc_ccflags := -mhard-float -msse +dsc_ccflags := -msse endif ifdef CONFIG_PPC64 -dsc_ccflags := -mhard-float -maltivec +dsc_ccflags := -maltivec endif ifdef CONFIG_CC_IS_GCC +dsc_ccflags += -mhard-float ifeq ($(call cc-ifversion, -lt, 0701, y), y) IS_OLD_GCC = 1 endif -- 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/5] drm/mgag200: Embed DRM device in struct mga_device
Hi Thomas. On Tue, May 05, 2020 at 11:56:44AM +0200, Thomas Zimmermann wrote: > After receiving reviews on the conversion of mgag200 to atomic mode > setting, I thought it would make sense to embed the DRM device in > struct mga_device first. Several comments in the atomic-conversion > reviews refer to that. I would have preferred that this was on top of at least some of the existing patches, as they are tested by at least one other person and reveiwed too (at least some of them, but maybe only by me). Anyway, now you did it like this and Daniel has reviewed so let's move on from here. Sam > > Patches 1 to 3 do some cleanups and preparation work. Patch 4 changes > the the init functions to allocate struct mga_device before struct > drm_device. Patch 5 does the conversion. > > I did not switch over struct mga_device to the new managed release > code. I found that this justifies another round of cleanup patches, > which I did not want to put into this patchset. > > The patches were tested on mgag200 hardware. > > Thomas Zimmermann (5): > drm/mgag200: Convert struct drm_device to struct mga_device with macro > drm/mgag200: Integrate init function into load function > drm/mgag200: Remove several references to struct mga_device.dev > drm/mgag200: Init and finalize devices in mgag200_device_{init,fini}() > drm/mgag200: Embed DRM device instance in struct mga_device > > drivers/gpu/drm/mgag200/mgag200_cursor.c | 10 +- > drivers/gpu/drm/mgag200/mgag200_drv.c| 29 +++--- > drivers/gpu/drm/mgag200/mgag200_drv.h| 8 +- > drivers/gpu/drm/mgag200/mgag200_i2c.c| 10 +- > drivers/gpu/drm/mgag200/mgag200_main.c | 114 +++ > drivers/gpu/drm/mgag200/mgag200_mode.c | 35 +++ > drivers/gpu/drm/mgag200/mgag200_ttm.c| 4 +- > 7 files changed, 101 insertions(+), 109 deletions(-) > > -- > 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/5] drm/mgag200: Integrate init function into load function
On Tue, May 05, 2020 at 11:56:46AM +0200, Thomas Zimmermann wrote: > Done to simplify initialization code before embedding the DRM device > instance in struct mga_device. And replace DRM_ERROR with drm_err And replace r with ret. I could not follow all the code re-shuffeling, but I expect it to be fine. Acked-by: Sam Ravnborg > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/mgag200/mgag200_main.c | 67 ++ > 1 file changed, 26 insertions(+), 41 deletions(-) > > diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c > b/drivers/gpu/drm/mgag200/mgag200_main.c > index b705b7776d2fc..3830d3f3c9fa2 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_main.c > +++ b/drivers/gpu/drm/mgag200/mgag200_main.c > @@ -89,12 +89,23 @@ static int mga_vram_init(struct mga_device *mdev) > return 0; > } > > -static int mgag200_device_init(struct drm_device *dev, > -uint32_t flags) > +/* > + * Functions here will be called by the core once it's bound the driver to > + * a PCI device > + */ > + > + > +int mgag200_driver_load(struct drm_device *dev, unsigned long flags) > { > - struct mga_device *mdev = to_mga_device(dev); > + struct mga_device *mdev; > int ret, option; > > + mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); > + if (mdev == NULL) > + return -ENOMEM; > + dev->dev_private = (void *)mdev; > + mdev->dev = dev; > + > mdev->flags = mgag200_flags_from_driver_data(flags); > mdev->type = mgag200_type_from_driver_data(flags); > > @@ -110,7 +121,7 @@ static int mgag200_device_init(struct drm_device *dev, > > if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, > mdev->rmmio_size, > "mgadrmfb_mmio")) { > - DRM_ERROR("can't reserve mmio registers\n"); > + drm_err(dev, "can't reserve mmio registers\n"); > return -ENOMEM; > } > > @@ -121,8 +132,8 @@ static int mgag200_device_init(struct drm_device *dev, > /* stash G200 SE model number for later use */ > if (IS_G200_SE(mdev)) { > mdev->unique_rev_id = RREG32(0x1e24); > - DRM_DEBUG("G200 SE unique revision id is 0x%x\n", > - mdev->unique_rev_id); > + drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", > + mdev->unique_rev_id); > } > > ret = mga_vram_init(mdev); > @@ -133,33 +144,9 @@ static int mgag200_device_init(struct drm_device *dev, > mdev->bpp_shifts[1] = 1; > mdev->bpp_shifts[2] = 0; > mdev->bpp_shifts[3] = 2; > - return 0; > -} > > -/* > - * Functions here will be called by the core once it's bound the driver to > - * a PCI device > - */ > - > - > -int mgag200_driver_load(struct drm_device *dev, unsigned long flags) > -{ > - struct mga_device *mdev; > - int r; > - > - mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); > - if (mdev == NULL) > - return -ENOMEM; > - dev->dev_private = (void *)mdev; > - mdev->dev = dev; > - > - r = mgag200_device_init(dev, flags); > - if (r) { > - dev_err(>pdev->dev, "Fatal error during GPU init: %d\n", > r); > - return r; > - } > - r = mgag200_mm_init(mdev); > - if (r) > + ret = mgag200_mm_init(mdev); > + if (ret) > goto err_mm; > > drm_mode_config_init(dev); > @@ -170,16 +157,15 @@ int mgag200_driver_load(struct drm_device *dev, > unsigned long flags) > dev->mode_config.preferred_depth = 32; > dev->mode_config.prefer_shadow = 1; > > - r = mgag200_modeset_init(mdev); > - if (r) { > - dev_err(>pdev->dev, "Fatal error during modeset init: > %d\n", r); > + ret = mgag200_modeset_init(mdev); > + if (ret) { > + drm_err(dev, "Fatal error during modeset init: %d\n", ret); > goto err_modeset; > } > > - r = mgag200_cursor_init(mdev); > - if (r) > - dev_warn(>pdev->dev, > - "Could not initialize cursors. Not doing hardware > cursors.\n"); > + ret = mgag200_cursor_init(mdev); > + if (ret) > + drm_err(dev, "Could not initialize cursors. Not doing hardware > cursors.\n"); > > return 0; > > @@ -189,8 +175,7 @@ int mgag200_driver_load(struct drm_device *dev, unsigned > long flags) > mgag200_mm_fini(mdev); > err_mm: > dev->dev_private = NULL; > - > - return r; > + return ret; > } > > void mgag200_driver_unload(struct drm_device *dev) > -- > 2.26.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: Fix pageflip event race condition for DCN. (v2)
Can you file a full bug report on the gitlab tracker? FreeSync is still working on my Navi setups with this patch applied, and this patch is essentially just a revert of another patch already (where FreeSync worked before). I can understand the v2 of this series causing issues, but the v1 shouldn't be - so I'd like to understand more about the setup where this is causing issues - ASIC, OS, compositor, displays, dmesg log, X log, etc. Regards, Nicholas Kazlauskas On 2020-05-05 1:03 p.m., Alex Deucher wrote: Mario or Nick any thoughts? Alex On Mon, May 4, 2020 at 1:35 PM Matt Coffin wrote: Hey guys, This is still an issue for me, and I'm still having to run a patch to revert this as of 5.7-rc4. To avoid breaking a lot of people's Navi setups in 5.7, is there any news on this? Has anyone else at the very least been able to reproduce the problem? It happens for me in every single program that mesa allows to utilize variable refresh rates, and reverting it "fixes" the issue. Cheers, and sorry for the extra email, just making sure this is still on someone's radar, Matt On 4/14/20 5:32 PM, Matt Coffin wrote: Hey everyone, This patch broke variable refresh rate in games (all that I've tried so far... Project CARS 2, DiRT Rally 2.0, Assetto Corsa Competizione) as well as a simple freesync tester application. FreeSync tester I've been using: https://github.com/Nixola/VRRTest I'm not at all familiar with the page flipping code, so it would take me a long time to find the *right* way to fix it, but does someone else see why it would do that? The symptom is that the refresh rate of the display constantly bounces between the two ends of the FreeSync range (for me 40 -> 144), and the game stutters like a madman. Any help on where to start, ideas on how to fix it (other than just revert this commit, which I've done in the interim), or alternative patches would be appreciated. Thanks in advance for the work/help, Matt On 3/13/20 8:42 AM, Michel Dänzer wrote: On 2020-03-13 1:35 p.m., Kazlauskas, Nicholas wrote: On 2020-03-12 10:32 a.m., Alex Deucher wrote: On Thu, Mar 5, 2020 at 4:21 PM Mario Kleiner wrote: Commit '16f17eda8bad ("drm/amd/display: Send vblank and user events at vsartup for DCN")' introduces a new way of pageflip completion handling for DCN, and some trouble. The current implementation introduces a race condition, which can cause pageflip completion events to be sent out one vblank too early, thereby confusing userspace and causing flicker: prepare_flip_isr(): 1. Pageflip programming takes the ddev->event_lock. 2. Sets acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED 3. Releases ddev->event_lock. --> Deadline for surface address regs double-buffering passes on target pipe. 4. dc_commit_updates_for_stream() MMIO programs the new pageflip into hw, but too late for current vblank. => pflip_status == AMDGPU_FLIP_SUBMITTED, but flip won't complete in current vblank due to missing the double-buffering deadline by a tiny bit. 5. VSTARTUP trigger point in vblank is reached, VSTARTUP irq fires, dm_dcn_crtc_high_irq() gets called. 6. Detects pflip_status == AMDGPU_FLIP_SUBMITTED and assumes the pageflip has been completed/will complete in this vblank and sends out pageflip completion event to userspace and resets pflip_status = AMDGPU_FLIP_NONE. => Flip completion event sent out one vblank too early. This behaviour has been observed during my testing with measurement hardware a couple of time. The commit message says that the extra flip event code was added to dm_dcn_crtc_high_irq() to prevent missing to send out pageflip events in case the pflip irq doesn't fire, because the "DCH HUBP" component is clock gated and doesn't fire pflip irqs in that state. Also that this clock gating may happen if no planes are active. According to Nicholas, the clock gating can also happen if psr is active, and the gating is controlled independently by the hardware, so difficult to detect if and when the completion code in above commit is needed. This patch tries the following solution: It only executes the extra pflip completion code in dm_dcn_crtc_high_irq() iff the hardware reports that there aren't any surface updated pending in the double-buffered surface scanout address registers. Otherwise it leaves pflip completion to the pflip irq handler, for a more race-free experience. This would only guard against the order of events mentioned above. If Step 5 (VSTARTUP trigger) happens before step 4 then this won't help at all, because 1-3 + 5 might happen even without the hw being programmed at all, ie. no surface update pending because none yet programmed into hw. Therefore this patch also changes locking in amdgpu_dm_commit_planes(), so that prepare_flip_isr() and dc_commit_updates_for_stream() are done under event_lock protection within the same critical section. v2: Take Nicholas comments into account, try a different solution. Lightly tested on
Re: [PATCH] drm/bridge: ti-sn65dsi86: Implement lane reordering + polarity
Hi, On Tue, May 5, 2020 at 1:24 AM Laurent Pinchart wrote: > > Hi Douglas, > > Thank you for the patch. > > On Mon, May 04, 2020 at 09:36:31PM -0700, Douglas Anderson wrote: > > The ti-sn65dsi86 MIPI DSI to eDP bridge chip supports arbitrary > > remapping of eDP lanes and also polarity inversion. Both of these > > features have been described in the device tree bindings for the > > device since the beginning but were never implemented in the driver. > > Implement both of them. > > > > Part of this change also allows you to (via the same device tree > > bindings) specify to use fewer than the max number of DP lanes that > > the panel reports. This could be useful if your display supports more > > lanes but only a few are hooked up on your board. > > > > Signed-off-by: Douglas Anderson > > --- > > This patch is based upon my my outstanding series[1] not because there > > is any real requirement but simply to avoid merge conflicts. I > > believe that my previous series is ready to land. If, however, you'd > > prefer that I rebase this patch somewhere atop something else then > > please shout. > > > > [1] https://lore.kernel.org/r/20200430194617.197510-1-diand...@chromium.org > > > > drivers/gpu/drm/bridge/ti-sn65dsi86.c | 75 ++- > > 1 file changed, 62 insertions(+), 13 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > index 1a125423eb07..52cca54b525f 100644 > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > @@ -50,8 +50,12 @@ > > #define SN_CHA_VERTICAL_BACK_PORCH_REG 0x36 > > #define SN_CHA_HORIZONTAL_FRONT_PORCH_REG0x38 > > #define SN_CHA_VERTICAL_FRONT_PORCH_REG 0x3A > > +#define SN_LN_ASSIGN_REG 0x59 > > +#define LN_ASSIGN_WIDTH 2 > > #define SN_ENH_FRAME_REG 0x5A > > #define VSTREAM_ENABLE BIT(3) > > +#define LN_POLRS_OFFSET 4 > > +#define LN_POLRS_MASK 0xf0 > > #define SN_DATA_FORMAT_REG 0x5B > > #define BPP_18_RGB BIT(0) > > #define SN_HPD_DISABLE_REG 0x5C > > @@ -98,6 +102,7 @@ > > > > #define SN_REGULATOR_SUPPLY_NUM 4 > > > > +#define SN_MAX_DP_LANES 4 > > #define SN_NUM_GPIOS 4 > > > > /** > > @@ -115,6 +120,8 @@ > > * @enable_gpio: The GPIO we toggle to enable the bridge. > > * @supplies: Data for bulk enabling/disabling our regulators. > > * @dp_lanes: Count of dp_lanes we're using. > > + * @ln_assign:Value to program to the LN_ASSIGN register. > > + * @ln_polr: Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG. > > * > > * @gchip:If we expose our GPIOs, this is used. > > * @gchip_output: A cache of whether we've set GPIOs to output. This > > @@ -140,6 +147,8 @@ struct ti_sn_bridge { > > struct gpio_desc*enable_gpio; > > struct regulator_bulk_data supplies[SN_REGULATOR_SUPPLY_NUM]; > > int dp_lanes; > > + u8 ln_assign; > > + u8 ln_polrs; > > > > struct gpio_chipgchip; > > DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS); > > @@ -707,26 +716,20 @@ static void ti_sn_bridge_enable(struct drm_bridge > > *bridge) > > int dp_rate_idx; > > unsigned int val; > > int ret = -EINVAL; > > + int max_dp_lanes; > > > > - /* > > - * Run with the maximum number of lanes that the DP sink supports. > > - * > > - * Depending use cases, we might want to revisit this later because: > > - * - It's plausible that someone may have run fewer lines to the > > - * sink than the sink actually supports, assuming that the lines > > - * will just be driven at a higher rate. > > - * - The DP spec seems to indicate that it's more important to > > minimize > > - * the number of lanes than the link rate. > > - * > > - * If we do revisit, it would be important to measure the power > > impact. > > - */ > > - pdata->dp_lanes = ti_sn_get_max_lanes(pdata); > > + max_dp_lanes = ti_sn_get_max_lanes(pdata); > > + pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes); > > > > /* DSI_A lane config */ > > val = CHA_DSI_LANES(4 - pdata->dsi->lanes); > > regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, > > CHA_DSI_LANES_MASK, val); > > > > + regmap_write(pdata->regmap, SN_LN_ASSIGN_REG, pdata->ln_assign); > > + regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, LN_POLRS_MASK, > > +pdata->ln_polrs << LN_POLRS_OFFSET); > > + > > /* set dsi clk frequency value */ > > ti_sn_bridge_set_dsi_rate(pdata); > > > > @@ -1063,6
Re: [PATCH 3/5] drm/mgag200: Remove several references to struct mga_device.dev
Hi Thomas. On Tue, May 05, 2020 at 11:56:47AM +0200, Thomas Zimmermann wrote: > Done in preparation of embedding the DRM device in struct mga_device. > > Signed-off-by: Thomas Zimmermann Trivial, one nit you can fix while applying, or ignore. Reviewed-by: Sam Ravnborg > --- > drivers/gpu/drm/mgag200/mgag200_main.c | 21 +++-- > drivers/gpu/drm/mgag200/mgag200_mode.c | 17 + > 2 files changed, 20 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c > b/drivers/gpu/drm/mgag200/mgag200_main.c > index 3830d3f3c9fa2..010b309c01fc4 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_main.c > +++ b/drivers/gpu/drm/mgag200/mgag200_main.c > @@ -66,25 +66,26 @@ static int mga_probe_vram(struct mga_device *mdev, void > __iomem *mem) > /* Map the framebuffer from the card and configure the core */ > static int mga_vram_init(struct mga_device *mdev) > { > + struct drm_device *dev = mdev->dev; > void __iomem *mem; > > /* BAR 0 is VRAM */ > - mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0); > - mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0); > + mdev->mc.vram_base = pci_resource_start(dev->pdev, 0); > + mdev->mc.vram_window = pci_resource_len(dev->pdev, 0); > > - if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, > mdev->mc.vram_window, > - "mgadrmfb_vram")) { > + if (!devm_request_mem_region(dev->dev, mdev->mc.vram_base, > + mdev->mc.vram_window, "mgadrmfb_vram")) { > DRM_ERROR("can't reserve VRAM\n"); > return -ENXIO; > } > > - mem = pci_iomap(mdev->dev->pdev, 0, 0); > + mem = pci_iomap(dev->pdev, 0, 0); > if (!mem) > return -ENOMEM; > > mdev->mc.vram_size = mga_probe_vram(mdev, mem); > > - pci_iounmap(mdev->dev->pdev, mem); > + pci_iounmap(dev->pdev, mem); > > return 0; > } > @@ -116,11 +117,11 @@ int mgag200_driver_load(struct drm_device *dev, > unsigned long flags) > mdev->has_sdram = !(option & (1 << 14)); > > /* BAR 0 is the framebuffer, BAR 1 contains registers */ > - mdev->rmmio_base = pci_resource_start(mdev->dev->pdev, 1); > - mdev->rmmio_size = pci_resource_len(mdev->dev->pdev, 1); > + mdev->rmmio_base = pci_resource_start(dev->pdev, 1); > + mdev->rmmio_size = pci_resource_len(dev->pdev, 1); > > - if (!devm_request_mem_region(mdev->dev->dev, mdev->rmmio_base, > mdev->rmmio_size, > - "mgadrmfb_mmio")) { > + if (!devm_request_mem_region(dev->dev, mdev->rmmio_base, > + mdev->rmmio_size, "mgadrmfb_mmio")) { > drm_err(dev, "can't reserve mmio registers\n"); > return -ENOMEM; > } > diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c > b/drivers/gpu/drm/mgag200/mgag200_mode.c > index fa91869c0db52..aaa73b29b04f0 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_mode.c > +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c > @@ -1433,6 +1433,7 @@ static const struct drm_crtc_helper_funcs > mga_helper_funcs = { > /* CRTC setup */ > static void mga_crtc_init(struct mga_device *mdev) > { > + struct drm_device *dev = mdev->dev; > struct mga_crtc *mga_crtc; > > mga_crtc = kzalloc(sizeof(struct mga_crtc) + > @@ -1442,7 +1443,7 @@ static void mga_crtc_init(struct mga_device *mdev) > if (mga_crtc == NULL) > return; > > - drm_crtc_init(mdev->dev, _crtc->base, _crtc_funcs); > + drm_crtc_init(dev, _crtc->base, _crtc_funcs); > > drm_mode_crtc_set_gamma_size(_crtc->base, MGAG200_LUT_SIZE); > mdev->mode_info.crtc = mga_crtc; > @@ -1617,30 +1618,30 @@ static struct drm_connector *mga_vga_init(struct > drm_device *dev) > > int mgag200_modeset_init(struct mga_device *mdev) > { > + struct drm_device *dev = mdev->dev; > struct drm_encoder *encoder = >encoder; > struct drm_connector *connector; > int ret; > > mdev->mode_info.mode_config_initialized = true; > > - mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH; > - mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT; > + dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH; > + dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT; > > - mdev->dev->mode_config.fb_base = mdev->mc.vram_base; > + dev->mode_config.fb_base = mdev->mc.vram_base; > > mga_crtc_init(mdev); > > - ret = drm_simple_encoder_init(mdev->dev, encoder, > - DRM_MODE_ENCODER_DAC); > + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); > if (ret) { > - drm_err(mdev->dev, > + drm_err(dev, > "drm_simple_encoder_init() failed, error %d\n", Join with line before. > ret); > return ret; > } >
Re: [PATCH] drm/amd/display: Fix pageflip event race condition for DCN. (v2)
Sure, I'll file one after work today. To clarify though, FreeSync still "works" as in the monitor refresh rate is updating, but it constantly bounces between the maximum and minimum freesync refresh rates, causing it to look VERY stuttery. Thanks for the attention, I'll file the but tonight. If you want another reference person, it got a little discussion in this bug report... https://gitlab.freedesktop.org/drm/amd/-/issues/1002#note_486494 Cheers, Matt On 5/5/20 11:59 AM, Kazlauskas, Nicholas wrote: > Can you file a full bug report on the gitlab tracker? > > FreeSync is still working on my Navi setups with this patch applied, and > this patch is essentially just a revert of another patch already (where > FreeSync worked before). > > I can understand the v2 of this series causing issues, but the v1 > shouldn't be - so I'd like to understand more about the setup where this > is causing issues - ASIC, OS, compositor, displays, dmesg log, X log, etc. > > Regards, > Nicholas Kazlauskas > > On 2020-05-05 1:03 p.m., Alex Deucher wrote: >> Mario or Nick any thoughts? >> >> Alex >> >> On Mon, May 4, 2020 at 1:35 PM Matt Coffin wrote: >>> >>> Hey guys, >>> >>> This is still an issue for me, and I'm still having to run a patch to >>> revert this as of 5.7-rc4. To avoid breaking a lot of people's Navi >>> setups in 5.7, is there any news on this? Has anyone else at the very >>> least been able to reproduce the problem? >>> >>> It happens for me in every single program that mesa allows to utilize >>> variable refresh rates, and reverting it "fixes" the issue. >>> >>> Cheers, and sorry for the extra email, just making sure this is still on >>> someone's radar, >>> Matt >>> >>> On 4/14/20 5:32 PM, Matt Coffin wrote: Hey everyone, This patch broke variable refresh rate in games (all that I've tried so far... Project CARS 2, DiRT Rally 2.0, Assetto Corsa Competizione) as well as a simple freesync tester application. FreeSync tester I've been using: https://github.com/Nixola/VRRTest I'm not at all familiar with the page flipping code, so it would take me a long time to find the *right* way to fix it, but does someone else see why it would do that? The symptom is that the refresh rate of the display constantly bounces between the two ends of the FreeSync range (for me 40 -> 144), and the game stutters like a madman. Any help on where to start, ideas on how to fix it (other than just revert this commit, which I've done in the interim), or alternative patches would be appreciated. Thanks in advance for the work/help, Matt On 3/13/20 8:42 AM, Michel Dänzer wrote: > On 2020-03-13 1:35 p.m., Kazlauskas, Nicholas wrote: >> On 2020-03-12 10:32 a.m., Alex Deucher wrote: >>> On Thu, Mar 5, 2020 at 4:21 PM Mario Kleiner >>> wrote: Commit '16f17eda8bad ("drm/amd/display: Send vblank and user events at vsartup for DCN")' introduces a new way of pageflip completion handling for DCN, and some trouble. The current implementation introduces a race condition, which can cause pageflip completion events to be sent out one vblank too early, thereby confusing userspace and causing flicker: prepare_flip_isr(): 1. Pageflip programming takes the ddev->event_lock. 2. Sets acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED 3. Releases ddev->event_lock. --> Deadline for surface address regs double-buffering passes on target pipe. 4. dc_commit_updates_for_stream() MMIO programs the new pageflip into hw, but too late for current vblank. => pflip_status == AMDGPU_FLIP_SUBMITTED, but flip won't complete in current vblank due to missing the double-buffering deadline by a tiny bit. 5. VSTARTUP trigger point in vblank is reached, VSTARTUP irq fires, dm_dcn_crtc_high_irq() gets called. 6. Detects pflip_status == AMDGPU_FLIP_SUBMITTED and assumes the pageflip has been completed/will complete in this vblank and sends out pageflip completion event to userspace and resets pflip_status = AMDGPU_FLIP_NONE. => Flip completion event sent out one vblank too early. This behaviour has been observed during my testing with measurement hardware a couple of time. The commit message says that the extra flip event code was added to dm_dcn_crtc_high_irq() to prevent missing to send out pageflip events in case the pflip irq doesn't fire, because the "DCH HUBP" component is clock gated and doesn't fire pflip irqs in that state. Also that this clock gating may happen if no planes are active.
Re: [PATCH v2] drm: Fix HDCP failures when SRM fw is missing
On Wed, Apr 29, 2020 at 12:20 PM Ramalingam C wrote: > > On 2020-04-29 at 10:46:29 -0400, Sean Paul wrote: > > On Wed, Apr 29, 2020 at 10:22 AM Ramalingam C > > wrote: > > > > > > On 2020-04-29 at 09:58:16 -0400, Sean Paul wrote: > > > > On Wed, Apr 29, 2020 at 9:50 AM Ramalingam C > > > > wrote: > > > > > > > > > > On 2020-04-14 at 15:02:55 -0400, Sean Paul wrote: > > > > > > From: Sean Paul > > > > > > > > > > > > The SRM cleanup in 79643fddd6eb2 ("drm/hdcp: optimizing the srm > > > > > > handling") inadvertently altered the behavior of HDCP auth when > > > > > > the SRM firmware is missing. Before that patch, missing SRM was > > > > > > interpreted as the device having no revoked keys. With that patch, > > > > > > if the SRM fw file is missing we reject _all_ keys. > > > > > > > > > > > > This patch fixes that regression by returning success if the file > > > > > > cannot be found. It also checks the return value from request_srm > > > > > > such > > > > > > that we won't end up trying to parse the ksv list if there is an > > > > > > error > > > > > > fetching it. > > > > > > > > > > > > Fixes: 79643fddd6eb ("drm/hdcp: optimizing the srm handling") > > > > > > Cc: sta...@vger.kernel.org > > > > > > Cc: Ramalingam C > > > > > > Cc: Sean Paul > > > > > > Cc: Maarten Lankhorst > > > > > > Cc: Maxime Ripard > > > > > > Cc: Thomas Zimmermann > > > > > > Cc: David Airlie > > > > > > Cc: Daniel Vetter > > > > > > Cc: dri-devel@lists.freedesktop.org > > > > > > Signed-off-by: Sean Paul > > > > > > > > > > > > Changes in v2: > > > > > > -Noticed a couple other things to clean up > > > > > > --- > > > > > > > > > > > > Sorry for the quick rev, noticed a couple other loose ends that > > > > > > should > > > > > > be cleaned up. > > > > > > > > > > > > drivers/gpu/drm/drm_hdcp.c | 8 +++- > > > > > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > > > > > > > > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c > > > > > > index 7f386adcf872..910108ccaae1 100644 > > > > > > --- a/drivers/gpu/drm/drm_hdcp.c > > > > > > +++ b/drivers/gpu/drm/drm_hdcp.c > > > > > > @@ -241,8 +241,12 @@ static int drm_hdcp_request_srm(struct > > > > > > drm_device *drm_dev, > > > > > > > > > > > > ret = request_firmware_direct(, (const char *)fw_name, > > > > > > drm_dev->dev); > > > > > > - if (ret < 0) > > > > > > + if (ret < 0) { > > > > > > + *revoked_ksv_cnt = 0; > > > > > > + *revoked_ksv_list = NULL; > > > > > These two variables are already initialized by the caller. > > > > > > > > Right now it is, but that's not guaranteed. In the ret == 0 case, it's > > > > pretty common for a caller to assume the called function has > > > > validated/assigned all the function output. > > > Ok. > > > > > > > > > > + ret = 0; > > > > > Missing of this should have been caught by CI. May be CI system always > > > > > having the SRM file from previous execution. Never been removed. IGT > > > > > need a fix to clean the prior SRM files before execution. > > > > > > > > > > CI fix shouldn't block this fix. > > > > > > goto exit; > > > > > > + } > > > > > > > > > > > > if (fw->size && fw->data) > > > > > > ret = drm_hdcp_srm_update(fw->data, fw->size, > > > > > > revoked_ksv_list, > > > > > > @@ -287,6 +291,8 @@ int drm_hdcp_check_ksvs_revoked(struct > > > > > > drm_device *drm_dev, u8 *ksvs, > > > > > > > > > > > > ret = drm_hdcp_request_srm(drm_dev, _ksv_list, > > > > > > _ksv_cnt); > > > > > > + if (ret) > > > > > > + return ret; > > > > > This error code also shouldn't effect the caller(i915) > > > > > > > > Why not? I'd assume an invalid SRM revocation list should probably be > > > > treated as failure? > > > IMHO invalid SRM revocation need not be treated as HDCP authentication > > > failure. > > > > > > First of all SRM need not supplied by all players. and incase, supplied > > > SRM is not as per the spec, then we dont have any list of revoked ID. > > > with this I dont think we need to fail the HDCP authentication. Until we > > > have valid list of revoked IDs from SRM, and the receiver ID is matching > > > to one of the revoked IDs, I wouldn't want to fail the HDCP > > > authentication. > > > > > > > Ok, thanks for the explanation. This all seems reasonable to me. > > > > Looks like this can be applied as-is, right? > Yes. > Applied to drm-misc-fixes Sean > Thanks, > Ram > > > I'll review the patch you > > posted so we can ignore the -ve return values. > > > > Thanks for the review! > > > > Sean > > > > > -Ram > > > > > > > > > > > > > hence pushed a > > > > > change https://patchwork.freedesktop.org/series/76730/ > > > > > > > > > > With these addresed. > > > > > > > > > > LGTM. > > > > > > > > > > Reviewed-by: Ramalingam C > > > > > > > > > > > > /* revoked_ksv_cnt will be zero when above function
Re: [PATCH 4/5] drm/mgag200: Init and finalize devices in mgag200_device_{init,fini}()
Hi Thomas. On Tue, May 05, 2020 at 11:56:48AM +0200, Thomas Zimmermann wrote: > Device initialization is now done in mgag200_device_init(). Specifically, > the function allocates the DRM device and sets up the respective fields > in struct mga_device. > > A call to mgag200_device_fini() finalizes struct mga_device. > > The old function mgag200_driver_load() and mgag200_driver_unload() were > left over from the DRM driver's load callbacks and have now been removed. Not too big fan of this patch, due to the changes allocation. I would prefer if you merged patch 4+5 and then take it from there. You have patch 1+2+3 and they are now reviewed so why not push them and work on top of them. And then you could also push the patch that removes the cursor stuff so we do not need to look at that anymore. Sam > > Signed-off-by: Thomas Zimmermann > --- > drivers/gpu/drm/mgag200/mgag200_drv.c | 27 ++-- > drivers/gpu/drm/mgag200/mgag200_drv.h | 5 ++-- > drivers/gpu/drm/mgag200/mgag200_main.c | 34 -- > 3 files changed, 37 insertions(+), 29 deletions(-) > > diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c > b/drivers/gpu/drm/mgag200/mgag200_drv.c > index c2f0e4b40b052..ad12c1b7c66cc 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_drv.c > +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c > @@ -51,6 +51,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist); > > static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id > *ent) > { > + struct mga_device *mdev; > struct drm_device *dev; > int ret; > > @@ -60,31 +61,28 @@ static int mga_pci_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > if (ret) > return ret; > > - dev = drm_dev_alloc(, >dev); > - if (IS_ERR(dev)) { > - ret = PTR_ERR(dev); > + mdev = devm_kzalloc(>dev, sizeof(*mdev), GFP_KERNEL); > + if (!mdev) { > + ret = -ENOMEM; > goto err_pci_disable_device; > } > > - dev->pdev = pdev; > - pci_set_drvdata(pdev, dev); > - > - ret = mgag200_driver_load(dev, ent->driver_data); > + ret = mgag200_device_init(mdev, , pdev, ent->driver_data); > if (ret) > - goto err_drm_dev_put; > + goto err_pci_disable_device; > + > + dev = mdev->dev; > > ret = drm_dev_register(dev, ent->driver_data); > if (ret) > - goto err_mgag200_driver_unload; > + goto err_mgag200_device_fini; > > drm_fbdev_generic_setup(dev, 0); > > return 0; > > -err_mgag200_driver_unload: > - mgag200_driver_unload(dev); > -err_drm_dev_put: > - drm_dev_put(dev); > +err_mgag200_device_fini: > + mgag200_device_fini(mdev); > err_pci_disable_device: > pci_disable_device(pdev); > return ret; > @@ -93,9 +91,10 @@ static int mga_pci_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > static void mga_pci_remove(struct pci_dev *pdev) > { > struct drm_device *dev = pci_get_drvdata(pdev); > + struct mga_device *mdev = to_mga_device(dev); > > drm_dev_unregister(dev); > - mgag200_driver_unload(dev); > + mgag200_device_fini(mdev); > drm_dev_put(dev); > } > > diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h > b/drivers/gpu/drm/mgag200/mgag200_drv.h > index 632bbb50465c9..1ce0386669ffa 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_drv.h > +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h > @@ -200,8 +200,9 @@ int mgag200_modeset_init(struct mga_device *mdev); > void mgag200_modeset_fini(struct mga_device *mdev); > > /* mgag200_main.c */ > -int mgag200_driver_load(struct drm_device *dev, unsigned long flags); > -void mgag200_driver_unload(struct drm_device *dev); > +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, > + struct pci_dev *pdev, unsigned long flags); > +void mgag200_device_fini(struct mga_device *mdev); > > /* mgag200_i2c.c */ > struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); > diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c > b/drivers/gpu/drm/mgag200/mgag200_main.c > index 010b309c01fc4..070ff1f433df2 100644 > --- a/drivers/gpu/drm/mgag200/mgag200_main.c > +++ b/drivers/gpu/drm/mgag200/mgag200_main.c > @@ -11,6 +11,7 @@ > #include > > #include > +#include > #include > > #include "mgag200_drv.h" > @@ -96,17 +97,21 @@ static int mga_vram_init(struct mga_device *mdev) > */ > > > -int mgag200_driver_load(struct drm_device *dev, unsigned long flags) > +int mgag200_device_init(struct mga_device *mdev, struct drm_driver *drv, > + struct pci_dev *pdev, unsigned long flags) > { > - struct mga_device *mdev; > + struct drm_device *dev = mdev->dev; > int ret, option; > > - mdev = devm_kzalloc(dev->dev, sizeof(struct mga_device), GFP_KERNEL); > - if (mdev == NULL) > - return
[PATCH 00/16] dts/dt-bindings: Fix Arm Ltd. ARMv8 "boards"
Date: Mon, 4 May 2020 12:41:55 +0100 Subject: [PATCH 01/16] dt-bindings: mali-midgard: Allow dma-coherent Add the boolean dma-coherent property to the list of allowed properties, since some boards (Arm Juno) integrate the GPU this way. Signed-off-by: Andre Przywara --- Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml index 0407e45eb8c4..5d7165385e1f 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml @@ -87,6 +87,8 @@ properties: "#cooling-cells": const: 2 + dma-coherent: true + required: - compatible - reg -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/16] dts/dt-bindings: Fix Arm Ltd. ARMv8 "boards"
On 2020-05-05 5:51 pm, Andre Przywara wrote: Date: Mon, 4 May 2020 12:41:55 +0100 Subject: [PATCH 01/16] dt-bindings: mali-midgard: Allow dma-coherent Add the boolean dma-coherent property to the list of allowed properties, since some boards (Arm Juno) integrate the GPU this way. The same comment as for "iommus" applies to some degree here too. There's a bit more likelihood that the device itself does want to know whether it's integrated coherently, so that it can choose what memory attributes to use (as is the case here), but with protocols like ACE-lite it's possible to hard-wire any old dumb device to behave coherently without even realising. Thus this is another property that could legitimately turn up more or less anywhere. Robin. Signed-off-by: Andre Przywara --- Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml index 0407e45eb8c4..5d7165385e1f 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.yaml @@ -87,6 +87,8 @@ properties: "#cooling-cells": const: 2 + dma-coherent: true + required: - compatible - reg ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH net-next] net: bnxt: Remove Comparison to bool in bnxt_ethtool.c
From: Jason Yan Date: Tue, 5 May 2020 15:46:08 +0800 > Fix the following coccicheck warning: > > drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:1991:5-46: WARNING: > Comparison to bool > drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:1993:10-54: WARNING: > Comparison to bool > drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:2380:5-38: WARNING: > Comparison to bool > > Signed-off-by: Jason Yan Applied. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V6 3/4] backlight: qcom-wled: Add WLED5 bindings
On Thu, 23 Apr 2020 21:03:36 +0530, Kiran Gunda wrote: > Add WLED5 specific bindings. > > Signed-off-by: Kiran Gunda > Signed-off-by: Subbaraman Narayanamurthy > Acked-by: Daniel Thompson > --- > .../bindings/leds/backlight/qcom-wled.yaml | 59 > -- > 1 file changed, 56 insertions(+), 3 deletions(-) > Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Question about sRGB framebuffer support
Hi Artem. On Tue, May 05, 2020 at 01:24:16PM +0300, Artem Mygaiev wrote: > Hello all > > I am currently working on DRM/KMS driver for Fresco Logic FL2000 USB display > controller [1]. I have already implemented a POC driver [2] which is working > for > me, although there are still plenty of things to improve or fix, of course. > > So far I have one thing that I somehow cannot find in DRM/KMS documentation or > existing drivers: how to tell the system that HW expects sRGB (i.e. > non-linear) > color encoding in framebuffers? This is a HW limitation that I cannot > influence > by configuration. > > Any pointers are greatly appreciated. No clue, I hope others can help you. > > [1] www.frescologic.com/product/single/fl2000 > [2] https://github.com/klogg/fl2000_drm I just visited your github site - and noticed you are using the it66121 bridge. Phong LE have recently submitted a patch to add this bridge to the kernel: https://lore.kernel.org/dri-devel/20200311125135.30832-1-...@baylibre.com/ I did not really looks at your code, awaits that you feel ready to submit it. Sam ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH V6 1/4] backlight: qcom-wled: convert the wled bindings to .yaml format
On Thu, 23 Apr 2020 21:03:34 +0530, Kiran Gunda wrote: > Convert the qcom-wled bindings from .txt to .yaml format. > Also replace PM8941 to WLED3 and PMI8998 to WLED4. > > Signed-off-by: Kiran Gunda > Signed-off-by: Subbaraman Narayanamurthy > Acked-by: Daniel Thompson > --- > .../bindings/leds/backlight/qcom-wled.txt | 154 --- > .../bindings/leds/backlight/qcom-wled.yaml | 208 > + > 2 files changed, 208 insertions(+), 154 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/leds/backlight/qcom-wled.txt > create mode 100644 > Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml > Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: Fix pageflip event race condition for DCN. (v2)
Mario or Nick any thoughts? Alex On Mon, May 4, 2020 at 1:35 PM Matt Coffin wrote: > > Hey guys, > > This is still an issue for me, and I'm still having to run a patch to > revert this as of 5.7-rc4. To avoid breaking a lot of people's Navi > setups in 5.7, is there any news on this? Has anyone else at the very > least been able to reproduce the problem? > > It happens for me in every single program that mesa allows to utilize > variable refresh rates, and reverting it "fixes" the issue. > > Cheers, and sorry for the extra email, just making sure this is still on > someone's radar, > Matt > > On 4/14/20 5:32 PM, Matt Coffin wrote: > > Hey everyone, > > > > This patch broke variable refresh rate in games (all that I've tried so > > far... Project CARS 2, DiRT Rally 2.0, Assetto Corsa Competizione) as > > well as a simple freesync tester application. > > > > FreeSync tester I've been using: https://github.com/Nixola/VRRTest > > > > I'm not at all familiar with the page flipping code, so it would take me > > a long time to find the *right* way to fix it, but does someone else see > > why it would do that? > > > > The symptom is that the refresh rate of the display constantly bounces > > between the two ends of the FreeSync range (for me 40 -> 144), and the > > game stutters like a madman. > > > > Any help on where to start, ideas on how to fix it (other than just > > revert this commit, which I've done in the interim), or alternative > > patches would be appreciated. > > > > Thanks in advance for the work/help, > > Matt > > > > On 3/13/20 8:42 AM, Michel Dänzer wrote: > >> On 2020-03-13 1:35 p.m., Kazlauskas, Nicholas wrote: > >>> On 2020-03-12 10:32 a.m., Alex Deucher wrote: > On Thu, Mar 5, 2020 at 4:21 PM Mario Kleiner > wrote: > > > > Commit '16f17eda8bad ("drm/amd/display: Send vblank and user > > events at vsartup for DCN")' introduces a new way of pageflip > > completion handling for DCN, and some trouble. > > > > The current implementation introduces a race condition, which > > can cause pageflip completion events to be sent out one vblank > > too early, thereby confusing userspace and causing flicker: > > > > prepare_flip_isr(): > > > > 1. Pageflip programming takes the ddev->event_lock. > > 2. Sets acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED > > 3. Releases ddev->event_lock. > > > > --> Deadline for surface address regs double-buffering passes on > > target pipe. > > > > 4. dc_commit_updates_for_stream() MMIO programs the new pageflip > > into hw, but too late for current vblank. > > > > => pflip_status == AMDGPU_FLIP_SUBMITTED, but flip won't complete > > in current vblank due to missing the double-buffering deadline > > by a tiny bit. > > > > 5. VSTARTUP trigger point in vblank is reached, VSTARTUP irq fires, > > dm_dcn_crtc_high_irq() gets called. > > > > 6. Detects pflip_status == AMDGPU_FLIP_SUBMITTED and assumes the > > pageflip has been completed/will complete in this vblank and > > sends out pageflip completion event to userspace and resets > > pflip_status = AMDGPU_FLIP_NONE. > > > > => Flip completion event sent out one vblank too early. > > > > This behaviour has been observed during my testing with measurement > > hardware a couple of time. > > > > The commit message says that the extra flip event code was added to > > dm_dcn_crtc_high_irq() to prevent missing to send out pageflip events > > in case the pflip irq doesn't fire, because the "DCH HUBP" component > > is clock gated and doesn't fire pflip irqs in that state. Also that > > this clock gating may happen if no planes are active. According to > > Nicholas, the clock gating can also happen if psr is active, and the > > gating is controlled independently by the hardware, so difficult to > > detect if and when the completion code in above commit is needed. > > > > This patch tries the following solution: It only executes the extra > > pflip > > completion code in dm_dcn_crtc_high_irq() iff the hardware reports > > that there aren't any surface updated pending in the double-buffered > > surface scanout address registers. Otherwise it leaves pflip completion > > to the pflip irq handler, for a more race-free experience. > > > > This would only guard against the order of events mentioned above. > > If Step 5 (VSTARTUP trigger) happens before step 4 then this won't help > > at all, because 1-3 + 5 might happen even without the hw being > > programmed > > at all, ie. no surface update pending because none yet programmed > > into hw. > > > > Therefore this patch also changes locking in amdgpu_dm_commit_planes(), > > so that prepare_flip_isr() and dc_commit_updates_for_stream() are done > > under event_lock protection within the same
Re: [PATCH] drm/bridge: ti-sn65dsi86: Implement lane reordering + polarity
Hi On Mon, May 4, 2020 at 10:44 PM Stephen Boyd wrote: > > Quoting Douglas Anderson (2020-05-04 21:36:31) > > The ti-sn65dsi86 MIPI DSI to eDP bridge chip supports arbitrary > > remapping of eDP lanes and also polarity inversion. Both of these > > features have been described in the device tree bindings for the > > device since the beginning but were never implemented in the driver. > > Implement both of them. > > > > Part of this change also allows you to (via the same device tree > > bindings) specify to use fewer than the max number of DP lanes that > > the panel reports. This could be useful if your display supports more > > lanes but only a few are hooked up on your board. > > > > Signed-off-by: Douglas Anderson > > --- > > Except for one thing below: > > Reviewed-by: Stephen Boyd > > > diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > index 1a125423eb07..52cca54b525f 100644 > > --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c > > @@ -707,26 +716,20 @@ static void ti_sn_bridge_enable(struct drm_bridge > > *bridge) > > int dp_rate_idx; > > unsigned int val; > > int ret = -EINVAL; > > + int max_dp_lanes; > > > > - /* > > -* Run with the maximum number of lanes that the DP sink supports. > > -* > > -* Depending use cases, we might want to revisit this later because: > > -* - It's plausible that someone may have run fewer lines to the > > -* sink than the sink actually supports, assuming that the lines > > -* will just be driven at a higher rate. > > -* - The DP spec seems to indicate that it's more important to > > minimize > > -* the number of lanes than the link rate. > > -* > > -* If we do revisit, it would be important to measure the power > > impact. > > -*/ > > - pdata->dp_lanes = ti_sn_get_max_lanes(pdata); > > + max_dp_lanes = ti_sn_get_max_lanes(pdata); > > + pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes); > > > > /* DSI_A lane config */ > > val = CHA_DSI_LANES(4 - pdata->dsi->lanes); > > Not a problem in this patch, but maybe this can be SN_MAX_DP_LANES - > pdata->dsi->lanes now. Since I introduce the define in this patch, I'll update it in v2. > > regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, > >CHA_DSI_LANES_MASK, val); > > > > + regmap_write(pdata->regmap, SN_LN_ASSIGN_REG, pdata->ln_assign); > > + regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, LN_POLRS_MASK, > > + pdata->ln_polrs << LN_POLRS_OFFSET); > > + > > /* set dsi clk frequency value */ > > ti_sn_bridge_set_dsi_rate(pdata); > > > > @@ -1063,6 +1066,50 @@ static int ti_sn_setup_gpio_controller(struct > > ti_sn_bridge *pdata) > > return ret; > > } > > > > +static void ti_sn_bridge_parse_lanes(struct ti_sn_bridge *pdata, > > +struct device_node *np) > > +{ > > + u32 lane_assignments[SN_MAX_DP_LANES] = { 0, 1, 2, 3 }; > > + u32 lane_polarities[SN_MAX_DP_LANES] = { }; > > + struct device_node *endpoint; > > + u8 ln_assign = 0; > > + u8 ln_polrs = 0; > > Do we need to assign to 0 to start? Seems like no? Yes. See usage: ln_assign = ln_assign << LN_ASSIGN_WIDTH | lane_assignments[i]; ln_polrs = ln_polrs << 1 | lane_polarities[i]; Notably each time we shift a new bit in we base on the old value. If you think it'll make it clearer, I can put this initialization at the beginning of the loop. It's 2 extra lines of code but if it adds clarity I'll do it. > > + int dp_lanes; > > + int i; > > + > > + /* > > +* Read config from the device tree about lane remapping and lane > > +* polarities. These are optional and we assume identity map and > > +* normal polarity if nothing is specified. It's OK to specify just > > +* data-lanes but not lane-polarities but not vice versa. > > +*/ > > + endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); > > + dp_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); > > + if (dp_lanes > 0) { > > + of_property_read_u32_array(endpoint, "data-lanes", > > + lane_assignments, dp_lanes); > > + of_property_read_u32_array(endpoint, "lane-polarities", > > + lane_polarities, dp_lanes); > > + } else { > > + dp_lanes = SN_MAX_DP_LANES; > > + } > > Needs an of_node_put(endpoint) here for the > of_graph_get_endpoint_by_regs() above. Thanks! I'll fix in v2, which I'll send out either after a delay of a few days or whenever I get resolution on my email to Laurent, whichever comes first. ;-) -Doug ___ dri-devel
Re: [PATCH 3/3] drm/mediatek: mtk_dpi: Use simple encoder
Hi, Enric: Enric Balletbo i Serra 於 2020年5月4日 週一 下午10:14寫道: > > The mtk_dpi driver uses an empty implementation for its encoder. Replace > the code with the generic simple encoder. Reviewed-by: Chun-Kuang Hu > > Signed-off-by: Enric Balletbo i Serra > --- > > drivers/gpu/drm/mediatek/mtk_dpi.c | 14 +++--- > 1 file changed, 3 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index baad198c69eb..80778b2aac2a 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > > #include "mtk_dpi_regs.h" > #include "mtk_drm_ddp_comp.h" > @@ -510,15 +511,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, > return 0; > } > > -static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) > -{ > - drm_encoder_cleanup(encoder); > -} > - > -static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { > - .destroy = mtk_dpi_encoder_destroy, > -}; > - > static int mtk_dpi_bridge_attach(struct drm_bridge *bridge, > enum drm_bridge_attach_flags flags) > { > @@ -591,8 +583,8 @@ static int mtk_dpi_bind(struct device *dev, struct device > *master, void *data) > return ret; > } > > - ret = drm_encoder_init(drm_dev, >encoder, _dpi_encoder_funcs, > - DRM_MODE_ENCODER_TMDS, NULL); > + ret = drm_simple_encoder_init(drm_dev, >encoder, > + DRM_MODE_ENCODER_TMDS); > if (ret) { > dev_err(dev, "Failed to initialize decoder: %d\n", ret); > goto err_unregister; > -- > 2.26.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: Avoid integer overflow in amdgpu_device_suspend_display_audio
On Sat, May 2, 2020 at 4:35 AM Nathan Chancellor wrote: > > When building with Clang: > > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:4160:53: warning: overflow in > expression; result is -294967296 with type 'long' [-Winteger-overflow] > expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4L; > ^ > 1 warning generated. > > Multiplication happens first due to order of operations and both > NSEC_PER_SEC and 4 are long literals so the expression overflows. To > avoid this, make 4 an unsigned long long literal, which matches the > type of expires (u64). > > Fixes: 3f12acc8d6d4 ("drm/amdgpu: put the audio codec into suspend state > before gpu reset V3") > Link: https://github.com/ClangBuiltLinux/linux/issues/1017 > Signed-off-by: Nathan Chancellor Applied. Thanks! Alex > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index 6f93af972b0a..caa38e7d502e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -4157,7 +4157,7 @@ static int amdgpu_device_suspend_display_audio(struct > amdgpu_device *adev) > * the audio controller default autosuspend delay setting. > * 4S used here is guaranteed to cover that. > */ > - expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4L; > + expires = ktime_get_mono_fast_ns() + NSEC_PER_SEC * 4ULL; > > while (!pm_runtime_status_suspended(&(p->dev))) { > if (!pm_runtime_suspend(&(p->dev))) > > base-commit: fb9d670f57e3f6478602328bbbf71138be06ca4f > -- > 2.26.2 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v12 2/2] dt-bindings: documenting compatible string vendor "visionox"
On Wed, 29 Apr 2020 11:15:15 +0530, Harigovindan P wrote: > Documenting compatible string vendor "visionox" in vendor-prefix yaml file. > > Signed-off-by: Harigovindan P > --- > Changes in v11: > - Added compatible string in vendor-prefix yaml file > > Changes in v12: > - Fixed the string to clear dt_binding_check errors. > > Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ > 1 file changed, 2 insertions(+) > Acked-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel