summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2024-04-27 10:27:29 +0300
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2024-04-27 10:27:29 +0300
commit02aa7823449673ec44a73402084535f00fd9b854 (patch)
treefadb16aecf439eec0905fedc692dac2daef19e5a
parent9c87114a6fb43a61405643bf388affd0c21a79c2 (diff)
parentc72211751870ffa2cff5d91834059456cfa7cbd5 (diff)
Merge remote-tracking branch 'drm-misc/drm-misc-next' into drm-tip
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c361
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.c2
-rw-r--r--drivers/gpu/drm/tiny/ili9225.c1
-rw-r--r--drivers/gpu/drm/tiny/mi0283qt.c1
-rw-r--r--drivers/gpu/drm/tiny/panel-mipi-dbi.c1
-rw-r--r--drivers/gpu/drm/tiny/st7586.c1
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_disp.c50
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dp.c25
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dpsub.c7
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dpsub.h1
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_kms.h4
13 files changed, 382 insertions, 80 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d6327dc12cb1..23997d2ea91c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6766,7 +6766,7 @@ DRM DRIVER FOR LG SW43408 PANELS
M: Sumit Semwal <sumit.semwal@linaro.org>
M: Caleb Connolly <caleb.connolly@linaro.org>
S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
+T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml
F: drivers/gpu/drm/panel/panel-lg-sw43408.c
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index 6f5d376d8fcc..3fbc57b16a05 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -211,6 +211,12 @@ struct nvkm_gsp {
struct mutex mutex;;
struct idr idr;
} client_id;
+
+ /* A linked list of registry items. The registry RPC will be built from it. */
+ struct list_head registry_list;
+
+ /* The size of the registry RPC */
+ size_t registry_rpc_size;
};
static inline bool
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
index 9858c1438aa7..0b46db5c77b8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
@@ -54,6 +54,8 @@
#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h>
#include <linux/acpi.h>
+#include <linux/ctype.h>
+#include <linux/parser.h>
#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE
#define GSP_MSG_MAX_SIZE GSP_PAGE_MIN_SIZE * 16
@@ -1080,53 +1082,364 @@ r535_gsp_rpc_unloading_guest_driver(struct nvkm_gsp *gsp, bool suspend)
return nvkm_gsp_rpc_wr(gsp, rpc, true);
}
+enum registry_type {
+ REGISTRY_TABLE_ENTRY_TYPE_DWORD = 1, /* 32-bit unsigned integer */
+ REGISTRY_TABLE_ENTRY_TYPE_BINARY = 2, /* Binary blob */
+ REGISTRY_TABLE_ENTRY_TYPE_STRING = 3, /* Null-terminated string */
+};
+
+/* An arbitrary limit to the length of a registry key */
+#define REGISTRY_MAX_KEY_LENGTH 64
+
+/**
+ * registry_list_entry - linked list member for a registry key/value
+ * @head: list_head struct
+ * @type: dword, binary, or string
+ * @klen: the length of name of the key
+ * @vlen: the length of the value
+ * @key: the key name
+ * @dword: the data, if REGISTRY_TABLE_ENTRY_TYPE_DWORD
+ * @binary: the data, if TYPE_BINARY or TYPE_STRING
+ *
+ * Every registry key/value is represented internally by this struct.
+ *
+ * Type DWORD is a simple 32-bit unsigned integer, and its value is stored in
+ * @dword.
+ *
+ * Types BINARY and STRING are variable-length binary blobs. The only real
+ * difference between BINARY and STRING is that STRING is null-terminated and
+ * is expected to contain only printable characters.
+ *
+ * Note: it is technically possible to have multiple keys with the same name
+ * but different types, but this is not useful since GSP-RM expects keys to
+ * have only one specific type.
+ */
+struct registry_list_entry {
+ struct list_head head;
+ enum registry_type type;
+ size_t klen;
+ char key[REGISTRY_MAX_KEY_LENGTH];
+ size_t vlen;
+ u32 dword; /* TYPE_DWORD */
+ u8 binary[] __counted_by(vlen); /* TYPE_BINARY or TYPE_STRING */
+};
+
+/**
+ * add_registry -- adds a registry entry
+ * @gsp: gsp pointer
+ * @key: name of the registry key
+ * @type: type of data
+ * @data: pointer to value
+ * @length: size of data, in bytes
+ *
+ * Adds a registry key/value pair to the registry database.
+ *
+ * This function collects the registry information in a linked list. After
+ * all registry keys have been added, build_registry() is used to create the
+ * RPC data structure.
+ *
+ * registry_rpc_size is a running total of the size of all registry keys.
+ * It's used to avoid an O(n) calculation of the size when the RPC is built.
+ *
+ * Returns 0 on success, or negative error code on error.
+ */
+static int add_registry(struct nvkm_gsp *gsp, const char *key,
+ enum registry_type type, const void *data, size_t length)
+{
+ struct registry_list_entry *reg;
+ const size_t nlen = strnlen(key, REGISTRY_MAX_KEY_LENGTH) + 1;
+ size_t alloc_size; /* extra bytes to alloc for binary or string value */
+
+ if (nlen > REGISTRY_MAX_KEY_LENGTH)
+ return -EINVAL;
+
+ alloc_size = (type == REGISTRY_TABLE_ENTRY_TYPE_DWORD) ? 0 : length;
+
+ reg = kmalloc(sizeof(*reg) + alloc_size, GFP_KERNEL);
+ if (!reg)
+ return -ENOMEM;
+
+ switch (type) {
+ case REGISTRY_TABLE_ENTRY_TYPE_DWORD:
+ reg->dword = *(const u32 *)(data);
+ break;
+ case REGISTRY_TABLE_ENTRY_TYPE_BINARY:
+ case REGISTRY_TABLE_ENTRY_TYPE_STRING:
+ memcpy(reg->binary, data, alloc_size);
+ break;
+ default:
+ nvkm_error(&gsp->subdev, "unrecognized registry type %u for '%s'\n",
+ type, key);
+ kfree(reg);
+ return -EINVAL;
+ }
+
+ memcpy(reg->key, key, nlen);
+ reg->klen = nlen;
+ reg->vlen = length;
+ reg->type = type;
+
+ list_add_tail(&reg->head, &gsp->registry_list);
+ gsp->registry_rpc_size += sizeof(PACKED_REGISTRY_ENTRY) + nlen + alloc_size;
+
+ return 0;
+}
+
+static int add_registry_num(struct nvkm_gsp *gsp, const char *key, u32 value)
+{
+ return add_registry(gsp, key, REGISTRY_TABLE_ENTRY_TYPE_DWORD,
+ &value, sizeof(u32));
+}
+
+static int add_registry_string(struct nvkm_gsp *gsp, const char *key, const char *value)
+{
+ return add_registry(gsp, key, REGISTRY_TABLE_ENTRY_TYPE_STRING,
+ value, strlen(value) + 1);
+}
+
+/**
+ * build_registry -- create the registry RPC data
+ * @gsp: gsp pointer
+ * @registry: pointer to the RPC payload to fill
+ *
+ * After all registry key/value pairs have been added, call this function to
+ * build the RPC.
+ *
+ * The registry RPC looks like this:
+ *
+ * +-----------------+
+ * |NvU32 size; |
+ * |NvU32 numEntries;|
+ * +-----------------+
+ * +----------------------------------------+
+ * |PACKED_REGISTRY_ENTRY |
+ * +----------------------------------------+
+ * |Null-terminated key (string) for entry 0|
+ * +----------------------------------------+
+ * |Binary/string data value for entry 0 | (only if necessary)
+ * +----------------------------------------+
+ *
+ * +----------------------------------------+
+ * |PACKED_REGISTRY_ENTRY |
+ * +----------------------------------------+
+ * |Null-terminated key (string) for entry 1|
+ * +----------------------------------------+
+ * |Binary/string data value for entry 1 | (only if necessary)
+ * +----------------------------------------+
+ * ... (and so on, one copy for each entry)
+ *
+ *
+ * The 'data' field of an entry is either a 32-bit integer (for type DWORD)
+ * or an offset into the PACKED_REGISTRY_TABLE (for types BINARY and STRING).
+ *
+ * All memory allocated by add_registry() is released.
+ */
+static void build_registry(struct nvkm_gsp *gsp, PACKED_REGISTRY_TABLE *registry)
+{
+ struct registry_list_entry *reg, *n;
+ size_t str_offset;
+ unsigned int i = 0;
+
+ registry->numEntries = list_count_nodes(&gsp->registry_list);
+ str_offset = struct_size(registry, entries, registry->numEntries);
+
+ list_for_each_entry_safe(reg, n, &gsp->registry_list, head) {
+ registry->entries[i].type = reg->type;
+ registry->entries[i].length = reg->vlen;
+
+ /* Append the key name to the table */
+ registry->entries[i].nameOffset = str_offset;
+ memcpy((void *)registry + str_offset, reg->key, reg->klen);
+ str_offset += reg->klen;
+
+ switch (reg->type) {
+ case REGISTRY_TABLE_ENTRY_TYPE_DWORD:
+ registry->entries[i].data = reg->dword;
+ break;
+ case REGISTRY_TABLE_ENTRY_TYPE_BINARY:
+ case REGISTRY_TABLE_ENTRY_TYPE_STRING:
+ /* If the type is binary or string, also append the value */
+ memcpy((void *)registry + str_offset, reg->binary, reg->vlen);
+ registry->entries[i].data = str_offset;
+ str_offset += reg->vlen;
+ break;
+ default:
+ }
+
+ i++;
+ list_del(&reg->head);
+ kfree(reg);
+ }
+
+ /* Double-check that we calculated the sizes correctly */
+ WARN_ON(gsp->registry_rpc_size != str_offset);
+
+ registry->size = gsp->registry_rpc_size;
+}
+
+/**
+ * clean_registry -- clean up registry memory in case of error
+ * @gsp: gsp pointer
+ *
+ * Call this function to clean up all memory allocated by add_registry()
+ * in case of error and build_registry() is not called.
+ */
+static void clean_registry(struct nvkm_gsp *gsp)
+{
+ struct registry_list_entry *reg, *n;
+
+ list_for_each_entry_safe(reg, n, &gsp->registry_list, head) {
+ list_del(&reg->head);
+ kfree(reg);
+ }
+
+ gsp->registry_rpc_size = sizeof(PACKED_REGISTRY_TABLE);
+}
+
+MODULE_PARM_DESC(NVreg_RegistryDwords,
+ "A semicolon-separated list of key=integer pairs of GSP-RM registry keys");
+static char *NVreg_RegistryDwords;
+module_param(NVreg_RegistryDwords, charp, 0400);
+
/* dword only */
struct nv_gsp_registry_entries {
const char *name;
u32 value;
};
+/**
+ * r535_registry_entries - required registry entries for GSP-RM
+ *
+ * This array lists registry entries that are required for GSP-RM to
+ * function correctly.
+ *
+ * RMSecBusResetEnable - enables PCI secondary bus reset
+ * RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration
+ * registers on any PCI reset.
+ */
static const struct nv_gsp_registry_entries r535_registry_entries[] = {
{ "RMSecBusResetEnable", 1 },
{ "RMForcePcieConfigSave", 1 },
};
#define NV_GSP_REG_NUM_ENTRIES ARRAY_SIZE(r535_registry_entries)
+/**
+ * strip - strips all characters in 'reject' from 's'
+ * @s: string to strip
+ * @reject: string of characters to remove
+ *
+ * 's' is modified.
+ *
+ * Returns the length of the new string.
+ */
+static size_t strip(char *s, const char *reject)
+{
+ char *p = s, *p2 = s;
+ size_t length = 0;
+ char c;
+
+ do {
+ while ((c = *p2) && strchr(reject, c))
+ p2++;
+
+ *p++ = c = *p2++;
+ length++;
+ } while (c);
+
+ return length;
+}
+
+/**
+ * r535_gsp_rpc_set_registry - build registry RPC and call GSP-RM
+ * @gsp: gsp pointer
+ *
+ * The GSP-RM registry is a set of key/value pairs that configure some aspects
+ * of GSP-RM. The keys are strings, and the values are 32-bit integers.
+ *
+ * The registry is built from a combination of a static hard-coded list (see
+ * above) and entries passed on the driver's command line.
+ */
static int
r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp)
{
PACKED_REGISTRY_TABLE *rpc;
- char *strings;
- int str_offset;
- int i;
- size_t rpc_size = struct_size(rpc, entries, NV_GSP_REG_NUM_ENTRIES);
+ unsigned int i;
+ int ret;
- /* add strings + null terminator */
- for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++)
- rpc_size += strlen(r535_registry_entries[i].name) + 1;
+ INIT_LIST_HEAD(&gsp->registry_list);
+ gsp->registry_rpc_size = sizeof(PACKED_REGISTRY_TABLE);
- rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, rpc_size);
- if (IS_ERR(rpc))
- return PTR_ERR(rpc);
+ for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) {
+ ret = add_registry_num(gsp, r535_registry_entries[i].name,
+ r535_registry_entries[i].value);
+ if (ret)
+ goto fail;
+ }
- rpc->numEntries = NV_GSP_REG_NUM_ENTRIES;
+ /*
+ * The NVreg_RegistryDwords parameter is a string of key=value
+ * pairs separated by semicolons. We need to extract and trim each
+ * substring, and then parse the substring to extract the key and
+ * value.
+ */
+ if (NVreg_RegistryDwords) {
+ char *p = kstrdup(NVreg_RegistryDwords, GFP_KERNEL);
+ char *start, *next = p, *equal;
+
+ if (!p) {
+ ret = -ENOMEM;
+ goto fail;
+ }
- str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]);
- strings = (char *)rpc + str_offset;
- for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) {
- int name_len = strlen(r535_registry_entries[i].name) + 1;
-
- rpc->entries[i].nameOffset = str_offset;
- rpc->entries[i].type = 1;
- rpc->entries[i].data = r535_registry_entries[i].value;
- rpc->entries[i].length = 4;
- memcpy(strings, r535_registry_entries[i].name, name_len);
- strings += name_len;
- str_offset += name_len;
+ /* Remove any whitespace from the parameter string */
+ strip(p, " \t\n");
+
+ while ((start = strsep(&next, ";"))) {
+ long value;
+
+ equal = strchr(start, '=');
+ if (!equal || equal == start || equal[1] == 0) {
+ nvkm_error(&gsp->subdev,
+ "ignoring invalid registry string '%s'\n",
+ start);
+ continue;
+ }
+
+ /* Truncate the key=value string to just key */
+ *equal = 0;
+
+ ret = kstrtol(equal + 1, 0, &value);
+ if (!ret) {
+ ret = add_registry_num(gsp, start, value);
+ } else {
+ /* Not a number, so treat it as a string */
+ ret = add_registry_string(gsp, start, equal + 1);
+ }
+
+ if (ret) {
+ nvkm_error(&gsp->subdev,
+ "ignoring invalid registry key/value '%s=%s'\n",
+ start, equal + 1);
+ continue;
+ }
+ }
+
+ kfree(p);
+ }
+
+ rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, gsp->registry_rpc_size);
+ if (IS_ERR(rpc)) {
+ ret = PTR_ERR(rpc);
+ goto fail;
}
- rpc->size = str_offset;
+
+ build_registry(gsp, rpc);
return nvkm_gsp_rpc_wr(gsp, rpc, false);
+
+fail:
+ clean_registry(gsp);
+ return ret;
}
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 62ebbdb16253..9873172e3fd3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2344,7 +2344,7 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
else
- port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index dd8b0a181be9..eb1213352bce 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -447,7 +447,6 @@ static void ili9225_shutdown(struct spi_device *spi)
static struct spi_driver ili9225_spi_driver = {
.driver = {
.name = "ili9225",
- .owner = THIS_MODULE,
.of_match_table = ili9225_of_match,
},
.id_table = ili9225_id,
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index 01ff43c8ac3f..05509e519518 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -263,7 +263,6 @@ static const struct dev_pm_ops mi0283qt_pm_ops = {
static struct spi_driver mi0283qt_spi_driver = {
.driver = {
.name = "mi0283qt",
- .owner = THIS_MODULE,
.of_match_table = mi0283qt_of_match,
.pm = &mi0283qt_pm_ops,
},
diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
index f80a141fcf36..a3cc09c578c5 100644
--- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c
+++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
@@ -384,7 +384,6 @@ MODULE_DEVICE_TABLE(spi, panel_mipi_dbi_spi_id);
static struct spi_driver panel_mipi_dbi_spi_driver = {
.driver = {
.name = "panel-mipi-dbi-spi",
- .owner = THIS_MODULE,
.of_match_table = panel_mipi_dbi_spi_of_match,
.pm = &panel_mipi_dbi_pm_ops,
},
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 7336fa1ddaed..c4ad8340180e 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -392,7 +392,6 @@ static void st7586_shutdown(struct spi_device *spi)
static struct spi_driver st7586_spi_driver = {
.driver = {
.name = "st7586",
- .owner = THIS_MODULE,
.of_match_table = st7586_of_match,
},
.id_table = st7586_id,
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 13157da0089e..9368acf56eaf 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -141,24 +141,18 @@ struct zynqmp_disp_layer {
* struct zynqmp_disp - Display controller
* @dev: Device structure
* @dpsub: Display subsystem
- * @blend.base: Register I/O base address for the blender
- * @avbuf.base: Register I/O base address for the audio/video buffer manager
- * @audio.base: Registers I/O base address for the audio mixer
+ * @blend: Register I/O base address for the blender
+ * @avbuf: Register I/O base address for the audio/video buffer manager
+ * @audio: Registers I/O base address for the audio mixer
* @layers: Layers (planes)
*/
struct zynqmp_disp {
struct device *dev;
struct zynqmp_dpsub *dpsub;
- struct {
- void __iomem *base;
- } blend;
- struct {
- void __iomem *base;
- } avbuf;
- struct {
- void __iomem *base;
- } audio;
+ void __iomem *blend;
+ void __iomem *avbuf;
+ void __iomem *audio;
struct zynqmp_disp_layer layers[ZYNQMP_DPSUB_NUM_LAYERS];
};
@@ -410,12 +404,12 @@ static const struct zynqmp_disp_format avbuf_live_fmts[] = {
static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
{
- return readl(disp->avbuf.base + reg);
+ return readl(disp->avbuf + reg);
}
static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->avbuf.base + reg);
+ writel(val, disp->avbuf + reg);
}
static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
@@ -651,7 +645,7 @@ static void zynqmp_disp_avbuf_disable(struct zynqmp_disp *disp)
static void zynqmp_disp_blend_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->blend.base + reg);
+ writel(val, disp->blend + reg);
}
/*
@@ -877,7 +871,7 @@ static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
static void zynqmp_disp_audio_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->audio.base + reg);
+ writel(val, disp->audio + reg);
}
/**
@@ -940,7 +934,7 @@ zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
* zynqmp_disp_layer_find_live_format - Find format information for given
* media bus format
* @layer: The layer
- * @drm_fmt: Media bus format to search
+ * @media_bus_format: Media bus format to search
*
* Search display subsystem format information corresponding to the given media
* bus format @media_bus_format for the @layer, and return a pointer to the
@@ -981,7 +975,7 @@ u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
unsigned int i;
u32 *formats;
- if (WARN_ON(!layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE)) {
+ if (WARN_ON(layer->mode != ZYNQMP_DPSUB_LAYER_NONLIVE)) {
*num_formats = 0;
return NULL;
}
@@ -1117,7 +1111,7 @@ void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
/**
* zynqmp_disp_layer_set_live_format - Set the live video layer format
* @layer: The layer
- * @info: The format info
+ * @media_bus_format: Media bus format to set
*
* NOTE: This function should not be used to set format for non-live video
* layer. Use zynqmp_disp_layer_set_format() instead.
@@ -1412,21 +1406,21 @@ int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub)
disp->dev = &pdev->dev;
disp->dpsub = dpsub;
- disp->blend.base = devm_platform_ioremap_resource_byname(pdev, "blend");
- if (IS_ERR(disp->blend.base)) {
- ret = PTR_ERR(disp->blend.base);
+ disp->blend = devm_platform_ioremap_resource_byname(pdev, "blend");
+ if (IS_ERR(disp->blend)) {
+ ret = PTR_ERR(disp->blend);
goto error;
}
- disp->avbuf.base = devm_platform_ioremap_resource_byname(pdev, "av_buf");
- if (IS_ERR(disp->avbuf.base)) {
- ret = PTR_ERR(disp->avbuf.base);
+ disp->avbuf = devm_platform_ioremap_resource_byname(pdev, "av_buf");
+ if (IS_ERR(disp->avbuf)) {
+ ret = PTR_ERR(disp->avbuf);
goto error;
}
- disp->audio.base = devm_platform_ioremap_resource_byname(pdev, "aud");
- if (IS_ERR(disp->audio.base)) {
- ret = PTR_ERR(disp->audio.base);
+ disp->audio = devm_platform_ioremap_resource_byname(pdev, "aud");
+ if (IS_ERR(disp->audio)) {
+ ret = PTR_ERR(disp->audio);
goto error;
}
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 8c2d24809014..9df068a413f3 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -606,28 +606,21 @@ static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp,
u8 link_status[DP_LINK_STATUS_SIZE])
{
u8 *train_set = dp->train_set;
- u8 voltage = 0, preemphasis = 0;
u8 i;
for (i = 0; i < dp->mode.lane_cnt; i++) {
- u8 v = drm_dp_get_adjust_request_voltage(link_status, i);
- u8 p = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
+ u8 voltage = drm_dp_get_adjust_request_voltage(link_status, i);
+ u8 preemphasis =
+ drm_dp_get_adjust_request_pre_emphasis(link_status, i);
- if (v > voltage)
- voltage = v;
+ if (voltage >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+ voltage |= DP_TRAIN_MAX_SWING_REACHED;
- if (p > preemphasis)
- preemphasis = p;
- }
-
- if (voltage >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
- voltage |= DP_TRAIN_MAX_SWING_REACHED;
+ if (preemphasis >= DP_TRAIN_PRE_EMPH_LEVEL_2)
+ preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
- if (preemphasis >= DP_TRAIN_PRE_EMPH_LEVEL_2)
- preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
-
- for (i = 0; i < dp->mode.lane_cnt; i++)
train_set[i] = voltage | preemphasis;
+ }
}
/**
@@ -1007,7 +1000,7 @@ zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
msg->buffer, msg->size,
&msg->reply);
if (!ret) {
- dev_dbg(dp->dev, "aux %d retries\n", i);
+ dev_vdbg(dp->dev, "aux %d retries\n", i);
return msg->size;
}
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index 88eb33acd5f0..face8d6b2a6f 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -256,12 +256,12 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
if (ret)
goto err_dp;
+ drm_bridge_add(dpsub->bridge);
+
if (dpsub->dma_enabled) {
ret = zynqmp_dpsub_drm_init(dpsub);
if (ret)
goto err_disp;
- } else {
- drm_bridge_add(dpsub->bridge);
}
dev_info(&pdev->dev, "ZynqMP DisplayPort Subsystem driver probed");
@@ -288,9 +288,8 @@ static void zynqmp_dpsub_remove(struct platform_device *pdev)
if (dpsub->drm)
zynqmp_dpsub_drm_cleanup(dpsub);
- else
- drm_bridge_remove(dpsub->bridge);
+ drm_bridge_remove(dpsub->bridge);
zynqmp_disp_remove(dpsub);
zynqmp_dp_remove(dpsub);
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
index 09ea01878f2a..b18554467e9c 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
@@ -53,6 +53,7 @@ enum zynqmp_dpsub_format {
* @drm: The DRM/KMS device data
* @bridge: The DP encoder bridge
* @disp: The display controller
+ * @layers: Video and graphics layers
* @dp: The DisplayPort controller
* @dma_align: DMA alignment constraint (must be a power of 2)
*/
diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.h b/drivers/gpu/drm/xlnx/zynqmp_kms.h
index 01be96b00e3f..cb13c6b8008e 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_kms.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_kms.h
@@ -22,9 +22,9 @@
struct zynqmp_dpsub;
/**
- * struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem DRM/KMS data
+ * struct zynqmp_dpsub_drm - ZynqMP DisplayPort Subsystem DRM/KMS data
* @dpsub: Backpointer to the DisplayPort subsystem
- * @drm: The DRM/KMS device
+ * @dev: The DRM/KMS device
* @planes: The DRM planes
* @crtc: The DRM CRTC
* @encoder: The dummy DRM encoder