diff options
67 files changed, 1476 insertions, 437 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml index e841659e20cd..9f61ebdfefa8 100644 --- a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml +++ b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml @@ -105,6 +105,29 @@ properties: DSI output port node to the panel or the next bridge in the chain. + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 4 + uniqueItems: true + items: + enum: [ 1, 2, 3, 4 ] + + lane-polarities: + minItems: 1 + maxItems: 5 + description: + The Samsung MIPI DSI IP requires that all the data lanes have + the same polarity. + + dependencies: + lane-polarities: [data-lanes] + required: - clock-names - clocks diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml index e1494b5007cb..0521261b04a9 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml @@ -4,16 +4,24 @@ $id: http://devicetree.org/schemas/display/bridge/toshiba,tc358767.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Toshiba TC358767 eDP bridge +title: Toshiba TC358767/TC358867/TC9595 DSI/DPI/eDP bridge maintainers: - Andrey Gusakov <andrey.gusakov@cogentembedded.com> -description: The TC358767 is bridge device which converts DSI/DPI to eDP/DP +description: | + The TC358767/TC358867/TC9595 is bridge device which + converts DSI/DPI to eDP/DP . properties: compatible: - const: toshiba,tc358767 + oneOf: + - items: + - enum: + - toshiba,tc358867 + - toshiba,tc9595 + - const: toshiba,tc358767 + - const: toshiba,tc358767 reg: enum: diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index ec50dd268314..733e47da36e8 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -77,6 +77,8 @@ properties: - auo,t215hvn01 # Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel - avic,tm070ddh03 + # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel + - boe,ev121wxm-n10-1850 # BOE HV070WSA-100 7.01" WSVGA TFT LCD panel - boe,hv070wsa-100 # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml new file mode 100644 index 000000000000..45a236d2cc70 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,s6d7aa0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung S6D7AA0 MIPI-DSI LCD panel controller + +maintainers: + - Artur Weber <aweber.kernel@gmail.com> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - enum: + # 1280x800 LSL080AL02 panel + - samsung,lsl080al02 + # 1024x768 LSL080AL03 panel + - samsung,lsl080al03 + # 1024x768 LTL101AT01 panel + - samsung,ltl101at01 + - const: samsung,s6d7aa0 + + reg: true + + backlight: + description: + Backlight to use for the panel. If this property is set on panels + that have DSI-based backlight control (LSL080AL03 and LTL101AT01), + it overrides the DSI-based backlight. + + reset-gpios: + description: Reset GPIO pin, usually GPIO_ACTIVE_LOW. + + power-supply: + description: + Main power supply for the panel; the exact voltage differs between + panels, and is usually somewhere around 3.3-5v. + + vmipi-supply: + description: VMIPI supply, usually 1.8v. + +required: + - compatible + - reg + - reset-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,lsl080al02", "samsung,s6d7aa0"; + reg = <0>; + power-supply = <&display_3v3_supply>; + reset-gpios = <&gpf0 4 GPIO_ACTIVE_LOW>; + backlight = <&backlight>; + }; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 70d4385fd5ef..b344e1318ac3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6691,6 +6691,12 @@ S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c +DRM DRIVER FOR SAMSUNG S6D7AA0 PANELS +M: Artur Weber <aweber.kernel@gmail.com> +S: Maintained +F: Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml +F: drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c + DRM DRIVER FOR SITRONIX ST7586 PANELS M: David Lechner <david@lechnology.com> S: Maintained diff --git a/arch/ia64/include/asm/fb.h b/arch/ia64/include/asm/fb.h index 0208f64a0da0..1717b26fd423 100644 --- a/arch/ia64/include/asm/fb.h +++ b/arch/ia64/include/asm/fb.h @@ -2,7 +2,9 @@ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ +#include <linux/compiler.h> #include <linux/efi.h> +#include <linux/string.h> #include <asm/page.h> @@ -18,6 +20,24 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, } #define fb_pgprotect fb_pgprotect +static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) +{ + memcpy(to, (void __force *)from, n); +} +#define fb_memcpy_fromio fb_memcpy_fromio + +static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n) +{ + memcpy((void __force *)to, from, n); +} +#define fb_memcpy_toio fb_memcpy_toio + +static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n) +{ + memset((void __force *)addr, c, n); +} +#define fb_memset fb_memset_io + #include <asm-generic/fb.h> #endif /* _ASM_FB_H_ */ diff --git a/arch/loongarch/include/asm/fb.h b/arch/loongarch/include/asm/fb.h index ff82f20685c8..0b218b10a9ec 100644 --- a/arch/loongarch/include/asm/fb.h +++ b/arch/loongarch/include/asm/fb.h @@ -5,6 +5,27 @@ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ +#include <linux/compiler.h> +#include <linux/string.h> + +static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) +{ + memcpy(to, (void __force *)from, n); +} +#define fb_memcpy_fromio fb_memcpy_fromio + +static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n) +{ + memcpy((void __force *)to, from, n); +} +#define fb_memcpy_toio fb_memcpy_toio + +static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n) +{ + memset((void __force *)addr, c, n); +} +#define fb_memset fb_memset_io + #include <asm-generic/fb.h> #endif /* _ASM_FB_H_ */ diff --git a/arch/mips/include/asm/fb.h b/arch/mips/include/asm/fb.h index 6bda0a81d8ca..18b7226403ba 100644 --- a/arch/mips/include/asm/fb.h +++ b/arch/mips/include/asm/fb.h @@ -12,6 +12,28 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, } #define fb_pgprotect fb_pgprotect +/* + * MIPS doesn't define __raw_ I/O macros, so the helpers + * in <asm-generic/fb.h> don't generate fb_readq() and + * fb_write(). We have to provide them here. + * + * TODO: Convert MIPS to generic I/O. The helpers below can + * then be removed. + */ +#ifdef CONFIG_64BIT +static inline u64 fb_readq(const volatile void __iomem *addr) +{ + return __raw_readq(addr); +} +#define fb_readq fb_readq + +static inline void fb_writeq(u64 b, volatile void __iomem *addr) +{ + __raw_writeq(b, addr); +} +#define fb_writeq fb_writeq +#endif + #include <asm-generic/fb.h> #endif /* _ASM_FB_H_ */ diff --git a/arch/parisc/video/fbdev.c b/arch/parisc/video/fbdev.c index 4a0ae08fc75b..137561d98246 100644 --- a/arch/parisc/video/fbdev.c +++ b/arch/parisc/video/fbdev.c @@ -5,10 +5,9 @@ * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de> */ +#include <linux/fb.h> #include <linux/module.h> -#include <asm/fb.h> - #include <video/sticore.h> int fb_is_primary_device(struct fb_info *info) diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index 689ee5c60054..572ecd3e1cc4 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -2,6 +2,8 @@ #ifndef _SPARC_FB_H_ #define _SPARC_FB_H_ +#include <linux/io.h> + struct fb_info; struct file; struct vm_area_struct; @@ -16,6 +18,24 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, int fb_is_primary_device(struct fb_info *info); #define fb_is_primary_device fb_is_primary_device +static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) +{ + sbus_memcpy_fromio(to, from, n); +} +#define fb_memcpy_fromio fb_memcpy_fromio + +static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n) +{ + sbus_memcpy_toio(to, from, n); +} +#define fb_memcpy_toio fb_memcpy_toio + +static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n) +{ + sbus_memset_io(addr, c, n); +} +#define fb_memset fb_memset_io + #include <asm-generic/fb.h> #endif /* _SPARC_FB_H_ */ diff --git a/arch/sparc/video/fbdev.c b/arch/sparc/video/fbdev.c index dadd5799fbb3..25837f128132 100644 --- a/arch/sparc/video/fbdev.c +++ b/arch/sparc/video/fbdev.c @@ -4,7 +4,6 @@ #include <linux/fb.h> #include <linux/module.h> -#include <asm/fb.h> #include <asm/prom.h> int fb_is_primary_device(struct fb_info *info) diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c index 57ee3c158f97..f41a17ebac48 100644 --- a/arch/x86/video/fbdev.c +++ b/arch/x86/video/fbdev.c @@ -7,8 +7,6 @@ * */ -#include <asm/fb.h> - #include <linux/fb.h> #include <linux/module.h> #include <linux/pci.h> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 348b3a9170fa..63f0aeb66db6 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -85,7 +85,7 @@ static struct sync_timeline *sync_timeline_create(const char *name) kref_init(&obj->kref); obj->context = dma_fence_context_alloc(1); - strlcpy(obj->name, name, sizeof(obj->name)); + strscpy(obj->name, name, sizeof(obj->name)); obj->pt_tree = RB_ROOT; INIT_LIST_HEAD(&obj->pt_list); diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 3c197db42c9d..82fcfd29bc4d 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -128,4 +128,4 @@ unlock_mutex: } /* must execute after PCI subsystem for EFI quirks */ -device_initcall(sysfb_init); +subsys_initcall_sync(sysfb_init); diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 093e7b9a570f..c86531f7b072 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1686,6 +1686,14 @@ static int anx7625_parse_dt(struct device *dev, if (of_property_read_bool(np, "analogix,audio-enable")) pdata->audio_en = 1; + return 0; +} + +static int anx7625_parse_dt_panel(struct device *dev, + struct anx7625_platform_data *pdata) +{ + struct device_node *np = dev->of_node; + pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); if (IS_ERR(pdata->panel_bridge)) { if (PTR_ERR(pdata->panel_bridge) == -ENODEV) { @@ -2031,7 +2039,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx) return 0; } -static int anx7625_attach_dsi(struct anx7625_data *ctx) +static int anx7625_setup_dsi_device(struct anx7625_data *ctx) { struct mipi_dsi_device *dsi; struct device *dev = &ctx->client->dev; @@ -2041,9 +2049,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) .channel = 0, .node = NULL, }; - int ret; - - DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n"); host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node); if (!host) { @@ -2064,14 +2069,24 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_HS_PKT_END_ALIGNED; - ret = devm_mipi_dsi_attach(dev, dsi); + ctx->dsi = dsi; + + return 0; +} + +static int anx7625_attach_dsi(struct anx7625_data *ctx) +{ + struct device *dev = &ctx->client->dev; + int ret; + + DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n"); + + ret = devm_mipi_dsi_attach(dev, ctx->dsi); if (ret) { DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n"); return ret; } - ctx->dsi = dsi; - DRM_DEV_DEBUG_DRIVER(dev, "attach dsi succeeded.\n"); return 0; @@ -2559,6 +2574,40 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static int anx7625_link_bridge(struct drm_dp_aux *aux) +{ + struct anx7625_data *platform = container_of(aux, struct anx7625_data, aux); + struct device *dev = aux->dev; + int ret; + + ret = anx7625_parse_dt_panel(dev, &platform->pdata); + if (ret) { + DRM_DEV_ERROR(dev, "fail to parse DT for panel : %d\n", ret); + return ret; + } + + platform->bridge.funcs = &anx7625_bridge_funcs; + platform->bridge.of_node = dev->of_node; + if (!anx7625_of_panel_on_aux_bus(dev)) + platform->bridge.ops |= DRM_BRIDGE_OP_EDID; + if (!platform->pdata.panel_bridge) + platform->bridge.ops |= DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DETECT; + platform->bridge.type = platform->pdata.panel_bridge ? + DRM_MODE_CONNECTOR_eDP : + DRM_MODE_CONNECTOR_DisplayPort; + + drm_bridge_add(&platform->bridge); + + if (!platform->pdata.is_dpi) { + ret = anx7625_attach_dsi(platform); + if (ret) + drm_bridge_remove(&platform->bridge); + } + + return ret; +} + static int anx7625_i2c_probe(struct i2c_client *client) { struct anx7625_data *platform; @@ -2633,6 +2682,24 @@ static int anx7625_i2c_probe(struct i2c_client *client) platform->aux.wait_hpd_asserted = anx7625_wait_hpd_asserted; drm_dp_aux_init(&platform->aux); + ret = anx7625_parse_dt(dev, pdata); + if (ret) { + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); + goto free_wq; + } + + if (!platform->pdata.is_dpi) { + ret = anx7625_setup_dsi_device(platform); + if (ret < 0) + goto free_wq; + } + + /* + * Registering the i2c devices will retrigger deferred probe, so it + * needs to be done after calls that might return EPROBE_DEFER, + * otherwise we can get an infinite loop. + */ if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { ret = -ENOMEM; DRM_DEV_ERROR(dev, "fail to reserve I2C bus.\n"); @@ -2647,13 +2714,21 @@ static int anx7625_i2c_probe(struct i2c_client *client) if (ret) goto free_wq; - devm_of_dp_aux_populate_ep_devices(&platform->aux); - - ret = anx7625_parse_dt(dev, pdata); + /* + * Populating the aux bus will retrigger deferred probe, so it needs to + * be done after calls that might return EPROBE_DEFER, otherwise we can + * get an infinite loop. + */ + ret = devm_of_dp_aux_populate_bus(&platform->aux, anx7625_link_bridge); if (ret) { - if (ret != -EPROBE_DEFER) - DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); - goto free_wq; + if (ret != -ENODEV) { + DRM_DEV_ERROR(dev, "failed to populate aux bus : %d\n", ret); + goto free_wq; + } + + ret = anx7625_link_bridge(&platform->aux); + if (ret) + goto free_wq; } if (!platform->pdata.low_power_mode) { @@ -2666,27 +2741,6 @@ static int anx7625_i2c_probe(struct i2c_client *client) if (platform->pdata.intp_irq) queue_work(platform->workqueue, &platform->work); - platform->bridge.funcs = &anx7625_bridge_funcs; - platform->bridge.of_node = client->dev.of_node; - if (!anx7625_of_panel_on_aux_bus(& |
