OSDN Git Service

drm/aspeed: Use dt matching for default register values
authorJoel Stanley <joel@jms.id.au>
Tue, 9 Feb 2021 12:37:34 +0000 (23:07 +1030)
committerJoel Stanley <joel@jms.id.au>
Wed, 10 Feb 2021 00:26:16 +0000 (10:56 +1030)
There are minor differences in the values for the threshold value and
the scan line size between families of ASPEED SoC. Additionally the SCU
registers for the output control and scratch registers differ between
families.

This adds device tree matching to parameterise these values, allowing us
to add support for the AST2400 now, and in the future the AST2600.

Reviewed-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Link: https://patchwork.freedesktop.org/patch/msgid/20210209123734.130483-3-joel@jms.id.au
drivers/gpu/drm/aspeed/aspeed_gfx.h
drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c

index f1e7e56..9650115 100644 (file)
@@ -11,6 +11,11 @@ struct aspeed_gfx {
        struct reset_control            *rst;
        struct regmap                   *scu;
 
+       u32                             dac_reg;
+       u32                             vga_scratch_reg;
+       u32                             throd_val;
+       u32                             scan_line_max;
+
        struct drm_simple_display_pipe  pipe;
        struct drm_connector            connector;
 };
@@ -100,6 +105,3 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CRT_THROD */
 #define CRT_THROD_LOW(x)               (x)
 #define CRT_THROD_HIGH(x)              ((x) << 8)
-
-/* Default Threshold Seting */
-#define G5_CRT_THROD_VAL       (CRT_THROD_LOW(0x24) | CRT_THROD_HIGH(0x3C))
index e54686c..20c2197 100644 (file)
@@ -59,8 +59,8 @@ static void aspeed_gfx_enable_controller(struct aspeed_gfx *priv)
        u32 ctrl1 = readl(priv->base + CRT_CTRL1);
        u32 ctrl2 = readl(priv->base + CRT_CTRL2);
 
-       /* SCU2C: set DAC source for display output to Graphics CRT (GFX) */
-       regmap_update_bits(priv->scu, 0x2c, BIT(16), BIT(16));
+       /* Set DAC source for display output to Graphics CRT (GFX) */
+       regmap_update_bits(priv->scu, priv->dac_reg, BIT(16), BIT(16));
 
        writel(ctrl1 | CRT_CTRL_EN, priv->base + CRT_CTRL1);
        writel(ctrl2 | CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2);
@@ -74,7 +74,7 @@ static void aspeed_gfx_disable_controller(struct aspeed_gfx *priv)
        writel(ctrl1 & ~CRT_CTRL_EN, priv->base + CRT_CTRL1);
        writel(ctrl2 & ~CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2);
 
-       regmap_update_bits(priv->scu, 0x2c, BIT(16), 0);
+       regmap_update_bits(priv->scu, priv->dac_reg, BIT(16), 0);
 }
 
 static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv)
@@ -127,7 +127,8 @@ static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv)
         * Terminal Count: memory size of one scan line
         */
        d_offset = m->hdisplay * bpp / 8;
-       t_count = (m->hdisplay * bpp + 127) / 128;
+       t_count = DIV_ROUND_UP(m->hdisplay * bpp, priv->scan_line_max);
+
        writel(CRT_DISP_OFFSET(d_offset) | CRT_TERM_COUNT(t_count),
                        priv->base + CRT_OFFSET);
 
@@ -135,7 +136,7 @@ static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv)
         * Threshold: FIFO thresholds of refill and stop (16 byte chunks
         * per line, rounded up)
         */
