# Base git commit: ffc253263a13 # (Linux 6.6) # # Author: Russell King (Sun 24 Jun 14:05:12 BST 2018) # Committer: Russell King (Oracle) (Mon 30 Oct 13:26:29 GMT 2023) # # ARM: dts: cubox: add LCD controller and TDA998x configuration # # Add DT configuration for the HDMI display output on the Dove Cubox. # This adds support for the LCD0 controller which is connected to a # TDA19988 HDMI encoder. # # Signed-off-by: Russell King # # c6962139fc748aa528250f5283fc70ba27ca9e65 # arch/arm/boot/dts/marvell/dove-cubox.dts | 37 ++++++++++++++++++++++++++++++++ # arch/arm/boot/dts/marvell/dove.dtsi | 4 ++-- # 2 files changed, 39 insertions(+), 2 deletions(-) # # Author: Russell King (Sun 24 Jun 14:03:31 BST 2018) # Committer: Russell King (Oracle) (Mon 30 Oct 13:21:46 GMT 2023) # # drm/armada: add detection of DT LCD controllers for probing # # Using a virtual device is deprecated, so we have no option but to # detect the presence of available LCD controllers in DT and probe # all LCD controllers together within one DRM device. # # Signed-off-by: Russell King # # 3408ef26a44402a64475c498fb65ace792a3306d # drivers/gpu/drm/armada/armada_drv.c | 52 ++++++++++++++++++++++++++++++++----- # 1 file changed, 45 insertions(+), 7 deletions(-) # # Author: Russell King (Sun 24 Jun 14:03:31 BST 2018) # Committer: Russell King (Oracle) (Mon 30 Oct 13:21:43 GMT 2023) # # drm/armada: add reserved memory support # # Existing Armada DRM makes use of reserved memory for allocating # contiguous screen buffers, which currently prevents its use with # DT systems. Add support for this for DT systems. # # Signed-off-by: Russell King # # 87125ba103873bbdeb0e0f08d10ce8e1daf1709a # drivers/gpu/drm/armada/armada_drv.c | 52 ++++++++++++++++++++++++++++++++----- # 1 file changed, 46 insertions(+), 6 deletions(-) # diff --git a/arch/arm/boot/dts/marvell/dove-cubox.dts b/arch/arm/boot/dts/marvell/dove-cubox.dts index bfde99486a87..9ef4dcb58e3c 100644 --- a/arch/arm/boot/dts/marvell/dove-cubox.dts +++ b/arch/arm/boot/dts/marvell/dove-cubox.dts @@ -60,6 +60,19 @@ ir_recv: ir-receiver { gpu-subsystem { status = "okay"; }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer { + compatible = "marvell,armada-framebuffer"; + size = <0x02000000>; + alignment = <0x02000000>; + no-map; + }; + }; }; &uart0 { status = "okay"; }; @@ -117,6 +130,30 @@ clkout2 { silabs,pll-master; }; }; + + tda998x: hdmi-encoder@70 { + compatible = "nxp,tda998x"; + reg = <0x70>; + video-ports = <0x234501>; + interrupts-extended = <&gpio0 27 IRQ_TYPE_LEVEL_LOW>; + + port { + tda998x_video: endpoint { + remote-endpoint = <&lcd0_rgb>; + }; + }; + }; +}; + +&lcd0 { + status = "okay"; + clocks = <&si5351 0>; + clock-names = "ext_ref_clk1"; + lcd0_port: port { + lcd0_rgb: endpoint { + remote-endpoint = <&tda998x_video>; + }; + }; }; &sdio0 { diff --git a/arch/arm/boot/dts/marvell/dove.dtsi b/arch/arm/boot/dts/marvell/dove.dtsi index 062c86361640..b0865d28a646 100644 --- a/arch/arm/boot/dts/marvell/dove.dtsi +++ b/arch/arm/boot/dts/marvell/dove.dtsi @@ -785,14 +785,14 @@ gpio2: gpio-ctrl@e8400 { }; lcd1: lcd-controller@810000 { - compatible = "marvell,dove-lcd"; + compatible = "marvell,dove-lcd", "marvell,armada-lcdc"; reg = <0x810000 0x1000>; interrupts = <46>; status = "disabled"; }; lcd0: lcd-controller@820000 { - compatible = "marvell,dove-lcd"; + compatible = "marvell,dove-lcd", "marvell,armada-lcdc"; reg = <0x820000 0x1000>; interrupts = <47>; status = "disabled"; diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index e8d2fe955909..ad3393f2c813 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -56,11 +57,40 @@ static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = { .atomic_commit = drm_atomic_helper_commit, }; -static int armada_drm_bind(struct device *dev) +static struct reserved_mem *armada_drm_get_rmem(struct device *dev, + const char *compatible) +{ + struct device_node *np; + struct reserved_mem *rmem; + + np = of_find_compatible_node(NULL, NULL, compatible); + if (!np) + return NULL; + + rmem = of_reserved_mem_lookup(np); + of_node_put(np); + + return rmem; +} + +static struct resource *armada_drm_get_mem(struct device *dev) { - struct armada_private *priv; struct resource *mem = NULL; - int ret, n; + struct reserved_mem *rmem; + int n; + + rmem = armada_drm_get_rmem(dev, "marvell,armada-framebuffer"); + if (rmem) { + mem = devm_kzalloc(dev, sizeof(*mem), GFP_KERNEL); + if (!mem) + return ERR_PTR(-ENOMEM); + + mem->start = rmem->base; + mem->end = rmem->base + rmem->size - 1; + mem->flags = IORESOURCE_MEM; + + return mem; + } for (n = 0; ; n++) { struct resource *r = platform_get_resource(to_platform_device(dev), @@ -72,11 +102,21 @@ static int armada_drm_bind(struct device *dev) if (resource_size(r) > SZ_64K) mem = r; else - return -EINVAL; + return ERR_PTR(-EINVAL); } - if (!mem) - return -ENXIO; + return mem ? : ERR_PTR(-ENXIO); +} + +static int armada_drm_bind(struct device *dev) +{ + struct armada_private *priv; + struct resource *mem; + int ret; + + mem = armada_drm_get_mem(dev); + if (IS_ERR(mem)) + return PTR_ERR(mem); if (!devm_request_mem_region(dev, mem->start, resource_size(mem), "armada-drm")) @@ -191,11 +231,6 @@ static int armada_drm_probe(struct platform_device *pdev) { struct component_match *match = NULL; struct device *dev = &pdev->dev; - int ret; - - ret = drm_of_component_probe(dev, component_compare_dev_name, &armada_master_ops); - if (ret != -EINVAL) - return ret; if (dev->platform_data) { char **devices = dev->platform_data; @@ -218,6 +253,22 @@ static int armada_drm_probe(struct platform_device *pdev) armada_add_endpoints(dev, &match, d->of_node); put_device(d); } + } else { + struct device_node *np; + + for_each_compatible_node(np, NULL, "marvell,armada-lcdc") { + if (!of_device_is_available(np)) + continue; + + drm_of_component_match_add(dev, &match, component_compare_of, np); + } + + for_each_compatible_node(np, NULL, "marvell,armada-lcdc") { + if (!of_device_is_available(np)) + continue; + + armada_add_endpoints(dev, &match, np); + } } return component_master_add_with_match(&pdev->dev, &armada_master_ops, @@ -249,8 +300,11 @@ static struct platform_driver armada_drm_platform_driver = { .id_table = armada_drm_platform_ids, }; +static struct platform_device *armada_device; + static int __init armada_drm_init(void) { + struct device_node *np; int ret; if (drm_firmware_drivers_only()) @@ -258,16 +312,40 @@ static int __init armada_drm_init(void) ret = platform_driver_register(&armada_lcd_platform_driver); if (ret) - return ret; + goto err_lcd; + ret = platform_driver_register(&armada_drm_platform_driver); if (ret) - platform_driver_unregister(&armada_lcd_platform_driver); + goto err_drm; + + for_each_compatible_node(np, NULL, "marvell,armada-lcdc") { + if (!of_device_is_available(np)) + continue; + + of_node_put(np); + armada_device = platform_device_register_simple( + "armada-drm", -1, NULL, 0); + if (IS_ERR(armada_device)) { + ret = PTR_ERR(armada_device); + goto err_dev; + } + break; + } + return 0; + + err_dev: + platform_driver_unregister(&armada_drm_platform_driver); + err_drm: + platform_driver_unregister(&armada_lcd_platform_driver); + err_lcd: return ret; } module_init(armada_drm_init); static void __exit armada_drm_exit(void) { + if (armada_device) + platform_device_unregister(armada_device); platform_driver_unregister(&armada_drm_platform_driver); platform_driver_unregister(&armada_lcd_platform_driver); }