Commit 42e62ba7 authored by Russell King's avatar Russell King

drm/armada: make variant a CRTC thing

Move the variant pointer into the armada_crtc structure, and update for
the resulting changes.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 3ecea269
...@@ -79,6 +79,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc, ...@@ -79,6 +79,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
const struct armada_variant armada510_ops = { const struct armada_variant armada510_ops = {
.has_spu_adv_reg = true, .has_spu_adv_reg = true,
.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND, .spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
.crtc_init = armada510_crtc_init, .init = armada510_crtc_init,
.crtc_compute_clock = armada510_crtc_compute_clock, .compute_clock = armada510_crtc_compute_clock,
}; };
...@@ -332,17 +332,16 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc) ...@@ -332,17 +332,16 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc, static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode, struct drm_display_mode *adj) const struct drm_display_mode *mode, struct drm_display_mode *adj)
{ {
struct armada_private *priv = crtc->dev->dev_private;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
int ret; int ret;
/* We can't do interlaced modes if we don't have the SPU_ADV_REG */ /* We can't do interlaced modes if we don't have the SPU_ADV_REG */
if (!priv->variant->has_spu_adv_reg && if (!dcrtc->variant->has_spu_adv_reg &&
adj->flags & DRM_MODE_FLAG_INTERLACE) adj->flags & DRM_MODE_FLAG_INTERLACE)
return false; return false;
/* Check whether the display mode is possible */ /* Check whether the display mode is possible */
ret = priv->variant->crtc_compute_clock(dcrtc, adj, NULL); ret = dcrtc->variant->compute_clock(dcrtc, adj, NULL);
if (ret) if (ret)
return false; return false;
...@@ -491,7 +490,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, ...@@ -491,7 +490,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode, struct drm_display_mode *adj, struct drm_display_mode *mode, struct drm_display_mode *adj,
int x, int y, struct drm_framebuffer *old_fb) int x, int y, struct drm_framebuffer *old_fb)
{ {
struct armada_private *priv = crtc->dev->dev_private;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_regs regs[17]; struct armada_regs regs[17];
uint32_t lm, rm, tm, bm, val, sclk; uint32_t lm, rm, tm, bm, val, sclk;
...@@ -536,7 +534,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, ...@@ -536,7 +534,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
} }
/* Now compute the divider for real */ /* Now compute the divider for real */
priv->variant->crtc_compute_clock(dcrtc, adj, &sclk); dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
/* Ensure graphic fifo is enabled */ /* Ensure graphic fifo is enabled */
armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1); armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
...@@ -558,7 +556,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, ...@@ -558,7 +556,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
dcrtc->v[1].spu_v_porch = tm << 16 | bm; dcrtc->v[1].spu_v_porch = tm << 16 | bm;
val = adj->crtc_hsync_start; val = adj->crtc_hsync_start;
dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN | dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
priv->variant->spu_adv_reg; dcrtc->variant->spu_adv_reg;
if (interlaced) { if (interlaced) {
/* Odd interlaced frame */ /* Odd interlaced frame */
...@@ -567,7 +565,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, ...@@ -567,7 +565,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1; dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
val = adj->crtc_hsync_start - adj->crtc_htotal / 2; val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN | dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
priv->variant->spu_adv_reg; dcrtc->variant->spu_adv_reg;
} else { } else {
dcrtc->v[0] = dcrtc->v[1]; dcrtc->v[0] = dcrtc->v[1];
} }
...@@ -582,7 +580,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, ...@@ -582,7 +580,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total, armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
LCD_SPUT_V_H_TOTAL); LCD_SPUT_V_H_TOTAL);
if (priv->variant->has_spu_adv_reg) { if (dcrtc->variant->has_spu_adv_reg) {
armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg, armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF | ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
ADV_VSYNCOFFEN, LCD_SPU_ADV_REG); ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
...@@ -826,12 +824,11 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -826,12 +824,11 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_private *priv = crtc->dev->dev_private;
struct armada_gem_object *obj = NULL; struct armada_gem_object *obj = NULL;
int ret; int ret;
/* If no cursor support, replicate drm's return value */ /* If no cursor support, replicate drm's return value */
if (!priv->variant->has_spu_adv_reg) if (!dcrtc->variant->has_spu_adv_reg)
return -ENXIO; return -ENXIO;
if (handle && w > 0 && h > 0) { if (handle && w > 0 && h > 0) {
...@@ -879,11 +876,10 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) ...@@ -879,11 +876,10 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_private *priv = crtc->dev->dev_private;
int ret; int ret;
/* If no cursor support, replicate drm's return value */ /* If no cursor support, replicate drm's return value */
if (!priv->variant->has_spu_adv_reg) if (!dcrtc->variant->has_spu_adv_reg)
return -EFAULT; return -EFAULT;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
...@@ -1051,7 +1047,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev) ...@@ -1051,7 +1047,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
} }
int armada_drm_crtc_create(struct drm_device *dev, struct resource *res, int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
int irq) int irq, const struct armada_variant *variant)
{ {
struct armada_private *priv = dev->dev_private; struct armada_private *priv = dev->dev_private;
struct armada_crtc *dcrtc; struct armada_crtc *dcrtc;
...@@ -1074,6 +1070,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res, ...@@ -1074,6 +1070,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
return -ENOMEM; return -ENOMEM;
} }
dcrtc->variant = variant;
dcrtc->base = base; dcrtc->base = base;
dcrtc->num = dev->mode_config.num_crtc; dcrtc->num = dev->mode_config.num_crtc;
dcrtc->clk = ERR_PTR(-EINVAL); dcrtc->clk = ERR_PTR(-EINVAL);
...@@ -1107,8 +1104,8 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res, ...@@ -1107,8 +1104,8 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
return ret; return ret;
} }
if (priv->variant->crtc_init) { if (dcrtc->variant->init) {
ret = priv->variant->crtc_init(dcrtc, dev->dev); ret = dcrtc->variant->init(dcrtc, dev->dev);
if (ret) { if (ret) {
kfree(dcrtc); kfree(dcrtc);
return ret; return ret;
......
...@@ -32,9 +32,11 @@ struct armada_regs { ...@@ -32,9 +32,11 @@ struct armada_regs {
armada_reg_queue_mod(_r, _i, 0, 0, ~0) armada_reg_queue_mod(_r, _i, 0, 0, ~0)
struct armada_frame_work; struct armada_frame_work;
struct armada_variant;
struct armada_crtc { struct armada_crtc {
struct drm_crtc crtc; struct drm_crtc crtc;
const struct armada_variant *variant;
unsigned num; unsigned num;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
...@@ -73,7 +75,8 @@ struct armada_crtc { ...@@ -73,7 +75,8 @@ struct armada_crtc {
}; };
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc) #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
int armada_drm_crtc_create(struct drm_device *, struct resource *, int); int armada_drm_crtc_create(struct drm_device *, struct resource *, int,
const struct armada_variant *);
void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int); void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int); void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
void armada_drm_crtc_disable_irq(struct armada_crtc *, u32); void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
......
...@@ -61,17 +61,16 @@ struct armada_private; ...@@ -61,17 +61,16 @@ struct armada_private;
struct armada_variant { struct armada_variant {
bool has_spu_adv_reg; bool has_spu_adv_reg;
uint32_t spu_adv_reg; uint32_t spu_adv_reg;
int (*crtc_init)(struct armada_crtc *, struct device *); int (*init)(struct armada_crtc *, struct device *);
int (*crtc_compute_clock)(struct armada_crtc *, int (*compute_clock)(struct armada_crtc *,
const struct drm_display_mode *, const struct drm_display_mode *,
uint32_t *); uint32_t *);
}; };
/* Variant ops */ /* Variant ops */
extern const struct armada_variant armada510_ops; extern const struct armada_variant armada510_ops;
struct armada_private { struct armada_private {
const struct armada_variant *variant;
struct work_struct fb_unref_work; struct work_struct fb_unref_work;
DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
struct drm_fb_helper *fbdev; struct drm_fb_helper *fbdev;
......
...@@ -85,6 +85,7 @@ void armada_drm_queue_unref_work(struct drm_device *dev, ...@@ -85,6 +85,7 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
static int armada_drm_load(struct drm_device *dev, unsigned long flags) static int armada_drm_load(struct drm_device *dev, unsigned long flags)
{ {
const struct platform_device_id *id; const struct platform_device_id *id;
const struct armada_variant *variant;
struct armada_private *priv; struct armada_private *priv;
struct resource *res[ARRAY_SIZE(priv->dcrtc)]; struct resource *res[ARRAY_SIZE(priv->dcrtc)];
struct resource *mem = NULL; struct resource *mem = NULL;
...@@ -128,7 +129,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -128,7 +129,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (!id) if (!id)
return -ENXIO; return -ENXIO;
priv->variant = (struct armada_variant *)id->driver_data; variant = (const struct armada_variant *)id->driver_data;
INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
INIT_KFIFO(priv->fb_unref); INIT_KFIFO(priv->fb_unref);
...@@ -160,7 +161,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -160,7 +161,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (irq < 0) if (irq < 0)
goto err_kms; goto err_kms;
ret = armada_drm_crtc_create(dev, res[n], irq); ret = armada_drm_crtc_create(dev, res[n], irq, variant);
if (ret) if (ret)
goto err_kms; goto err_kms;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment