diff options
| author | Dave Airlie <airlied@redhat.com> | 2021-04-07 17:32:05 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2021-04-07 17:32:12 +1000 |
| commit | 1539f71602edf09bb33666afddc5a781c42e768d (patch) | |
| tree | 7cdfad1e08b3d58acee56659de1f64f3bd2b1697 /drivers/gpu/drm | |
| parent | fb457e02f0ec09162734d7a0add1b0e39280c8d1 (diff) | |
| parent | 6c744983004ebc66756e582294672f8b991288d5 (diff) | |
| download | linux-1539f71602edf09bb33666afddc5a781c42e768d.tar.gz linux-1539f71602edf09bb33666afddc5a781c42e768d.tar.bz2 linux-1539f71602edf09bb33666afddc5a781c42e768d.zip | |
Merge tag 'drm-misc-next-2021-04-01' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.13:
UAPI Changes:
Cross-subsystem Changes:
Core Changes:
- mst: Improve topology logging
- edid: Rework and improvements for displayid
Driver Changes:
- anx7625: Regulators support
- bridge: Support for the Chipone ICN6211, Lontium LT8912B
- lt9611: Fix 4k panels handling
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210401110552.2b3yetlgsjtlotcn@gilmour
Diffstat (limited to 'drivers/gpu/drm')
67 files changed, 3894 insertions, 505 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 1461652921be..3c16bd1afd87 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -384,6 +384,8 @@ source "drivers/gpu/drm/tidss/Kconfig" source "drivers/gpu/drm/xlnx/Kconfig" +source "drivers/gpu/drm/gud/Kconfig" + # Keep legacy drivers last menuconfig DRM_LEGACY diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 5eb5bf7c16e3..5279db4392df 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -7,7 +7,7 @@ drm-y := drm_auth.o drm_cache.o \ drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_drv.o \ drm_sysfs.o drm_hashtab.o drm_mm.o \ - drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ + drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o drm_displayid.o \ drm_encoder_slave.o \ drm_trace_points.o drm_prime.o \ drm_rect.o drm_vma_manager.o drm_flip_work.o \ @@ -125,3 +125,4 @@ obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/ obj-$(CONFIG_DRM_MCDE) += mcde/ obj-$(CONFIG_DRM_TIDSS) += tidss/ obj-y += xlnx/ +obj-y += gud/ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index e8cafc97eada..f314e1e269cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -638,15 +638,15 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, struct amdgpu_vm_bo_base *bo_base; if (vm->bulk_moveable) { - spin_lock(&ttm_glob.lru_lock); + spin_lock(&adev->mman.bdev.lru_lock); ttm_bo_bulk_move_lru_tail(&vm->lru_bulk_move); - spin_unlock(&ttm_glob.lru_lock); + spin_unlock(&adev->mman.bdev.lru_lock); return; } memset(&vm->lru_bulk_move, 0, sizeof(vm->lru_bulk_move)); - spin_lock(&ttm_glob.lru_lock); + spin_lock(&adev->mman.bdev.lru_lock); list_for_each_entry(bo_base, &vm->idle, vm_status) { struct amdgpu_bo *bo = bo_base->bo; @@ -660,7 +660,7 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, &bo->shadow->tbo.mem, &vm->lru_bulk_move); } - spin_unlock(&ttm_glob.lru_lock); + spin_unlock(&adev->mman.bdev.lru_lock); vm->bulk_moveable = true; } diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index e4110d6ca7b3..dba62f92d051 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -27,6 +27,19 @@ 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_CHIPONE_ICN6211 + tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge" + depends on OF + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE + help + ICN6211 is MIPI-DSI/RGB Converter bridge from chipone. + + It has a flexible configuration of MIPI DSI signal input + and produce RGB565, RGB666, RGB888 output format. + + If in doubt, say "N". + config DRM_CHRONTEL_CH7033 tristate "Chrontel CH7033 Video Encoder" depends on OF @@ -48,6 +61,20 @@ config DRM_DISPLAY_CONNECTOR on ARM-based platforms. Saying Y here when this driver is not needed will not cause any issue. +config DRM_LONTIUM_LT8912B + tristate "Lontium LT8912B DSI/HDMI bridge" + depends on OF + select DRM_PANEL_BRIDGE + select DRM_KMS_HELPER + select REGMAP_I2C + help + Driver for Lontium LT8912B DSI to HDMI bridge + chip driver. + Please say Y if you have such hardware. + + Say M here if you want to support this hardware as a module. + The module will be named "lontium-lt8912b". + config DRM_LONTIUM_LT9611 tristate "Lontium LT9611 DSI/HDMI bridge" select SND_SOC_HDMI_CODEC if SND_SOC diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 86e7acc76f8d..5c61b50c1663 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,7 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o +obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o +obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c index d9164fab044d..aa6cda458eb9 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c @@ -550,28 +550,38 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge, DRM_MODE_CONNECTOR_eDP); if (err) { DRM_ERROR("Failed to initialize connector: %d\n", err); - return err; + goto aux_unregister; } drm_connector_helper_add(&anx6345->connector, &anx6345_connector_helper_funcs); - err = drm_connector_register(&anx6345->connector); - if (err) { - DRM_ERROR("Failed to register connector: %d\n", err); - return err; - } - anx6345->connector.polled = DRM_CONNECTOR_POLL_HPD; err = drm_connector_attach_encoder(&anx6345->connector, bridge->encoder); if (err) { DRM_ERROR("Failed to link up connector to encoder: %d\n", err); - return err; + goto connector_cleanup; + } + + err = drm_connector_register(&anx6345->connector); + if (err) { + DRM_ERROR("Failed to register connector: %d\n", err); + goto connector_cleanup; } return 0; +connector_cleanup: + drm_connector_cleanup(&anx6345->connector); +aux_unregister: + drm_dp_aux_unregister(&anx6345->aux); + return err; +} + +static void anx6345_bridge_detach(struct drm_bridge *bridge) +{ + drm_dp_aux_unregister(&bridge_to_anx6345(bridge)->aux); } static enum drm_mode_status @@ -624,6 +634,7 @@ static void anx6345_bridge_enable(struct drm_bridge *bridge) static const struct drm_bridge_funcs anx6345_bridge_funcs = { .attach = anx6345_bridge_attach, + .detach = anx6345_bridge_detach, .mode_valid = anx6345_bridge_mode_valid, .disable = anx6345_bridge_disable, .enable = anx6345_bridge_enable, diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c index 81debd02c169..f20558618220 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c @@ -918,28 +918,38 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, DRM_MODE_CONNECTOR_DisplayPort); if (err) { DRM_ERROR("Failed to initialize connector: %d\n", err); - return err; + goto aux_unregister; } drm_connector_helper_add(&anx78xx->connector, &anx78xx_connector_helper_funcs); - err = drm_connector_register(&anx78xx->connector); - if (err) { - DRM_ERROR("Failed to register connector: %d\n", err); - return err; - } - anx78xx->connector.polled = DRM_CONNECTOR_POLL_HPD; err = drm_connector_attach_encoder(&anx78xx->connector, bridge->encoder); if (err) { DRM_ERROR("Failed to link up connector to encoder: %d\n", err); - return err; + goto connector_cleanup; + } + + err = drm_connector_register(&anx78xx->connector); + if (err) { + DRM_ERROR("Failed to register connector: %d\n", err); + goto connector_cleanup; } return 0; +connector_cleanup: + drm_connector_cleanup(&anx78xx->connector); +aux_unregister: + drm_dp_aux_unregister(&anx78xx->aux); + return err; +} + +static void anx78xx_bridge_detach(struct drm_bridge *bridge) +{ + drm_dp_aux_unregister(&bridge_to_anx78xx(bridge)->aux); } static enum drm_mode_status @@ -1013,6 +1023,7 @@ static void anx78xx_bridge_enable(struct drm_bridge *bridge) static const struct drm_bridge_funcs anx78xx_bridge_funcs = { .attach = anx78xx_bridge_attach, + .detach = anx78xx_bridge_detach, .mode_valid = anx78xx_bridge_mode_valid, .disable = anx78xx_bridge_disable, .mode_set = anx78xx_bridge_mode_set, diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index aa1bb86293fd..f115233b1cb9 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1782,6 +1782,7 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev) err_disable_pm_runtime: pm_runtime_disable(dp->dev); + drm_dp_aux_unregister(&dp->aux); return ret; } diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 65cc05982f82..23283ba0c4f9 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/workqueue.h> @@ -875,12 +876,25 @@ static int sp_tx_edid_read(struct anx7625_data *ctx, static void anx7625_power_on(struct anx7625_data *ctx) { struct device *dev = &ctx->client->dev; + int ret, i; if (!ctx->pdata.low_power_mode) { DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n"); return; } + for (i = 0; i < ARRAY_SIZE(ctx->pdata.supplies); i++) { + ret = regulator_enable(ctx->pdata.supplies[i].consumer); + if (ret < 0) { + DRM_DEV_DEBUG_DRIVER(dev, "cannot enable supply %d: %d\n", + i, ret); + goto reg_err; + } + usleep_range(2000, 2100); + } + + usleep_range(4000, 4100); + /* Power on pin enable */ gpiod_set_value(ctx->pdata.gpio_p_on, 1); usleep_range(10000, 11000); @@ -889,11 +903,16 @@ static void anx7625_power_on(struct anx7625_data *ctx) usleep_range(10000, 11000); DRM_DEV_DEBUG_DRIVER(dev, "power on !\n"); + return; +reg_err: + for (--i; i >= 0; i--) + regulator_disable(ctx->pdata.supplies[i].consumer); } static void anx7625_power_standby(struct anx7625_data *ctx) { struct device *dev = &ctx->client->dev; + int ret; if (!ctx->pdata.low_power_mode) { DRM_DEV_DEBUG_DRIVER(dev, "not low power mode!\n"); @@ -904,6 +923,12 @@ static void anx7625_power_standby(struct anx7625_data *ctx) usleep_range(1000, 1100); gpiod_set_value(ctx->pdata.gpio_p_on, 0); usleep_range(1000, 1100); + + ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies), + ctx->pdata.supplies); + if (ret < 0) + DRM_DEV_DEBUG_DRIVER(dev, "cannot disable supplies %d\n", ret); + DRM_DEV_DEBUG_DRIVER(dev, "power down\n"); } @@ -1742,6 +1767,15 @@ static int anx7625_i2c_probe(struct i2c_client *client, platform->client = client; i2c_set_clientdata(client, platform); + pdata->supplies[0].supply = "vdd10"; + pdata->supplies[1].supply = "vdd18"; + pdata->supplies[2].supply = "vdd33"; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pdata->supplies), + pdata->supplies); + if (ret) { + DRM_DEV_ERROR(dev, "fail to get power supplies: %d\n", ret); + return ret; + } anx7625_init_gpio(platform); atomic_set(&platform->power_status, 0); diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 193ad86c5450..e4a086b3a3d7 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -350,6 +350,7 @@ struct s_edid_data { struct anx7625_platform_data { struct gpio_desc *gpio_p_on; struct gpio_desc *gpio_reset; + struct regulator_bulk_data supplies[3]; struct drm_bridge *panel_bridge; int intp_irq; u32 low_power_mode; diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c new file mode 100644 index 000000000000..a6151db95586 --- /dev/null +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Amarula Solutions(India) + * Author: Jagan Teki <jagan@amarulasolutions.com> + */ + +#include <drm/drm_of.h> +#include <drm/drm_print.h> +#include <drm/drm_mipi_dsi.h> + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#define HACTIVE_LI 0x20 +#define VACTIVE_LI 0x21 +#define VACTIVE_HACTIVE_HI 0x22 +#define HFP_LI 0x23 +#define HSYNC_LI 0x24 +#define HBP_LI 0x25 +#define HFP_HSW_HBP_HI 0x26 +#define VFP 0x27 +#define VSYNC 0x28 +#define VBP 0x29 + +struct chipone { + struct device *dev; + struct drm_bridge bridge; + struct drm_bridge *panel_bridge; + struct gpio_desc *enable_gpio; + struct regulator *vdd1; + struct regulator *vdd2; + struct regulator *vdd3; +}; + +static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) +{ + return container_of(bridge, struct chipone, bridge); +} + +static struct drm_display_mode *bridge_to_mode(struct drm_bridge *bridge) +{ + return &bridge->encoder->crtc->state->adjusted_mode; +} + +static inline int chipone_dsi_write(struct chipone *icn, const void *seq, + size_t len) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(icn->dev); + + return mipi_dsi_generic_write(dsi, seq, len); +} + +#define ICN6211_DSI(icn, seq...) \ + { \ + const u8 d[] = { seq }; \ + chipone_dsi_write(icn, d, ARRAY_SIZE(d)); \ + } + +static void chipone_enable(struct drm_bridge *bridge) +{ + struct chipone *icn = bridge_to_chipone(bridge); + struct drm_display_mode *mode = bridge_to_mode(bridge); + + ICN6211_DSI(icn, 0x7a, 0xc1); + + ICN6211_DSI(icn, HACTIVE_LI, mode->hdisplay & 0xff); + + ICN6211_DSI(icn, VACTIVE_LI, mode->vdisplay & 0xff); + + /** + * lsb nibble: 2nd nibble of hdisplay + * msb nibble: 2nd nibble of vdisplay + */ + ICN6211_DSI(icn, VACTIVE_HACTIVE_HI, + ((mode->hdisplay >> 8) & 0xf) | + (((mode->vdisplay >> 8) & 0xf) << 4)); + + ICN6211_DSI(icn, HFP_LI, mode->hsync_start - mode->hdisplay); + + ICN6211_DSI(icn, HSYNC_LI, mode->hsync_end - mode->hsync_start); + + ICN6211_DSI(icn, HBP_LI, mode->htotal - mode->hsync_end); + + ICN6211_DSI(icn, HFP_HSW_HBP_HI, 0x00); + + ICN6211_DSI(icn, VFP, mode->vsync_start - mode->vdisplay); + + ICN6211_DSI(icn, VSYNC, mode->vsync_end - mode->vsync_start); + + ICN6211_DSI(icn, VBP, mode->vtotal - mode->vsync_end); + + /* dsi specific sequence */ + ICN6211_DSI(icn, MIPI_DCS_SET_TEAR_OFF, 0x80); + ICN6211_DSI(icn, MIPI_DCS_SET_ADDRESS_MODE, 0x28); + ICN6211_DSI(icn, 0xb5, 0xa0); + ICN6211_DSI(icn, 0x5c, 0xff); + ICN6211_DSI(icn, MIPI_DCS_SET_COLUMN_ADDRESS, 0x01); + ICN6211_DSI(icn, MIPI_DCS_GET_POWER_SAVE, 0x92); + ICN6211_DSI(icn, 0x6b, 0x71); + ICN6211_DSI(icn, 0x69, 0x2b); + ICN6211_DSI(icn, MIPI_DCS_ENTER_SLEEP_MODE, 0x40); + ICN6211_DSI(icn, MIPI_DCS_EXIT_SLEEP_MODE, 0x98); + + /* icn6211 specific sequence */ + ICN6211_DSI(icn, 0xb6, 0x20); + ICN6211_DSI(icn, 0x51, 0x20); + ICN6211_DSI(icn, 0x09, 0x10); + + usleep_range(10000, 1 |
