diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-08-15 08:59:49 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-10-12 05:13:40 -0400 |
| commit | 96f60e37dc66091bde8d5de136ff6fda09f2d799 (patch) | |
| tree | 2c2cc30a5ac7339730430369e27d33d4a8dd21ef /drivers/gpu | |
| parent | 15c03dd4859ab16f9212238f29dd315654aa94f6 (diff) | |
DRM: Armada: Add Armada DRM driver
This patch adds support for the pair of LCD controllers on the Marvell
Armada 510 SoCs. This driver supports:
- multiple contiguous scanout buffers for video and graphics
- shm backed cacheable buffer objects for X pixmaps for Vivante GPU
acceleration
- dual lcd0 and lcd1 crt operation
- video overlay on each LCD crt via DRM planes
- page flipping of the main scanout buffers
- DRM prime for buffer export/import
This driver is trivial to extend to other Armada SoCs.
Included in this commit is the core driver with no output support; output
support is platform and encoder driver dependent.
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/gpu')
22 files changed, 3953 insertions, 0 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 955555d6ec88..3b5176dd1c86 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
| @@ -225,6 +225,8 @@ source "drivers/gpu/drm/mgag200/Kconfig" | |||
| 225 | 225 | ||
| 226 | source "drivers/gpu/drm/cirrus/Kconfig" | 226 | source "drivers/gpu/drm/cirrus/Kconfig" |
| 227 | 227 | ||
| 228 | source "drivers/gpu/drm/armada/Kconfig" | ||
| 229 | |||
| 228 | source "drivers/gpu/drm/rcar-du/Kconfig" | 230 | source "drivers/gpu/drm/rcar-du/Kconfig" |
| 229 | 231 | ||
| 230 | source "drivers/gpu/drm/shmobile/Kconfig" | 232 | source "drivers/gpu/drm/shmobile/Kconfig" |
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index f089adfe70ee..385f460459d4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
| @@ -49,6 +49,7 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ | |||
| 49 | obj-$(CONFIG_DRM_GMA500) += gma500/ | 49 | obj-$(CONFIG_DRM_GMA500) += gma500/ |
| 50 | obj-$(CONFIG_DRM_UDL) += udl/ | 50 | obj-$(CONFIG_DRM_UDL) += udl/ |
| 51 | obj-$(CONFIG_DRM_AST) += ast/ | 51 | obj-$(CONFIG_DRM_AST) += ast/ |
| 52 | obj-$(CONFIG_DRM_ARMADA) += armada/ | ||
| 52 | obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ | 53 | obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ |
| 53 | obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ | 54 | obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ |
| 54 | obj-$(CONFIG_DRM_OMAP) += omapdrm/ | 55 | obj-$(CONFIG_DRM_OMAP) += omapdrm/ |
diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig new file mode 100644 index 000000000000..c7a0a944acfe --- /dev/null +++ b/drivers/gpu/drm/armada/Kconfig | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | config DRM_ARMADA | ||
| 2 | tristate "DRM support for Marvell Armada SoCs" | ||
| 3 | depends on DRM && HAVE_CLK | ||
| 4 | select FB_CFB_FILLRECT | ||
| 5 | select FB_CFB_COPYAREA | ||
| 6 | select FB_CFB_IMAGEBLIT | ||
| 7 | select DRM_KMS_HELPER | ||
| 8 | help | ||
| 9 | Support the "LCD" controllers found on the Marvell Armada 510 | ||
| 10 | devices. There are two controllers on the device, each controller | ||
| 11 | supports graphics and video overlays. | ||
| 12 | |||
| 13 | This driver provides no built-in acceleration; acceleration is | ||
| 14 | performed by other IP found on the SoC. This driver provides | ||
| 15 | kernel mode setting and buffer management to userspace. | ||
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile new file mode 100644 index 000000000000..d6f43e06150a --- /dev/null +++ b/drivers/gpu/drm/armada/Makefile | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ | ||
| 2 | armada_gem.o armada_output.o armada_overlay.o \ | ||
| 3 | armada_slave.o | ||
| 4 | armada-y += armada_510.o | ||
| 5 | armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o | ||
| 6 | |||
| 7 | obj-$(CONFIG_DRM_ARMADA) := armada.o | ||
diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c new file mode 100644 index 000000000000..a016888acd29 --- /dev/null +++ b/drivers/gpu/drm/armada/armada_510.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Russell King | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * Armada 510 (aka Dove) variant support | ||
| 9 | */ | ||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/io.h> | ||
| 12 | #include <drm/drmP.h> | ||
| 13 | #include <drm/drm_crtc_helper.h> | ||
| 14 | #include "armada_crtc.h" | ||
| 15 | #include "armada_drm.h" | ||
| 16 | #include "armada_hw.h" | ||
| 17 | |||
| 18 | static int armada510_init(struct armada_private *priv, struct device *dev) | ||
| 19 | { | ||
| 20 | priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1"); | ||
| 21 | |||
| 22 | if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT) | ||
| 23 | priv->extclk[0] = ERR_PTR(-EPROBE_DEFER); | ||
| 24 | |||
| 25 | return PTR_RET(priv->extclk[0]); | ||
| 26 | } | ||
| 27 | |||
| 28 | static int armada510_crtc_init(struct armada_crtc *dcrtc) | ||
| 29 | { | ||
| 30 | /* Lower the watermark so to eliminate jitter at higher bandwidths */ | ||
| 31 | armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F); | ||
| 32 | return 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Armada510 specific SCLK register selection. | ||
| 37 | * This gets called with sclk = NULL to test whether the mode is | ||
| 38 | * supportable, and again with sclk != NULL to set the clocks up for | ||
| 39 | * that. The former can return an error, but the latter is expected | ||
| 40 | * not to. | ||
| 41 | * | ||
| 42 | * We currently are pretty rudimentary here, always selecting | ||
| 43 | * EXT_REF_CLK_1 for LCD0 and erroring LCD1. This needs improvement! | ||
| 44 | */ | ||
| 45 | static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc, | ||
| 46 | const struct drm_display_mode *mode, uint32_t *sclk) | ||
| 47 | { | ||
| 48 | struct armada_private *priv = dcrtc->crtc.dev->dev_private; | ||
| 49 | struct clk *clk = priv->extclk[0]; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | if (dcrtc->num == 1) | ||
| 53 | return -EINVAL; | ||
| 54 | |||
| 55 | if (IS_ERR(clk)) | ||
| 56 | return PTR_ERR(clk); | ||
| 57 | |||
| 58 | if (dcrtc->clk != clk) { | ||
| 59 | ret = clk_prepare_enable(clk); | ||
| 60 | if (ret) | ||
| 61 | return ret; | ||
| 62 | dcrtc->clk = clk; | ||
| 63 | } | ||
| 64 | |||
| 65 | if (sclk) { | ||
| 66 | uint32_t rate, ref, div; | ||
| 67 | |||
| 68 | rate = mode->clock * 1000; | ||
| 69 | ref = clk_round_rate(clk, rate); | ||
| 70 | div = DIV_ROUND_UP(ref, rate); | ||
| 71 | if (div < 1) | ||
| 72 | div = 1; | ||
| 73 | |||
| 74 | clk_set_rate(clk, ref); | ||
| 75 | *sclk = div | SCLK_510_EXTCLK1; | ||
| 76 | } | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | const struct armada_variant armada510_ops = { | ||
| 82 | .has_spu_adv_reg = true, | ||
| 83 | .init = armada510_init, | ||
| 84 | .crtc_init = armada510_crtc_init, | ||
| 85 | .crtc_compute_clock = armada510_crtc_compute_clock, | ||
| 86 | }; | ||
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c new file mode 100644 index 000000000000..7b379fdb4e8c --- /dev/null +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -0,0 +1,861 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 Russell King | ||
| 3 | * Rewritten from the dovefb driver, and Armada510 manuals. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | #include <linux/clk.h> | ||
| 10 | #include <drm/drmP.h> | ||
| 11 | #include <drm/drm_crtc_helper.h> | ||
| 12 | #include "armada_crtc.h" | ||
| 13 | #include "armada_drm.h" | ||
| 14 | #include "armada_fb.h" | ||
| 15 | #include "armada_gem.h" | ||
