@@ -2,6 +2,7 @@
armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
armada_gem.o armada_overlay.o armada_plane.o armada_trace.o
armada-y += armada_510.o
+armada-y += armada_610.o
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
obj-$(CONFIG_DRM_ARMADA) := armada.o
new file mode 100644
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Russell King
+ * Copyright (C) 2018 Lubomir Rintel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Armada MMP2 variant support
+ */
+#include <linux/clk.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_crtc.h>
+#include "armada_crtc.h"
+#include "armada_drm.h"
+
+/*
+ * This gets called with sclk = NULL to test whether the mode is
+ * supportable, and again with sclk != NULL to set the clocks up for
+ * that. The former can return an error, but the latter is expected
+ * not to.
+ */
+static int armada610_crtc_compute_clock(struct armada_crtc *dcrtc,
+ const struct drm_display_mode *mode, uint32_t *sclk)
+{
+ struct clk *clk = dcrtc->axiclk;
+ uint32_t rate, ref, div;
+
+ if (!clk)
+ return -EINVAL;
+
+ rate = mode->clock * 1000;
+ ref = clk_get_rate(clk);
+ div = DIV_ROUND_UP(ref, rate);
+
+ if (div < 2)
+ return -EINVAL;
+
+ if (sclk) {
+ *sclk = 0x00001100; /* No idea */
+ *sclk |= (0x1 << 30); /* SCLK_SOURCE_SELECT = AXI bus clk */
+ *sclk |= div;
+ }
+
+ return 0;
+}
+
+const struct armada_variant armada610_ops = {
+ .compute_clock = armada610_crtc_compute_clock,
+};
@@ -915,6 +915,10 @@ static const struct of_device_id armada_lcd_of_match[] = {
.compatible = "marvell,dove-lcd",
.data = &armada510_ops,
},
+ {
+ .compatible = "marvell,mmp2-lcd",
+ .data = &armada610_ops,
+ },
{}
};
MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
@@ -52,6 +52,7 @@ struct armada_variant {
/* Variant ops */
extern const struct armada_variant armada510_ops;
+extern const struct armada_variant armada610_ops;
struct armada_private {
struct drm_device drm;
@@ -302,6 +302,7 @@ MODULE_DEVICE_TABLE(platform, armada_drm_platform_ids);
static const struct of_device_id armada_drm_dt_ids[] = {
{ .compatible = "marvell,dove-display-subsystem", },
+ { .compatible = "marvell,mmp2-display-subsystem", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, armada_drm_dt_ids);
@@ -45,5 +45,7 @@ static int __init armada_rmem_init(struct reserved_mem *rmem)
return 0;
}
-RESERVEDMEM_OF_DECLARE(armada_rmem, "marvell,dove-framebuffer",
+RESERVEDMEM_OF_DECLARE(armada_dove_rmem, "marvell,dove-framebuffer",
+ armada_rmem_init);
+RESERVEDMEM_OF_DECLARE(armada_mmp2_rmem, "marvell,mmp2-framebuffer",
armada_rmem_init);
This pretty much boils down to setting the LCD_CFG_SCLK_DIV register, and is tailored to the OLPC XO-1.75. I have no idea what are the meanings of most bits there, so I'm just making sure it ends up being 0x40001102. This means that the selection of the source clock is hardwired. Apparently the bit 30 selects the AXI bus clock as base clock for the pixel clock. It is not known to me what other options are there. Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> --- Notes; perhaps James or someone else with a datasheet could help me with this. I'm somewhat confused about the clock selection. The firmware contains this line: h# 00000700 value pmua-disp-clk-sel \ PLL1 / 7 -> 113.86 MHz However, the Linux clock driver seems to consider the value of 7 to configure the divisor to 8, so the resulting clock would end up being 100 MHz. Also, the clk-of-mmp2 driver suggests PLL1 outputs 800 MHz, dividing that by 7 would end up being 114.29 MHz, not 113.86 MHz. If the same logic was used here as Armada 510 driver uses, we'll end up with the divisor of 1 in LCD_CFG_SCLK_DIV and disp0_div divisor of 16. Would that be good also? (Do perhaps any of the bits in LCD_CFG_SCLK_DIV allow for a fractional divisor, allowing us to get the clock we need more precisely?) The pxa168fb driver as used on the stock OLPC software just avoids touching the register, preserving the value set from the firmware. --- drivers/gpu/drm/armada/Makefile | 1 + drivers/gpu/drm/armada/armada_610.c | 50 ++++++++++++++++++++++++++++ drivers/gpu/drm/armada/armada_crtc.c | 4 +++ drivers/gpu/drm/armada/armada_drm.h | 1 + drivers/gpu/drm/armada/armada_drv.c | 1 + drivers/gpu/drm/armada/armada_rmem.c | 4 ++- 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/armada/armada_610.c