Merge branch 'for-upstream/mali-dp' of git://linux-arm.org/linux-ld into drm-fixes
mali-dp interface cleanups. * 'for-upstream/mali-dp' of git://linux-arm.org/linux-ld: drm: mali-dp: Disable planes when their CRTC gets disabled. drm: mali-dp: Separate static internal data into a read-only structure. drm/arm: Replace instances of drm_dev_unref with drm_dev_put. drm: mali-dp: switch to drm_*_get(), drm_*_put() helpers
This commit is contained in:
commit
062076e861
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +77,12 @@ static void malidp_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||||||
struct malidp_hw_device *hwdev = malidp->dev;
|
struct malidp_hw_device *hwdev = malidp->dev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* always disable planes on the CRTC that is being turned off */
|
||||||
|
drm_atomic_helper_disable_planes_on_crtc(old_state, false);
|
||||||
|
|
||||||
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 +323,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 +479,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 +489,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,
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
@ -671,7 +667,7 @@ query_hw_fail:
|
|||||||
malidp_runtime_pm_suspend(dev);
|
malidp_runtime_pm_suspend(dev);
|
||||||
drm->dev_private = NULL;
|
drm->dev_private = NULL;
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
drm_dev_unref(drm);
|
drm_dev_put(drm);
|
||||||
alloc_fail:
|
alloc_fail:
|
||||||
of_reserved_mem_device_release(dev);
|
of_reserved_mem_device_release(dev);
|
||||||
|
|
||||||
@ -704,7 +700,7 @@ static void malidp_unbind(struct device *dev)
|
|||||||
malidp_runtime_pm_suspend(dev);
|
malidp_runtime_pm_suspend(dev);
|
||||||
drm->dev_private = NULL;
|
drm->dev_private = NULL;
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
drm_dev_unref(drm);
|
drm_dev_put(drm);
|
||||||
of_reserved_mem_device_release(dev);
|
of_reserved_mem_device_release(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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 {
|
|||||||
/* 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 {
|
|||||||
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 {
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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)
|
|||||||
};
|
};
|
||||||
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;
|
||||||
|
@ -57,7 +57,7 @@ static void malidp_de_plane_destroy(struct drm_plane *plane)
|
|||||||
struct malidp_plane *mp = to_malidp_plane(plane);
|
struct malidp_plane *mp = to_malidp_plane(plane);
|
||||||
|
|
||||||
if (mp->base.fb)
|
if (mp->base.fb)
|
||||||
drm_framebuffer_unreference(mp->base.fb);
|
drm_framebuffer_put(mp->base.fb);
|
||||||
|
|
||||||
drm_plane_helper_disable(plane);
|
drm_plane_helper_disable(plane);
|
||||||
drm_plane_cleanup(plane);
|
drm_plane_cleanup(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,
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 = {
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user