From fc903ebd50d0396b5de1ff614a009c2ddcb3222c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 12 Feb 2016 14:48:30 +0530 Subject: [PATCH 01/12] drm/dsi: Check for CONFIG_OF when defining of_mipi_dsi_device_add() of_mipi_dsi_device_add() is used only when CONFIG_OF is enabled. It currently works if OF support is disabled, but this will change when we add more functionality to it. Define the original function if CONFIG_OF is enabled and a dummy function otherwise. Signed-off-by: Archit Taneja Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 6e6a9c58d404..4f2a70471e05 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -129,6 +129,7 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi) return device_add(&dsi->dev); } +#if IS_ENABLED(CONFIG_OF) static struct mipi_dsi_device * of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) { @@ -170,6 +171,13 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) return dsi; } +#else +static struct mipi_dsi_device * +of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) +{ + return ERR_PTR(-ENODEV); +} +#endif int mipi_dsi_host_register(struct mipi_dsi_host *host) { From c63ae8a9686bb8c87154a31dc5ebadbda778a8e5 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 12 Feb 2016 14:48:31 +0530 Subject: [PATCH 02/12] drm/dsi: Use mipi_dsi_device_register_full() for DSI device creation Use mipi_dsi_device_register_full() for device creation. This takes in a struct mipi_dsi_device_info as a template to populate the DSI device information. The reason to introduce this is to have a way to create DSI devices not available via DT. Drivers that want to create a DSI device can populate a struct mipi_dsi_device_info and call this function. For DSI devices available via DT, of_mipi_dsi_device_add() is used as before, but this now calls mipi_dsi_device_register_full() internally. Signed-off-by: Archit Taneja Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 80 +++++++++++++++++++++++----------- include/drm/drm_mipi_dsi.h | 16 +++++++ 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 4f2a70471e05..5d7243da2323 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -133,8 +133,8 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi) static struct mipi_dsi_device * of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) { - struct mipi_dsi_device *dsi; struct device *dev = host->dev; + struct mipi_dsi_device_info info = { }; int ret; u32 reg; @@ -145,31 +145,10 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) return ERR_PTR(-EINVAL); } - if (reg > 3) { - dev_err(dev, "device node %s has invalid reg property: %u\n", - node->full_name, reg); - return ERR_PTR(-EINVAL); - } + info.channel = reg; + info.node = of_node_get(node); - dsi = mipi_dsi_device_alloc(host); - if (IS_ERR(dsi)) { - dev_err(dev, "failed to allocate DSI device %s: %ld\n", - node->full_name, PTR_ERR(dsi)); - return dsi; - } - - dsi->dev.of_node = of_node_get(node); - dsi->channel = reg; - - ret = mipi_dsi_device_add(dsi); - if (ret) { - dev_err(dev, "failed to add DSI device %s: %d\n", - node->full_name, ret); - kfree(dsi); - return ERR_PTR(ret); - } - - return dsi; + return mipi_dsi_device_register_full(host, &info); } #else static struct mipi_dsi_device * @@ -179,6 +158,57 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) } #endif +/** + * mipi_dsi_device_register_full - create a MIPI DSI device + * @host: DSI host to which this device is connected + * @info: pointer to template containing DSI device information + * + * Create a MIPI DSI device by using the device information provided by + * mipi_dsi_device_info template + * + * Returns: + * A pointer to the newly created MIPI DSI device, or, a pointer encoded + * with an error + */ +struct mipi_dsi_device * +mipi_dsi_device_register_full(struct mipi_dsi_host *host, + const struct mipi_dsi_device_info *info) +{ + struct mipi_dsi_device *dsi; + struct device *dev = host->dev; + int ret; + + if (!info) { + dev_err(dev, "invalid mipi_dsi_device_info pointer\n"); + return ERR_PTR(-EINVAL); + } + + if (info->channel > 3) { + dev_err(dev, "invalid virtual channel: %u\n", info->channel); + return ERR_PTR(-EINVAL); + } + + dsi = mipi_dsi_device_alloc(host); + if (IS_ERR(dsi)) { + dev_err(dev, "failed to allocate DSI device %ld\n", + PTR_ERR(dsi)); + return dsi; + } + + dsi->dev.of_node = info->node; + dsi->channel = info->channel; + + ret = mipi_dsi_device_add(dsi); + if (ret) { + dev_err(dev, "failed to add DSI device %d\n", ret); + kfree(dsi); + return ERR_PTR(ret); + } + + return dsi; +} +EXPORT_SYMBOL(mipi_dsi_device_register_full); + int mipi_dsi_host_register(struct mipi_dsi_host *host) { struct device_node *node; diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 1b3b1f8c8cdf..ce5eae438fd1 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -139,6 +139,19 @@ enum mipi_dsi_pixel_format { MIPI_DSI_FMT_RGB565, }; + /** + * struct mipi_dsi_device_info - template for creating a mipi_dsi_device + * @channel: DSI virtual channel assigned to peripheral + * @node: pointer to OF device node + * + * This is populated and passed to mipi_dsi_device_new to create a new + * DSI device + */ +struct mipi_dsi_device_info { + u32 channel; + struct device_node *node; +}; + /** * struct mipi_dsi_device - DSI peripheral device * @host: DSI host for this peripheral @@ -188,6 +201,9 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) return -EINVAL; } +struct mipi_dsi_device * +mipi_dsi_device_register_full(struct mipi_dsi_host *host, + const struct mipi_dsi_device_info *info); struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi); From bf4363ce3a67ba06042351f40841ef4da9b30787 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 12 Feb 2016 14:48:32 +0530 Subject: [PATCH 03/12] drm/dsi: Try to match non-DT DSI devices Add a device name field in struct mipi_dsi_device. This name is not the same as the device name (which is of the format "hostname.reg"). When the device is created via DT, this name is set to the modalias string. In the non-DT case, the driver creating the DSI device provides the name by populating a field in struct mipi_dsi_device_info. Matching for DT case would be as it was before. For the non-DT case, we compare the device and driver names. Other buses (like I2C/SPI) perform a non-DT match by comparing the device name and entries in the driver's id_table. Such a mechanism isn't used for the DSI bus. Reviewed-by: Andrzej Hajda Signed-off-by: Archit Taneja Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 18 +++++++++++++++++- include/drm/drm_mipi_dsi.h | 10 ++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 5d7243da2323..42a7aacf7a2f 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -47,7 +47,17 @@ static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) { - return of_driver_match_device(dev, drv); + struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + + /* attempt OF style match */ + if (of_driver_match_device(dev, drv)) + return 1; + + /* compare DSI device and driver names */ + if (!strcmp(dsi->name, drv->name)) + return 1; + + return 0; } static const struct dev_pm_ops mipi_dsi_device_pm_ops = { @@ -138,6 +148,11 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) int ret; u32 reg; + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { + dev_err(dev, "modalias failure on %s\n", node->full_name); + return ERR_PTR(-EINVAL); + } + ret = of_property_read_u32(node, "reg", ®); if (ret) { dev_err(dev, "device node %s has no valid reg property: %d\n", @@ -197,6 +212,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host, dsi->dev.of_node = info->node; dsi->channel = info->channel; + strlcpy(dsi->name, info->type, sizeof(dsi->name)); ret = mipi_dsi_device_add(dsi); if (ret) { diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index ce5eae438fd1..a91411682e83 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -139,15 +139,19 @@ enum mipi_dsi_pixel_format { MIPI_DSI_FMT_RGB565, }; - /** +#define DSI_DEV_NAME_SIZE 20 + +/** * struct mipi_dsi_device_info - template for creating a mipi_dsi_device + * @type: DSI peripheral chip type * @channel: DSI virtual channel assigned to peripheral - * @node: pointer to OF device node + * @node: pointer to OF device node or NULL * * This is populated and passed to mipi_dsi_device_new to create a new * DSI device */ struct mipi_dsi_device_info { + char type[DSI_DEV_NAME_SIZE]; u32 channel; struct device_node *node; }; @@ -156,6 +160,7 @@ struct mipi_dsi_device_info { * struct mipi_dsi_device - DSI peripheral device * @host: DSI host for this peripheral * @dev: driver model device node for this peripheral + * @name: DSI peripheral chip type * @channel: virtual channel assigned to the peripheral * @format: pixel format for video mode * @lanes: number of active data lanes @@ -165,6 +170,7 @@ struct mipi_dsi_device { struct mipi_dsi_host *host; struct device dev; + char name[DSI_DEV_NAME_SIZE]; unsigned int channel; unsigned int lanes; enum mipi_dsi_pixel_format format; From 509e42ce0441df39d5241150c1bec32cf6347b6c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 12 Feb 2016 14:48:33 +0530 Subject: [PATCH 04/12] drm/dsi: Add routine to unregister a DSI device A driver calling mipi_dsi_device_register_full() might want to remove the device once it's done. It might also require it in an error handling path in case something went wrong. Create mipi_dsi_device_unregister() for this purpose and use it within mipi_dsi_remove_device_fn() as it does the same thing. Reviewed-by: Andrzej Hajda Signed-off-by: Archit Taneja Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 12 +++++++++++- include/drm/drm_mipi_dsi.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 42a7aacf7a2f..f2f5a6d3669a 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -225,6 +225,16 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host, } EXPORT_SYMBOL(mipi_dsi_device_register_full); +/** + * mipi_dsi_device_unregister - unregister MIPI DSI device + * @dsi: DSI peripheral device + */ +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi) +{ + device_unregister(&dsi->dev); +} +EXPORT_SYMBOL(mipi_dsi_device_unregister); + int mipi_dsi_host_register(struct mipi_dsi_host *host) { struct device_node *node; @@ -244,7 +254,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); - device_unregister(&dsi->dev); + mipi_dsi_device_unregister(dsi); return 0; } diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index a91411682e83..06e0a9382b35 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -210,6 +210,7 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) struct mipi_dsi_device * mipi_dsi_device_register_full(struct mipi_dsi_host *host, const struct mipi_dsi_device_info *info); +void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi); struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi); From 97b6ae50e05c533b6455e304d36bdf2bb5604ee6 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 12 Feb 2016 14:48:34 +0530 Subject: [PATCH 05/12] drm/dsi: Get DSI host by DT device node MIPI DSI devices are inherently aware of their host because they share a parent-child hierarchy in the device tree. Non-DSI drivers that create DSI device don't have this data. In order to get this information, they require to a phandle to the DSI host in the device tree. Maintain a list of all the DSI hosts that are currently registered. This list will be used to find the struct mipi_dsi_host corresponding to the device tree node passed to of_find_mipi_dsi_host_by_node(). Reviewed-by: Andrzej Hajda Signed-off-by: Archit Taneja Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 39 ++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index f2f5a6d3669a..f5d80839a90c 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -235,6 +235,37 @@ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi) } EXPORT_SYMBOL(mipi_dsi_device_unregister); +static DEFINE_MUTEX(host_lock); +static LIST_HEAD(host_list); + +/** + * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a + * device tree node + * @node: device tree node + * + * Returns: + * A pointer to the MIPI DSI host corresponding to @node or NULL if no + * such device exists (or has not been registered yet). + */ +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node) +{ + struct mipi_dsi_host *host; + + mutex_lock(&host_lock); + + list_for_each_entry(host, &host_list, list) { + if (host->dev->of_node == node) { + mutex_unlock(&host_lock); + return host; + } + } + + mutex_unlock(&host_lock); + + return NULL; +} +EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node); + int mipi_dsi_host_register(struct mipi_dsi_host *host) { struct device_node *node; @@ -246,6 +277,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host) of_mipi_dsi_device_add(host, node); } + mutex_lock(&host_lock); + list_add_tail(&host->list, &host_list); + mutex_unlock(&host_lock); + return 0; } EXPORT_SYMBOL(mipi_dsi_host_register); @@ -262,6 +297,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) void mipi_dsi_host_unregister(struct mipi_dsi_host *host) { device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); + + mutex_lock(&host_lock); + list_del_init(&host->list); + mutex_unlock(&host_lock); } EXPORT_SYMBOL(mipi_dsi_host_unregister); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 06e0a9382b35..7a9840f8b38e 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -96,14 +96,17 @@ struct mipi_dsi_host_ops { * struct mipi_dsi_host - DSI host device * @dev: driver model device node for this DSI host * @ops: DSI host operations + * @list: list management */ struct mipi_dsi_host { struct device *dev; const struct mipi_dsi_host_ops *ops; + struct list_head list; }; int mipi_dsi_host_register(struct mipi_dsi_host *host); void mipi_dsi_host_unregister(struct mipi_dsi_host *host); +struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node); /* DSI mode flags */ From 2e8c5eb9ef938a069fd9586769787021b2541698 Mon Sep 17 00:00:00 2001 From: Akshay Bhat Date: Tue, 1 Mar 2016 18:06:54 -0500 Subject: [PATCH 06/12] drm/panel: simple: Fix g121x1_l03 hsync/vsync polarity Set hsync/vsync to active low for g121x1_l03 panel to match the recommended setting in the datasheet. Signed-off-by: Akshay Bhat Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index f88a631c43ab..7a65cc849355 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -847,6 +847,7 @@ static const struct drm_display_mode innolux_g121x1_l03_mode = { .vsync_end = 768 + 38 + 1, .vtotal = 768 + 38 + 1 + 0, .vrefresh = 60, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, }; static const struct panel_desc innolux_g121x1_l03 = { From 2aa2e57f8106a1692d66d591161c623742d945fa Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Mon, 22 Feb 2016 19:01:43 +0800 Subject: [PATCH 07/12] dt-bindings: Add LG lp120up1 panel bindings Add documentation for lp120up1 panel Signed-off-by: Jitao Shi Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../devicetree/bindings/display/panel/lg,lp120up1.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt diff --git a/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt new file mode 100644 index 000000000000..8c5de692c55c --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt @@ -0,0 +1,7 @@ +LG 12.0" (1920x1280 pixels) TFT LCD panel + +Required properties: +- compatible: should be "lg,lp120up1" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. From 690d8fa70da2f81cf880a656d254d02172ed9c7b Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Mon, 22 Feb 2016 19:01:44 +0800 Subject: [PATCH 08/12] drm/panel: simple: Support for LG lp120up1 panel The LG lp120up1 TFT LCD panel with eDP interface is a 12.0" 1920x1280 panel, which can be supported by the simple panel driver. Signed-off-by: Jitao Shi Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 7a65cc849355..5186dbf6901c 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -983,6 +983,29 @@ static const struct panel_desc lg_lb070wv8 = { .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, }; +static const struct drm_display_mode lg_lp120up1_mode = { + .clock = 162300, + .hdisplay = 1920, + .hsync_start = 1920 + 40, + .hsync_end = 1920 + 40 + 40, + .htotal = 1920 + 40 + 40+ 80, + .vdisplay = 1280, + .vsync_start = 1280 + 4, + .vsync_end = 1280 + 4 + 4, + .vtotal = 1280 + 4 + 4 + 12, + .vrefresh = 60, +}; + +static const struct panel_desc lg_lp120up1 = { + .modes = &lg_lp120up1_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 267, + .height = 183, + }, +}; + static const struct drm_display_mode lg_lp129qe_mode = { .clock = 285250, .hdisplay = 2560, @@ -1256,6 +1279,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "lg,lb070wv8", .data = &lg_lb070wv8, + }, { + .compatible = "lg,lp120up1", + .data = &lg_lp120up1, }, { .compatible = "lg,lp129qe", .data = &lg_lp129qe, From 75fedc809f6ed27203e64c3cadda1316f06006dc Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Fri, 5 Feb 2016 00:19:56 +0100 Subject: [PATCH 09/12] of: Add United Radiant Technology Corporation vendor prefix Add vendor prefix for United Radiant Technology Corporation, a provider of liquid crystal display technologies. Signed-off-by: Maciej S. Szmigiero Acked-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 72e2c5a2b327..1bcef7300b37 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -240,6 +240,7 @@ tplink TP-LINK Technologies Co., Ltd. tronfy Tronfy truly Truly Semiconductors Limited upisemi uPI Semiconductor Corp. +urt United Radiant Technology Corporation usi Universal Scientific Industrial Co., Ltd. v3 V3 Semiconductor variscite Variscite Ltd. From 610599ca5d7c3b9fe7490e6a375a6c00911d8e8c Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 13 Feb 2016 22:50:24 +0100 Subject: [PATCH 10/12] dt-bindings: Add URT UMSH-8596MD-xT panel bindings Add DT bindings for United Radiant Technology UMSH-8596MD-xT 7.0" WVGA TFT LCD panels. Signed-off-by: Maciej S. Szmigiero Acked-by: Rob Herring Signed-off-by: Thierry Reding --- .../bindings/display/panel/urt,umsh-8596md.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt diff --git a/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt new file mode 100644 index 000000000000..088a6cea5015 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt @@ -0,0 +1,16 @@ +United Radiant Technology UMSH-8596MD-xT 7.0" WVGA TFT LCD panel + +Supported are LVDS versions (-11T, -19T) and parallel ones +(-T, -1T, -7T, -20T). + +Required properties: +- compatible: should be one of: + "urt,umsh-8596md-t", + "urt,umsh-8596md-1t", + "urt,umsh-8596md-7t", + "urt,umsh-8596md-11t", + "urt,umsh-8596md-19t", + "urt,umsh-8596md-20t". + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. From 06a9dc65afbd9d9e81ee6352a13f968e0540237e Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sat, 13 Feb 2016 22:52:03 +0100 Subject: [PATCH 11/12] drm/panel: simple: Add URT UMSH-8596MD-xT panels support Add support for United Radiant Technology UMSH-8596MD-xT 7.0" WVGA TFT LCD panels in the simple-panel driver. Signed-off-by: Maciej S. Szmigiero Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5186dbf6901c..1d194c8581dc 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1200,6 +1200,42 @@ static const struct panel_desc shelly_sca07010_bfn_lnn = { .bus_format = MEDIA_BUS_FMT_RGB666_1X18, }; +static const struct display_timing urt_umsh_8596md_timing = { + .pixelclock = { 33260000, 33260000, 33260000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 41, 41, 41 }, + .hback_porch = { 216 - 128, 216 - 128, 216 - 128 }, + .hsync_len = { 71, 128, 128 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 10, 10, 10 }, + .vback_porch = { 35 - 2, 35 - 2, 35 - 2 }, + .vsync_len = { 2, 2, 2 }, + .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE | + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, +}; + +static const struct panel_desc urt_umsh_8596md_lvds = { + .timings = &urt_umsh_8596md_timing, + .num_timings = 1, + .bpc = 6, + .size = { + .width = 152, + .height = 91, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, +}; + +static const struct panel_desc urt_umsh_8596md_parallel = { + .timings = &urt_umsh_8596md_timing, + .num_timings = 1, + .bpc = 6, + .size = { + .width = 152, + .height = 91, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, +}; + static const struct of_device_id platform_of_match[] = { { .compatible = "ampire,am800480r3tmqwa1h", @@ -1306,6 +1342,24 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "shelly,sca07010-bfn-lnn", .data = &shelly_sca07010_bfn_lnn, + }, { + .compatible = "urt,umsh-8596md-t", + .data = &urt_umsh_8596md_parallel, + }, { + .compatible = "urt,umsh-8596md-1t", + .data = &urt_umsh_8596md_parallel, + }, { + .compatible = "urt,umsh-8596md-7t", + .data = &urt_umsh_8596md_parallel, + }, { + .compatible = "urt,umsh-8596md-11t", + .data = &urt_umsh_8596md_lvds, + }, { + .compatible = "urt,umsh-8596md-19t", + .data = &urt_umsh_8596md_lvds, + }, { + .compatible = "urt,umsh-8596md-20t", + .data = &urt_umsh_8596md_parallel, }, { /* sentinel */ } From c8a3b2ae07130042682bc8e031bcfbae3754463d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 26 Feb 2016 11:51:06 +0200 Subject: [PATCH 12/12] drm/bridge: Make (pre/post) enable/disable callbacks optional Instead of forcing bridges to implement empty callbacks make them all optional. Signed-off-by: Laurent Pinchart Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_bridge.c | 12 ++++++++---- include/drm/drm_crtc.h | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index bd93453afa61..b3654404abd0 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -186,7 +186,8 @@ void drm_bridge_disable(struct drm_bridge *bridge) drm_bridge_disable(bridge->next); - bridge->funcs->disable(bridge); + if (bridge->funcs->disable) + bridge->funcs->disable(bridge); } EXPORT_SYMBOL(drm_bridge_disable); @@ -206,7 +207,8 @@ void drm_bridge_post_disable(struct drm_bridge *bridge) if (!bridge) return; - bridge->funcs->post_disable(bridge); + if (bridge->funcs->post_disable) + bridge->funcs->post_disable(bridge); drm_bridge_post_disable(bridge->next); } @@ -256,7 +258,8 @@ void drm_bridge_pre_enable(struct drm_bridge *bridge) drm_bridge_pre_enable(bridge->next); - bridge->funcs->pre_enable(bridge); + if (bridge->funcs->pre_enable) + bridge->funcs->pre_enable(bridge); } EXPORT_SYMBOL(drm_bridge_pre_enable); @@ -276,7 +279,8 @@ void drm_bridge_enable(struct drm_bridge *bridge) if (!bridge) return; - bridge->funcs->enable(bridge); + if (bridge->funcs->enable) + bridge->funcs->enable(bridge); drm_bridge_enable(bridge->next); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c65a212db77e..f336671ca932 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1581,6 +1581,8 @@ struct drm_bridge_funcs { * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is still running when this callback is called. + * + * The disable callback is optional. */ void (*disable)(struct drm_bridge *bridge); @@ -1597,6 +1599,8 @@ struct drm_bridge_funcs { * The bridge must assume that the display pipe (i.e. clocks and timing * singals) feeding it is no longer running when this callback is * called. + * + * The post_disable callback is optional. */ void (*post_disable)(struct drm_bridge *bridge); @@ -1625,6 +1629,8 @@ struct drm_bridge_funcs { * will not yet be running when this callback is called. The bridge must * not enable the display link feeding the next bridge in the chain (if * there is one) when this callback is called. + * + * The pre_enable callback is optional. */ void (*pre_enable)(struct drm_bridge *bridge); @@ -1642,6 +1648,8 @@ struct drm_bridge_funcs { * signals) feeding it is running when this callback is called. This * callback must enable the display link feeding the next bridge in the * chain if there is one. + * + * The enable callback is optional. */ void (*enable)(struct drm_bridge *bridge); };