-       writel(G5_CRT_THROD_VAL, priv->base + CRT_THROD);
+       writel(priv->throd_val, priv->base + CRT_THROD);
 }
 
 static void aspeed_gfx_pipe_enable(struct drm_simple_display_pipe *pipe,
index 54a6bda..6b3a01b 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
  * which is available under NDA from ASPEED.
  */
 
+struct aspeed_gfx_config {
+       u32 dac_reg;            /* DAC register in SCU */
+       u32 vga_scratch_reg;    /* VGA scratch register in SCU */
+       u32 throd_val;          /* Default Threshold Seting */
+       u32 scan_line_max;      /* Max memory size of one scan line */
+};
+
+static const struct aspeed_gfx_config ast2400_config = {
+       .dac_reg = 0x2c,
+       .vga_scratch_reg = 0x50,
+       .throd_val = CRT_THROD_LOW(0x1e) | CRT_THROD_HIGH(0x12),
+       .scan_line_max = 64,
+};
+
+static const struct aspeed_gfx_config ast2500_config = {
+       .dac_reg = 0x2c,
+       .vga_scratch_reg = 0x50,
+       .throd_val = CRT_THROD_LOW(0x24) | CRT_THROD_HIGH(0x3c),
+       .scan_line_max = 128,
+};
+
+static const struct of_device_id aspeed_gfx_match[] = {
+       { .compatible = "aspeed,ast2400-gfx", .data = &ast2400_config },
+       { .compatible = "aspeed,ast2500-gfx", .data = &ast2500_config },
+       { },
+};
+MODULE_DEVICE_TABLE(of, aspeed_gfx_match);
+
 static const struct drm_mode_config_funcs aspeed_gfx_mode_config_funcs = {
        .fb_create              = drm_gem_fb_create,
        .atomic_check           = drm_atomic_helper_check,
@@ -97,13 +126,13 @@ static irqreturn_t aspeed_gfx_irq_handler(int irq, void *data)
        return IRQ_NONE;
 }
 
-
-
 static int aspeed_gfx_load(struct drm_device *drm)
 {
        struct platform_device *pdev = to_platform_device(drm->dev);
        struct aspeed_gfx *priv = to_aspeed_gfx(drm);
        struct device_node *np = pdev->dev.of_node;
+       const struct aspeed_gfx_config *config;
+       const struct of_device_id *match;
        struct resource *res;
        int ret;
 
@@ -112,6 +141,16 @@ static int aspeed_gfx_load(struct drm_device *drm)
        if (IS_ERR(priv->base))
                return PTR_ERR(priv->base);
 
+       match = of_match_device(aspeed_gfx_match, &pdev->dev);
+       if (!match)
+               return -EINVAL;
+       config = match->data;
+
+       priv->dac_reg = config->dac_reg;
+       priv->vga_scratch_reg = config->vga_scratch_reg;
+       priv->throd_val = config->throd_val;
+       priv->scan_line_max = config->scan_line_max;
+
        priv->scu = syscon_regmap_lookup_by_phandle(np, "syscon");
        if (IS_ERR(priv->scu)) {
                priv->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2500-scu");
@@ -206,14 +245,6 @@ static const struct drm_driver aspeed_gfx_driver = {
        .minor = 0,
 };
 
-static const struct of_device_id aspeed_gfx_match[] = {
-       { .compatible = "aspeed,ast2500-gfx" },
-       { }
-};
-
-#define ASPEED_SCU_VGA0                0x50
-#define ASPEED_SCU_MISC_CTRL   0x2c
-
 static ssize_t dac_mux_store(struct device *dev, struct device_attribute *attr,
                             const char *buf, size_t count)
 {
@@ -228,7 +259,7 @@ static ssize_t dac_mux_store(struct device *dev, struct device_attribute *attr,
        if (val > 3)
                return -EINVAL;
 
-       rc = regmap_update_bits(priv->scu, ASPEED_SCU_MISC_CTRL, 0x30000, val << 16);
+       rc = regmap_update_bits(priv->scu, priv->dac_reg, 0x30000, val << 16);
        if (rc < 0)
                return 0;
 
@@ -241,7 +272,7 @@ static ssize_t dac_mux_show(struct device *dev, struct device_attribute *attr, c
        u32 reg;
        int rc;
 
-       rc = regmap_read(priv->scu, ASPEED_SCU_MISC_CTRL, &reg);
+       rc = regmap_read(priv->scu, priv->dac_reg, &reg);
        if (rc)
                return rc;
 
@@ -256,7 +287,7 @@ vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf)
        u32 reg;
        int rc;
 
-       rc = regmap_read(priv->scu, ASPEED_SCU_VGA0, &reg);
+       rc = regmap_read(priv->scu, priv->vga_scratch_reg, &reg);
        if (rc)
                return rc;