Commit a6993b21 authored by Liviu Dudau's avatar Liviu Dudau

drm: mali-dp: Separate static internal data into a read-only structure.

The malidp_hw_device structure that the driver uses to handle the
differences between versions of the IP contains both non-changeable
data and fields that get updated at probe time. Previously we were
copying the read-only part into allocated memory, but that can be
completely avoided by splitting the structure into a read-only part
and keeping the runtime modifiable fields into the old structure.
Reviewed-by: default avatarBrian Starkey <brian.starkey@arm.com>
Reviewed-by: default avatarGustavo Padovan <gustavo.padovan@collabora.com>
Signed-off-by: default avatarLiviu Dudau <liviu.dudau@arm.com>
parent 0970d7a2
...@@ -65,8 +65,8 @@ static void malidp_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -65,8 +65,8 @@ static void malidp_crtc_atomic_enable(struct drm_crtc *crtc,
/* We rely on firmware to set mclk to a sensible level. */ /* We rely on firmware to set mclk to a sensible level. */
clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000); clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000);
hwdev->modeset(hwdev, &vm); hwdev->hw->modeset(hwdev, &vm);
hwdev->leave_config_mode(hwdev); hwdev->hw->leave_config_mode(hwdev);
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
} }
...@@ -78,7 +78,8 @@ static void malidp_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -78,7 +78,8 @@ static void malidp_crtc_atomic_disable(struct drm_crtc *crtc,
int err; int err;
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
hwdev->enter_config_mode(hwdev); hwdev->hw->enter_config_mode(hwdev);
clk_disable_unprepare(hwdev->pxlclk); clk_disable_unprepare(hwdev->pxlclk);
err = pm_runtime_put(crtc->dev->dev); err = pm_runtime_put(crtc->dev->dev);
...@@ -319,7 +320,7 @@ static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc, ...@@ -319,7 +320,7 @@ static int malidp_crtc_atomic_check_scaling(struct drm_crtc *crtc,
mclk_calc: mclk_calc:
drm_display_mode_to_videomode(&state->adjusted_mode, &vm); drm_display_mode_to_videomode(&state->adjusted_mode, &vm);
ret = hwdev->se_calc_mclk(hwdev, s, &vm); ret = hwdev->hw->se_calc_mclk(hwdev, s, &vm);
if (ret < 0) if (ret < 0)
return -EINVAL; return -EINVAL;
return 0; return 0;
...@@ -475,7 +476,7 @@ static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) ...@@ -475,7 +476,7 @@ static int malidp_crtc_enable_vblank(struct drm_crtc *crtc)
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK, malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK,
hwdev->map.de_irq_map.vsync_irq); hwdev->hw->map.de_irq_map.vsync_irq);
return 0; return 0;
} }
...@@ -485,7 +486,7 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc) ...@@ -485,7 +486,7 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc)
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK, malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK,
hwdev->map.de_irq_map.vsync_irq); hwdev->hw->map.de_irq_map.vsync_irq);
} }
static const struct drm_crtc_funcs malidp_crtc_funcs = { static const struct drm_crtc_funcs malidp_crtc_funcs = {
......
...@@ -47,10 +47,10 @@ static void malidp_write_gamma_table(struct malidp_hw_device *hwdev, ...@@ -47,10 +47,10 @@ static void malidp_write_gamma_table(struct malidp_hw_device *hwdev,
* directly. * directly.
*/ */
malidp_hw_write(hwdev, gamma_write_mask, malidp_hw_write(hwdev, gamma_write_mask,
hwdev->map.coeffs_base + MALIDP_COEF_TABLE_ADDR); hwdev->hw->map.coeffs_base + MALIDP_COEF_TABLE_ADDR);
for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i) for (i = 0; i < MALIDP_COEFFTAB_NUM_COEFFS; ++i)
malidp_hw_write(hwdev, data[i], malidp_hw_write(hwdev, data[i],
hwdev->map.coeffs_base + hwdev->hw->map.coeffs_base +
MALIDP_COEF_TABLE_DATA); MALIDP_COEF_TABLE_DATA);
} }
...@@ -103,7 +103,7 @@ void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc, ...@@ -103,7 +103,7 @@ void malidp_atomic_commit_update_coloradj(struct drm_crtc *crtc,
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i) for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; ++i)
malidp_hw_write(hwdev, malidp_hw_write(hwdev,
mc->coloradj_coeffs[i], mc->coloradj_coeffs[i],
hwdev->map.coeffs_base + hwdev->hw->map.coeffs_base +
MALIDP_COLOR_ADJ_COEF + 4 * i); MALIDP_COLOR_ADJ_COEF + 4 * i);
malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ, malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_CADJ,
...@@ -120,8 +120,8 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc, ...@@ -120,8 +120,8 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
struct malidp_se_config *s = &cs->scaler_config; struct malidp_se_config *s = &cs->scaler_config;
struct malidp_se_config *old_s = &old_cs->scaler_config; struct malidp_se_config *old_s = &old_cs->scaler_config;
u32 se_control = hwdev->map.se_base + u32 se_control = hwdev->hw->map.se_base +
((hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
0x10 : 0xC); 0x10 : 0xC);
u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL; u32 layer_control = se_control + MALIDP_SE_LAYER_CONTROL;
u32 scr = se_control + MALIDP_SE_SCALING_CONTROL; u32 scr = se_control + MALIDP_SE_SCALING_CONTROL;
...@@ -135,7 +135,7 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc, ...@@ -135,7 +135,7 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
return; return;
} }
hwdev->se_set_scaling_coeffs(hwdev, s, old_s); hwdev->hw->se_set_scaling_coeffs(hwdev, s, old_s);
val = malidp_hw_read(hwdev, se_control); val = malidp_hw_read(hwdev, se_control);
val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN; val |= MALIDP_SE_SCALING_EN | MALIDP_SE_ALPHA_EN;
...@@ -170,9 +170,9 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm) ...@@ -170,9 +170,9 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
int ret; int ret;
atomic_set(&malidp->config_valid, 0); atomic_set(&malidp->config_valid, 0);
hwdev->set_config_valid(hwdev); hwdev->hw->set_config_valid(hwdev);
/* don't wait for config_valid flag if we are in config mode */ /* don't wait for config_valid flag if we are in config mode */
if (hwdev->in_config_mode(hwdev)) if (hwdev->hw->in_config_mode(hwdev))
return 0; return 0;
ret = wait_event_interruptible_timeout(malidp->wq, ret = wait_event_interruptible_timeout(malidp->wq,
...@@ -455,7 +455,7 @@ static int malidp_runtime_pm_suspend(struct device *dev) ...@@ -455,7 +455,7 @@ static int malidp_runtime_pm_suspend(struct device *dev)
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
/* we can only suspend if the hardware is in config mode */ /* we can only suspend if the hardware is in config mode */
WARN_ON(!hwdev->in_config_mode(hwdev)); WARN_ON(!hwdev->hw->in_config_mode(hwdev));
hwdev->pm_suspended = true; hwdev->pm_suspended = true;
clk_disable_unprepare(hwdev->mclk); clk_disable_unprepare(hwdev->mclk);
...@@ -500,11 +500,7 @@ static int malidp_bind(struct device *dev) ...@@ -500,11 +500,7 @@ static int malidp_bind(struct device *dev)
if (!hwdev) if (!hwdev)
return -ENOMEM; return -ENOMEM;
/* hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
* copy the associated data from malidp_drm_of_match to avoid
* having to keep a reference to the OF node after binding
*/
memcpy(hwdev, of_device_get_match_data(dev), sizeof(*hwdev));
malidp->dev = hwdev; malidp->dev = hwdev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -568,13 +564,13 @@ static int malidp_bind(struct device *dev) ...@@ -568,13 +564,13 @@ static int malidp_bind(struct device *dev)
goto query_hw_fail; goto query_hw_fail;
} }
ret = hwdev->query_hw(hwdev); ret = hwdev->hw->query_hw(hwdev);
if (ret) { if (ret) {
DRM_ERROR("Invalid HW configuration\n"); DRM_ERROR("Invalid HW configuration\n");
goto query_hw_fail; goto query_hw_fail;
} }
version = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_DE_CORE_ID); version = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_DE_CORE_ID);
DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16, DRM_INFO("found ARM Mali-DP%3x version r%dp%d\n", version >> 16,
(version >> 12) & 0xf, (version >> 8) & 0xf); (version >> 12) & 0xf, (version >> 8) & 0xf);
...@@ -589,7 +585,7 @@ static int malidp_bind(struct device *dev) ...@@ -589,7 +585,7 @@ static int malidp_bind(struct device *dev)
for (i = 0; i < MAX_OUTPUT_CHANNELS; i++) for (i = 0; i < MAX_OUTPUT_CHANNELS; i++)
out_depth = (out_depth << 8) | (output_width[i] & 0xf); out_depth = (out_depth << 8) | (output_width[i] & 0xf);
malidp_hw_write(hwdev, out_depth, hwdev->map.out_depth_base); malidp_hw_write(hwdev, out_depth, hwdev->hw->map.out_depth_base);
atomic_set(&malidp->config_valid, 0); atomic_set(&malidp->config_valid, 0);
init_waitqueue_head(&malidp->wq); init_waitqueue_head(&malidp->wq);
......
...@@ -183,7 +183,7 @@ static void malidp500_enter_config_mode(struct malidp_hw_device *hwdev) ...@@ -183,7 +183,7 @@ static void malidp500_enter_config_mode(struct malidp_hw_device *hwdev)
malidp_hw_setbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); malidp_hw_setbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL);
while (count) { while (count) {
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ) if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ)
break; break;
/* /*
...@@ -203,7 +203,7 @@ static void malidp500_leave_config_mode(struct malidp_hw_device *hwdev) ...@@ -203,7 +203,7 @@ static void malidp500_leave_config_mode(struct malidp_hw_device *hwdev)
malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP500_CONFIG_VALID); malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP500_CONFIG_VALID);
malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL);
while (count) { while (count) {
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP500_DC_CONFIG_REQ) == 0) if ((status & MALIDP500_DC_CONFIG_REQ) == 0)
break; break;
usleep_range(100, 1000); usleep_range(100, 1000);
...@@ -216,7 +216,7 @@ static bool malidp500_in_config_mode(struct malidp_hw_device *hwdev) ...@@ -216,7 +216,7 @@ static bool malidp500_in_config_mode(struct malidp_hw_device *hwdev)
{ {
u32 status; u32 status;
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ) if ((status & MALIDP500_DC_CONFIG_REQ) == MALIDP500_DC_CONFIG_REQ)
return true; return true;
...@@ -407,7 +407,7 @@ static void malidp550_enter_config_mode(struct malidp_hw_device *hwdev) ...@@ -407,7 +407,7 @@ static void malidp550_enter_config_mode(struct malidp_hw_device *hwdev)
malidp_hw_setbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); malidp_hw_setbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL);
while (count) { while (count) {
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ) if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ)
break; break;
/* /*
...@@ -427,7 +427,7 @@ static void malidp550_leave_config_mode(struct malidp_hw_device *hwdev) ...@@ -427,7 +427,7 @@ static void malidp550_leave_config_mode(struct malidp_hw_device *hwdev)
malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP550_CONFIG_VALID); malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP550_CONFIG_VALID);
malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL);
while (count) { while (count) {
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP550_DC_CONFIG_REQ) == 0) if ((status & MALIDP550_DC_CONFIG_REQ) == 0)
break; break;
usleep_range(100, 1000); usleep_range(100, 1000);
...@@ -440,7 +440,7 @@ static bool malidp550_in_config_mode(struct malidp_hw_device *hwdev) ...@@ -440,7 +440,7 @@ static bool malidp550_in_config_mode(struct malidp_hw_device *hwdev)
{ {
u32 status; u32 status;
status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hwdev->hw->map.dc_base + MALIDP_REG_STATUS);
if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ) if ((status & MALIDP550_DC_CONFIG_REQ) == MALIDP550_DC_CONFIG_REQ)
return true; return true;
...@@ -616,7 +616,7 @@ static int malidp650_query_hw(struct malidp_hw_device *hwdev) ...@@ -616,7 +616,7 @@ static int malidp650_query_hw(struct malidp_hw_device *hwdev)
return 0; return 0;
} }
const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
[MALIDP_500] = { [MALIDP_500] = {
.map = { .map = {
.coeffs_base = MALIDP500_COEFFS_BASE, .coeffs_base = MALIDP500_COEFFS_BASE,
...@@ -751,7 +751,7 @@ static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 ir ...@@ -751,7 +751,7 @@ static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 ir
{ {
u32 base = malidp_get_block_base(hwdev, block); u32 base = malidp_get_block_base(hwdev, block);
if (hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) if (hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ)
malidp_hw_write(hwdev, irq, base + MALIDP_REG_CLEARIRQ); malidp_hw_write(hwdev, irq, base + MALIDP_REG_CLEARIRQ);
else else
malidp_hw_write(hwdev, irq, base + MALIDP_REG_STATUS); malidp_hw_write(hwdev, irq, base + MALIDP_REG_STATUS);
...@@ -762,12 +762,14 @@ static irqreturn_t malidp_de_irq(int irq, void *arg) ...@@ -762,12 +762,14 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
struct drm_device *drm = arg; struct drm_device *drm = arg;
struct malidp_drm *malidp = drm->dev_private; struct malidp_drm *malidp = drm->dev_private;
struct malidp_hw_device *hwdev; struct malidp_hw_device *hwdev;
struct malidp_hw *hw;
const struct malidp_irq_map *de; const struct malidp_irq_map *de;
u32 status, mask, dc_status; u32 status, mask, dc_status;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
hwdev = malidp->dev; hwdev = malidp->dev;
de = &hwdev->map.de_irq_map; hw = hwdev->hw;
de = &hw->map.de_irq_map;
/* /*
* if we are suspended it is likely that we were invoked because * if we are suspended it is likely that we were invoked because
...@@ -778,8 +780,8 @@ static irqreturn_t malidp_de_irq(int irq, void *arg) ...@@ -778,8 +780,8 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
return IRQ_NONE; return IRQ_NONE;
/* first handle the config valid IRQ */ /* first handle the config valid IRQ */
dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); dc_status = malidp_hw_read(hwdev, hw->map.dc_base + MALIDP_REG_STATUS);
if (dc_status & hwdev->map.dc_irq_map.vsync_irq) { if (dc_status & hw->map.dc_irq_map.vsync_irq) {
/* we have a page flip event */ /* we have a page flip event */
atomic_set(&malidp->config_valid, 1); atomic_set(&malidp->config_valid, 1);
malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, dc_status); malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, dc_status);
...@@ -832,11 +834,11 @@ int malidp_de_irq_init(struct drm_device *drm, int irq) ...@@ -832,11 +834,11 @@ int malidp_de_irq_init(struct drm_device *drm, int irq)
/* first enable the DC block IRQs */ /* first enable the DC block IRQs */
malidp_hw_enable_irq(hwdev, MALIDP_DC_BLOCK, malidp_hw_enable_irq(hwdev, MALIDP_DC_BLOCK,
hwdev->map.dc_irq_map.irq_mask); hwdev->hw->map.dc_irq_map.irq_mask);
/* now enable the DE block IRQs */ /* now enable the DE block IRQs */
malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK, malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK,
hwdev->map.de_irq_map.irq_mask); hwdev->hw->map.de_irq_map.irq_mask);
return 0; return 0;
} }
...@@ -847,9 +849,9 @@ void malidp_de_irq_fini(struct drm_device *drm) ...@@ -847,9 +849,9 @@ void malidp_de_irq_fini(struct drm_device *drm)
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK, malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK,
hwdev->map.de_irq_map.irq_mask); hwdev->hw->map.de_irq_map.irq_mask);
malidp_hw_disable_irq(hwdev, MALIDP_DC_BLOCK, malidp_hw_disable_irq(hwdev, MALIDP_DC_BLOCK,
hwdev->map.dc_irq_map.irq_mask); hwdev->hw->map.dc_irq_map.irq_mask);
} }
static irqreturn_t malidp_se_irq(int irq, void *arg) static irqreturn_t malidp_se_irq(int irq, void *arg)
...@@ -857,6 +859,8 @@ static irqreturn_t malidp_se_irq(int irq, void *arg) ...@@ -857,6 +859,8 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)
struct drm_device *drm = arg; struct drm_device *drm = arg;
struct malidp_drm *malidp = drm->dev_private; struct malidp_drm *malidp = drm->dev_private;
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
struct malidp_hw *hw = hwdev->hw;
const struct malidp_irq_map *se = &hw->map.se_irq_map;
u32 status, mask; u32 status, mask;
/* /*
...@@ -867,12 +871,12 @@ static irqreturn_t malidp_se_irq(int irq, void *arg) ...@@ -867,12 +871,12 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)
if (hwdev->pm_suspended) if (hwdev->pm_suspended)
return IRQ_NONE; return IRQ_NONE;
status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_STATUS);
if (!(status & hwdev->map.se_irq_map.irq_mask)) if (!(status & se->irq_mask))
return IRQ_NONE; return IRQ_NONE;
mask = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_MASKIRQ); mask = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_MASKIRQ);
status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); status = malidp_hw_read(hwdev, hw->map.se_base + MALIDP_REG_STATUS);
status &= mask; status &= mask;
/* ToDo: status decoding and firing up of VSYNC and page flip events */ /* ToDo: status decoding and firing up of VSYNC and page flip events */
...@@ -905,7 +909,7 @@ int malidp_se_irq_init(struct drm_device *drm, int irq) ...@@ -905,7 +909,7 @@ int malidp_se_irq_init(struct drm_device *drm, int irq)
} }
malidp_hw_enable_irq(hwdev, MALIDP_SE_BLOCK, malidp_hw_enable_irq(hwdev, MALIDP_SE_BLOCK,
hwdev->map.se_irq_map.irq_mask); hwdev->hw->map.se_irq_map.irq_mask);
return 0; return 0;
} }
...@@ -916,5 +920,5 @@ void malidp_se_irq_fini(struct drm_device *drm) ...@@ -916,5 +920,5 @@ void malidp_se_irq_fini(struct drm_device *drm)
struct malidp_hw_device *hwdev = malidp->dev; struct malidp_hw_device *hwdev = malidp->dev;
malidp_hw_disable_irq(hwdev, MALIDP_SE_BLOCK, malidp_hw_disable_irq(hwdev, MALIDP_SE_BLOCK,
hwdev->map.se_irq_map.irq_mask); hwdev->hw->map.se_irq_map.irq_mask);
} }
...@@ -120,18 +120,14 @@ struct malidp_hw_regmap { ...@@ -120,18 +120,14 @@ struct malidp_hw_regmap {
/* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */ /* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */
#define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0) #define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0)
struct malidp_hw_device { struct malidp_hw_device;
const struct malidp_hw_regmap map;
void __iomem *regs;
/* APB clock */ /*
struct clk *pclk; * Static structure containing hardware specific data and pointers to
/* AXI clock */ * functions that behave differently between various versions of the IP.
struct clk *aclk; */
/* main clock for display core */ struct malidp_hw {
struct clk *mclk; const struct malidp_hw_regmap map;
/* pixel clock for display core */
struct clk *pxlclk;
/* /*
* Validate the driver instance against the hardware bits * Validate the driver instance against the hardware bits
...@@ -182,15 +178,6 @@ struct malidp_hw_device { ...@@ -182,15 +178,6 @@ struct malidp_hw_device {
struct videomode *vm); struct videomode *vm);
u8 features; u8 features;
u8 min_line_size;
u16 max_line_size;
/* track the device PM state */
bool pm_suspended;
/* size of memory used for rotating layers, up to two banks available */
u32 rotation_memory[2];
}; };
/* Supported variants of the hardware */ /* Supported variants of the hardware */
...@@ -202,7 +189,33 @@ enum { ...@@ -202,7 +189,33 @@ enum {
MALIDP_MAX_DEVICES MALIDP_MAX_DEVICES
}; };
extern const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES]; extern const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES];
/*
* Structure used by the driver during runtime operation.
*/
struct malidp_hw_device {
struct malidp_hw *hw;
void __iomem *regs;
/* APB clock */
struct clk *pclk;
/* AXI clock */
struct clk *aclk;
/* main clock for display core */
struct clk *mclk;
/* pixel clock for display core */
struct clk *pxlclk;
u8 min_line_size;
u16 max_line_size;
/* track the device PM state */
bool pm_suspended;
/* size of memory used for rotating layers, up to two banks available */
u32 rotation_memory[2];
};
static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg) static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg)
{ {
...@@ -240,9 +253,9 @@ static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev, ...@@ -240,9 +253,9 @@ static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev,
{ {
switch (block) { switch (block) {
case MALIDP_SE_BLOCK: case MALIDP_SE_BLOCK:
return hwdev->map.se_base; return hwdev->hw->map.se_base;
case MALIDP_DC_BLOCK: case MALIDP_DC_BLOCK:
return hwdev->map.dc_base; return hwdev->hw->map.dc_base;
} }
return 0; return 0;
...@@ -275,7 +288,7 @@ u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, ...@@ -275,7 +288,7 @@ u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map,
static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev, static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev,
unsigned int pitch) unsigned int pitch)
{ {
return !(pitch & (hwdev->map.bus_align_bytes - 1)); return !(pitch & (hwdev->hw->map.bus_align_bytes - 1));
} }
/* U16.16 */ /* U16.16 */
...@@ -308,8 +321,8 @@ static inline void malidp_se_set_enh_coeffs(struct malidp_hw_device *hwdev) ...@@ -308,8 +321,8 @@ static inline void malidp_se_set_enh_coeffs(struct malidp_hw_device *hwdev)
}; };
u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) | u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) |
MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL); MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL);
u32 image_enh = hwdev->map.se_base + u32 image_enh = hwdev->hw->map.se_base +
((hwdev->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
0x10 : 0xC) + MALIDP_SE_IMAGE_ENH; 0x10 : 0xC) + MALIDP_SE_IMAGE_ENH;
u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0; u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0;
int i; int i;
......
...@@ -185,8 +185,9 @@ static int malidp_de_plane_check(struct drm_plane *plane, ...@@ -185,8 +185,9 @@ static int malidp_de_plane_check(struct drm_plane *plane,
fb = state->fb; fb = state->fb;
ms->format = malidp_hw_get_format_id(&mp->hwdev->map, mp->layer->id, ms->format = malidp_hw_get_format_id(&mp->hwdev->hw->map,
fb->format->format); mp->layer->id,
fb->format->format);
if (ms->format == MALIDP_INVALID_FORMAT_ID) if (ms->format == MALIDP_INVALID_FORMAT_ID)
return -EINVAL; return -EINVAL;
...@@ -211,7 +212,7 @@ static int malidp_de_plane_check(struct drm_plane *plane, ...@@ -211,7 +212,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
* third plane stride register. * third plane stride register.
*/ */
if (ms->n_planes == 3 && if (ms->n_planes == 3 &&
!(mp->hwdev->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) && !(mp->hwdev->hw->features & MALIDP_DEVICE_LV_HAS_3_STRIDES) &&
(state->fb->pitches[1] != state->fb->pitches[2])) (state->fb->pitches[1] != state->fb->pitches[2]))
return -EINVAL; return -EINVAL;
...@@ -229,9 +230,9 @@ static int malidp_de_plane_check(struct drm_plane *plane, ...@@ -229,9 +230,9 @@ static int malidp_de_plane_check(struct drm_plane *plane,
if (state->rotation & MALIDP_ROTATED_MASK) { if (state->rotation & MALIDP_ROTATED_MASK) {
int val; int val;
val = mp->hwdev->rotmem_required(mp->hwdev, state->crtc_h, val = mp->hwdev->hw->rotmem_required(mp->hwdev, state->crtc_h,
state->crtc_w, state->crtc_w,
fb->format->format); fb->format->format);
if (val < 0) if (val < 0)
return val; return val;
...@@ -251,7 +252,7 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp, ...@@ -251,7 +252,7 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
return; return;
if (num_planes == 3) if (num_planes == 3)
num_strides = (mp->hwdev->features & num_strides = (mp->hwdev->hw->features &
MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2; MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
for (i = 0; i < num_strides; ++i) for (i = 0; i < num_strides; ++i)
...@@ -264,13 +265,11 @@ static void malidp_de_plane_update(struct drm_plane *plane, ...@@ -264,13 +265,11 @@ static void malidp_de_plane_update(struct drm_plane *plane,
struct drm_plane_state *old_state) struct drm_plane_state *old_state)
{ {
struct malidp_plane *mp; struct malidp_plane *mp;
const struct malidp_hw_regmap *map;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state); struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
u32 src_w, src_h, dest_w, dest_h, val; u32 src_w, src_h, dest_w, dest_h, val;
int i; int i;
mp = to_malidp_plane(plane); mp = to_malidp_plane(plane);
map = &mp->hwdev->map;
/* convert src values from Q16 fixed point to integer */ /* convert src values from Q16 fixed point to integer */
src_w = plane->state->src_w >> 16; src_w = plane->state->src_w >> 16;
...@@ -363,7 +362,7 @@ static const struct drm_plane_helper_funcs malidp_de_plane_helper_funcs = { ...@@ -363,7 +362,7 @@ static const struct drm_plane_helper_funcs malidp_de_plane_helper_funcs = {
int malidp_de_planes_init(struct drm_device *drm) int malidp_de_planes_init(struct drm_device *drm)
{ {
struct malidp_drm *malidp = drm->dev_private; struct malidp_drm *malidp = drm->dev_private;
const struct malidp_hw_regmap *map = &malidp->dev->map; const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
struct malidp_plane *plane = NULL; struct malidp_plane *plane = NULL;
enum drm_plane_type plane_type; enum drm_plane_type plane_type;
unsigned long crtcs = 1 << drm->mode_config.num_crtc; unsigned long crtcs = 1 << drm->mode_config.num_crtc;
......
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