From 39a5019a2c13580f21efc756babccb4c03b6a8ce Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 19 Oct 2016 17:32:20 -0700 Subject: [PATCH 1/6] drm/fsl-dcu: unload driver before disabling clocks Use drm_put_dev to unload the driver before disabling clocks. Otherwise the driver might read a register during unload which leads to an external abort. Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 0b0d1cb11641..30c46a80a540 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -428,9 +428,9 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev) { struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev); + drm_put_dev(fsl_dev->drm); clk_disable_unprepare(fsl_dev->clk); clk_unregister(fsl_dev->pix_clk); - drm_put_dev(fsl_dev->drm); return 0; } From 39c74b515bc2172597f6a85c7310cbf348d66a82 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 19 Oct 2016 17:32:21 -0700 Subject: [PATCH 2/6] drm/fsl-dcu: disable outputs before unloading driver Make sure that all outputs are disabled before unloading the DRM driver. Otherwise vblank handling is not shut down properly and warnings such as this appear: WARNING: CPU: 0 PID: 540 at drivers/gpu/drm/drm_irq.c:339 drm_vblank_cleanup+0x5c/0x94 Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 30c46a80a540..f8313f2b113a 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -108,6 +108,7 @@ static int fsl_dcu_unload(struct drm_device *dev) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; + drm_crtc_force_disable_all(dev); drm_kms_helper_poll_fini(dev); if (fsl_dev->fbdev) From 54ac0a0f72cdf66634c1321addd32eaadb0f022d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 16 Nov 2016 13:38:32 -0200 Subject: [PATCH 3/6] drm/fsl-dcu: Remove unneeded NULL check devm_ioremap_resource() performs NULL check for the 'res' argument, so remove the unneeded check. Signed-off-by: Fabio Estevam Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index f8313f2b113a..2ecbb4942b80 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -337,11 +337,6 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) fsl_dev->soc = id->data; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "could not get memory IO resource\n"); - return -ENODEV; - } - base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) { ret = PTR_ERR(base); From 238e4f44c05644089968fbd1a701a6be58ddb546 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 16 Nov 2016 13:38:33 -0200 Subject: [PATCH 4/6] drm/fsl-dcu: Propagate the real error code In case of platform_get_irq() failure, let's propagate the real error code, instead of a 'fake' one. Signed-off-by: Fabio Estevam Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 2ecbb4942b80..f242e64c76ca 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -346,7 +346,7 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) fsl_dev->irq = platform_get_irq(pdev, 0); if (fsl_dev->irq < 0) { dev_err(dev, "failed to get irq\n"); - return -ENXIO; + return fsl_dev->irq; } fsl_dev->regmap = devm_regmap_init_mmio(dev, base, From c162215f570567b3a264d8e1abb50971d78bbaf3 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 16 Nov 2016 17:14:06 -0800 Subject: [PATCH 5/6] drm/fsl-dcu: remove separate compilation unit for fbdev emulation The separate file fsl_dcu_drm_fbdev.c only initialized fbdev emulation which is a one-line operation. There is not much more code on sight which justifies a separate file, hence call the initialization helper directly from the drv file. Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/Makefile | 1 - drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 1 - drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c | 23 --------------------- 4 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile index b35a292287f3..aca34f656bea 100644 --- a/drivers/gpu/drm/fsl-dcu/Makefile +++ b/drivers/gpu/drm/fsl-dcu/Makefile @@ -3,6 +3,5 @@ fsl-dcu-drm-y := fsl_dcu_drm_drv.o \ fsl_dcu_drm_rgb.o \ fsl_dcu_drm_plane.o \ fsl_dcu_drm_crtc.o \ - fsl_dcu_drm_fbdev.o \ fsl_tcon.o obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu-drm.o diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index f242e64c76ca..736451616ce4 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -87,7 +87,7 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) goto done; dev->irq_enabled = true; - fsl_dcu_fbdev_init(dev); + fsl_dev->fbdev = drm_fbdev_cma_init(dev, 24, 1, 1); return 0; done: diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h index 3b371fe7491e..e9e9aeecf2eb 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h @@ -197,7 +197,6 @@ struct fsl_dcu_drm_device { struct drm_atomic_state *state; }; -void fsl_dcu_fbdev_init(struct drm_device *dev); int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev); #endif /* __FSL_DCU_DRM_DRV_H__ */ diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c deleted file mode 100644 index 8b8b819ea704..000000000000 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2015 Freescale Semiconductor, Inc. - * - * Freescale DCU drm device driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include - -#include "fsl_dcu_drm_drv.h" - -/* initialize fbdev helper */ -void fsl_dcu_fbdev_init(struct drm_device *dev) -{ - struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev->dev); - - fsl_dev->fbdev = drm_fbdev_cma_init(dev, 24, 1, 1); -} From 73fe26a48659abd2b85d2f87d3cf2400ddb313d7 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 16 Nov 2016 17:23:27 -0800 Subject: [PATCH 6/6] drm/fsl-dcu: introduce kernel parameter to specify fbdev depth Add a kernel parameter legancyfb_depth (like the i.MX drm driver) to control the legancy fbdev depth. Default to the so far hard coded depth of 24-bit. Currently changing the framebuffer depth is not possible from user space when using the fbdev emulation layer... This provides a rudimentary mechanism to change depth without having to change kernel code. Signed-off-by: Stefan Agner --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 736451616ce4..58ccacaf5a4e 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -32,6 +32,9 @@ #include "fsl_dcu_drm_drv.h" #include "fsl_tcon.h" +static int legacyfb_depth = 24; +module_param(legacyfb_depth, int, 0444); + static bool fsl_dcu_drm_is_volatile_reg(struct device *dev, unsigned int reg) { if (reg == DCU_INT_STATUS || reg == DCU_UPDATE_MODE) @@ -87,7 +90,18 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) goto done; dev->irq_enabled = true; - fsl_dev->fbdev = drm_fbdev_cma_init(dev, 24, 1, 1); + if (legacyfb_depth != 16 && legacyfb_depth != 24 && + legacyfb_depth != 32) { + dev_warn(dev->dev, + "Invalid legacyfb_depth. Defaulting to 24bpp\n"); + legacyfb_depth = 24; + } + fsl_dev->fbdev = drm_fbdev_cma_init(dev, legacyfb_depth, 1, 1); + if (IS_ERR(fsl_dev->fbdev)) { + ret = PTR_ERR(fsl_dev->fbdev); + fsl_dev->fbdev = NULL; + goto done; + } return 0; done: