diff options
author | keith.zhao <keith.zhao@starfivetech.com> | 2023-12-27 10:19:46 +0300 |
---|---|---|
committer | keith.zhao <keith.zhao@starfivetech.com> | 2023-12-27 12:29:50 +0300 |
commit | 4fb6817942d06bb50554ab3a574b614bd3c2499e (patch) | |
tree | 335869f6ec100f79b45bbbb891fa46451796da23 | |
parent | 1e48db4ca973e1a62efd3dd892514ea70c2f08f0 (diff) | |
download | linux-4fb6817942d06bb50554ab3a574b614bd3c2499e.tar.xz |
vout: divide interrupt into 2
crtc0 and ctrc1 use the diff bit instead of common one
Signed-off-by: keith.zhao <keith.zhao@starfivetech.com>
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 118 | ||||
-rw-r--r-- | drivers/gpu/drm/verisilicon/vs_crtc.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/verisilicon/vs_crtc.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/verisilicon/vs_dc.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/verisilicon/vs_dc_hw.c | 61 | ||||
-rw-r--r-- | drivers/gpu/drm/verisilicon/vs_dc_hw.h | 2 |
6 files changed, 104 insertions, 153 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2c0c6ec92820..fcf0d74f4955 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1014,6 +1014,42 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) struct drm_crtc_state *old_crtc_state, *new_crtc_state; int i; + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { + const struct drm_crtc_helper_funcs *funcs; + int ret; + + /* Shut down everything that needs a full modeset. */ + if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) + continue; + + if (!crtc_needs_disable(old_crtc_state, new_crtc_state)) + continue; + + funcs = crtc->helper_private; + + DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n", + crtc->base.id, crtc->name); + + + /* Right function depends upon target state. */ + if (new_crtc_state->enable && funcs->prepare) + funcs->prepare(crtc); + else if (funcs->atomic_disable) + funcs->atomic_disable(crtc, old_state); + else if (funcs->disable) + funcs->disable(crtc); + else if (funcs->dpms) + funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + + if (!drm_dev_has_vblank(dev)) + continue; + + ret = drm_crtc_vblank_get(crtc); + WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n"); + if (ret == 0) + drm_crtc_vblank_put(crtc); + } + for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; @@ -1073,42 +1109,6 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) drm_atomic_bridge_chain_post_disable(bridge, old_state); } - - for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { - const struct drm_crtc_helper_funcs *funcs; - int ret; - - /* Shut down everything that needs a full modeset. */ - if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) - continue; - - if (!crtc_needs_disable(old_crtc_state, new_crtc_state)) - continue; - - funcs = crtc->helper_private; - - DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n", - crtc->base.id, crtc->name); - - - /* Right function depends upon target state. */ - if (new_crtc_state->enable && funcs->prepare) - funcs->prepare(crtc); - else if (funcs->atomic_disable) - funcs->atomic_disable(crtc, old_state); - else if (funcs->disable) - funcs->disable(crtc); - else if (funcs->dpms) - funcs->dpms(crtc, DRM_MODE_DPMS_OFF); - - if (!drm_dev_has_vblank(dev)) - continue; - - ret = drm_crtc_vblank_get(crtc); - WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n"); - if (ret == 0) - drm_crtc_vblank_put(crtc); - } } /** @@ -1344,28 +1344,6 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_connector_state *new_conn_state; int i; - for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { - const struct drm_crtc_helper_funcs *funcs; - - /* Need to filter out CRTCs where only planes change. */ - if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) - continue; - - if (!new_crtc_state->active) - continue; - - funcs = crtc->helper_private; - - if (new_crtc_state->enable) { - DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", - crtc->base.id, crtc->name); - if (funcs->atomic_enable) - funcs->atomic_enable(crtc, old_state); - else if (funcs->commit) - funcs->commit(crtc); - } - } - for_each_new_connector_in_state(old_state, connector, new_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; @@ -1403,6 +1381,28 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, drm_atomic_bridge_chain_enable(bridge, old_state); } + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { + const struct drm_crtc_helper_funcs *funcs; + + /* Need to filter out CRTCs where only planes change. */ + if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) + continue; + + if (!new_crtc_state->active) + continue; + + funcs = crtc->helper_private; + + if (new_crtc_state->enable) { + DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", + crtc->base.id, crtc->name); + if (funcs->atomic_enable) + funcs->atomic_enable(crtc, old_state); + else if (funcs->commit) + funcs->commit(crtc); + } + } + drm_atomic_helper_commit_writebacks(dev, old_state); } EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables); @@ -1509,7 +1509,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, ret = wait_event_timeout(dev->vblank[i].queue, old_state->crtcs[i].last_vblank_count != drm_crtc_vblank_count(crtc), - msecs_to_jiffies(100)); + msecs_to_jiffies(500)); WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n", crtc->base.id, crtc->name); diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.c b/drivers/gpu/drm/verisilicon/vs_crtc.c index 90692ad3f3cf..ebf659decfde 100644 --- a/drivers/gpu/drm/verisilicon/vs_crtc.c +++ b/drivers/gpu/drm/verisilicon/vs_crtc.c @@ -191,8 +191,10 @@ static int vs_crtc_late_register(struct drm_crtc *crtc) static int vs_crtc_enable_vblank(struct drm_crtc *crtc) { struct vs_crtc *vs_crtc = to_vs_crtc(crtc); + u32 ctrc_mask = 0; - vs_crtc->funcs->enable_vblank(vs_crtc->dev, true); + ctrc_mask = drm_crtc_mask(crtc); + vs_crtc->funcs->enable_vblank(vs_crtc->dev, true, ctrc_mask); return 0; } @@ -200,8 +202,9 @@ static int vs_crtc_enable_vblank(struct drm_crtc *crtc) static void vs_crtc_disable_vblank(struct drm_crtc *crtc) { struct vs_crtc *vs_crtc = to_vs_crtc(crtc); - - vs_crtc->funcs->enable_vblank(vs_crtc->dev, false); + u32 ctrc_mask = 0; + ctrc_mask = drm_crtc_mask(crtc); + vs_crtc->funcs->enable_vblank(vs_crtc->dev, false, ctrc_mask); } static const struct drm_crtc_funcs vs_crtc_funcs = { diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.h b/drivers/gpu/drm/verisilicon/vs_crtc.h index a506ad00fb76..9292a4a060a6 100644 --- a/drivers/gpu/drm/verisilicon/vs_crtc.h +++ b/drivers/gpu/drm/verisilicon/vs_crtc.h @@ -21,7 +21,7 @@ struct vs_crtc_funcs { struct drm_color_lut *lut, unsigned int size); void (*enable_gamma)(struct device *dev, struct drm_crtc *crtc, bool enable); - void (*enable_vblank)(struct device *dev, bool enable); + void (*enable_vblank)(struct device *dev, bool enable, u32 ctrc_mask); void (*commit)(struct device *dev); }; diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c b/drivers/gpu/drm/verisilicon/vs_dc.c index 7c9e8a16c5fc..f6d8749183e6 100644 --- a/drivers/gpu/drm/verisilicon/vs_dc.c +++ b/drivers/gpu/drm/verisilicon/vs_dc.c @@ -267,47 +267,6 @@ static inline u8 to_vs_display_id(struct vs_dc *dc, struct drm_crtc *crtc) return 0; } -#if 0 -static int plda_clk_rst_init(struct device *dev) -{ - int ret; - struct vs_dc *dc = dev_get_drvdata(dev); - - dc->num_clks = devm_clk_bulk_get_all(dev, &dc->clks); - if (dc->num_clks < 0) { - dev_err(dev, "failed to get vout clocks\n"); - ret = -ENODEV; - goto exit; - } - ret = clk_bulk_prepare_enable(dc->num_clks, dc->clks); - if (ret) { - dev_err(dev, "failed to enable clocks\n"); - goto exit; - } - - dc->resets = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(dc->resets)) { - ret = PTR_ERR(dc->resets); - dev_err(dev, "failed to get pcie resets"); - goto err_clk_init; - } - ret = reset_control_deassert(dc->resets); - goto exit; - -err_clk_init: - clk_bulk_disable_unprepare(dc->num_clks, dc->clks); -exit: - return ret; -} - -static void plda_clk_rst_deinit(struct device *dev) -{ - struct vs_dc *dc = dev_get_drvdata(dev); - - reset_control_assert(dc->resets); - clk_bulk_disable_unprepare(dc->num_clks, dc->clks); -} -#endif static int vs_dc_get_clock(struct device *dev, struct vs_dc *dc) { @@ -473,14 +432,6 @@ static void vs_vout_reset_deassert(struct vs_dc *dc) //reset_control_deassert(dc->noc_disp);//ok } -/* -static void vs_vout_reset_assert(struct vs_dc *dc) -{ - reset_control_assert(dc->rst_vout_src);//no! - reset_control_assert(dc->noc_disp);//ok -} -*/ - static void vs_dc8200_reset_get(struct device *dev, struct vs_dc *dc) { dc->dc8200_rst_axi = reset_control_get_shared(dev, "rst_axi"); @@ -635,7 +586,7 @@ static void dc_deinit(struct device *dev) { struct vs_dc *dc = dev_get_drvdata(dev); int ret; - dc_hw_enable_interrupt(&dc->hw, 0); + dc_hw_enable_interrupt(&dc->hw, 0, 0); dc_hw_deinit(&dc->hw); vs_dc_dc8200_clock_disable(dc); vs_dc_vouttop_clock_disable(dc); @@ -920,11 +871,11 @@ static void vs_dc_enable_gamma(struct device *dev, struct drm_crtc *crtc, dc_hw_enable_gamma(&dc->hw, id, enable); } -static void vs_dc_enable_vblank(struct device *dev, bool enable) +static void vs_dc_enable_vblank(struct device *dev, bool enable, u32 ctrc_mask) { struct vs_dc *dc = dev_get_drvdata(dev); - dc_hw_enable_interrupt(&dc->hw, enable); + dc_hw_enable_interrupt(&dc->hw, enable, ctrc_mask); } static u32 calc_factor(u32 src, u32 dest) @@ -1008,11 +959,11 @@ static void update_fb(struct vs_plane *plane, u8 display_id, update_swizzle(drm_fb->format->format, fb); update_watermark(plane_state->watermark, fb); - sifive_l2_flush64_range(fb->y_address, fb->height * fb->y_stride); - if (fb->u_address) - sifive_l2_flush64_range(fb->u_address, fb->height * fb->u_stride); - if (fb->v_address) - sifive_l2_flush64_range(fb->v_address, fb->height * fb->v_stride); + sifive_l2_flush64_range(fb->y_address, fb->height * fb->y_stride); + if (fb->u_address) + sifive_l2_flush64_range(fb->u_address, fb->height * fb->u_stride); + if (fb->v_address) + sifive_l2_flush64_range(fb->v_address, fb->height * fb->v_stride); plane_state->status.tile_mode = fb->tile_mode; } diff --git a/drivers/gpu/drm/verisilicon/vs_dc_hw.c b/drivers/gpu/drm/verisilicon/vs_dc_hw.c index 22ab16cd01e1..e12b067a0311 100644 --- a/drivers/gpu/drm/verisilicon/vs_dc_hw.c +++ b/drivers/gpu/drm/verisilicon/vs_dc_hw.c @@ -1161,6 +1161,16 @@ static inline void hi_write(struct dc_hw *hw, u32 reg, u32 value) writel(value, hw->hi_base + reg); } +static inline void dc_high_set_clear(struct dc_hw *hw, u32 reg, u32 set, u32 clear) +{ + u32 value = hi_read(hw, reg); + + value &= ~clear; + value |= set; + hi_write(hw, reg, value); +} + + static inline void dc_write(struct dc_hw *hw, u32 reg, u32 value) { writel(value, hw->reg_base + reg - DC_REG_BASE); @@ -1486,16 +1496,12 @@ void dc_hw_setup_display(struct dc_hw *hw, struct dc_hw_display *display) hw->func->display(hw, display); } -void dc_hw_enable_interrupt(struct dc_hw *hw, bool enable) +void dc_hw_enable_interrupt(struct dc_hw *hw, bool enable, u32 ctrc_mask) { - if (enable) { - if (hw->out[1] == OUT_DPI) - dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3)); - - hi_write(hw, AQ_INTR_ENBL, 0xFFFFFFFF); - } else { - ;//hi_write(hw, AQ_INTR_ENBL, 0); - } + if (enable) + dc_high_set_clear(hw, AQ_INTR_ENBL, ctrc_mask, 0); + else + dc_high_set_clear(hw, AQ_INTR_ENBL, 0, ctrc_mask); } u32 dc_hw_get_interrupt(struct dc_hw *hw) @@ -1943,29 +1949,20 @@ static void setup_display(struct dc_hw *hw, struct dc_hw_display *display) dc_write(hw, DC_DISPLAY_DITHER_CONFIG + offset, 0); } - dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(12), 0); - if (hw->display[id].sync_enable) - dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(2) | BIT(3), 0); - else if (id == 0) - dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(0), BIT(3)); - else - if (hw->out[id] != OUT_DPI) - dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3)); - } else { - dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(12)); - if (id == 0) - dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2)); - else - dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2)); - - dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x0, 0x0, BIT(24)); - dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x4, 0x0, BIT(24)); - dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x8, 0x0, BIT(24)); - dc_set_clear(hw, DC_OVERLAY_CONFIG + 0xc, 0x0, BIT(24)); - - dc_set_clear(hw, DC_CURSOR_CONFIG + 0x0, BIT(3), 0x03); - dc_set_clear(hw, DC_CURSOR_CONFIG + DC_CURSOR_OFFSET, BIT(3), 0x03); - } + dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(12), 0); + if (hw->display[id].sync_enable) + dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(2) | BIT(3), 0); + else if (id == 0) + dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(0), BIT(3)); + else + dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3)); + } else { + dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(12)); + if (id == 0) + dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2)); + else + dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2)); + } } static void setup_display_ex(struct dc_hw *hw, struct dc_hw_display *display) diff --git a/drivers/gpu/drm/verisilicon/vs_dc_hw.h b/drivers/gpu/drm/verisilicon/vs_dc_hw.h index c6f467355597..7bc1c385eab3 100644 --- a/drivers/gpu/drm/verisilicon/vs_dc_hw.h +++ b/drivers/gpu/drm/verisilicon/vs_dc_hw.h @@ -558,7 +558,7 @@ void dc_hw_enable_gamma(struct dc_hw *hw, u8 id, bool enable); void dc_hw_enable_dump(struct dc_hw *hw, u32 addr, u32 pitch); void dc_hw_disable_dump(struct dc_hw *hw); void dc_hw_setup_display(struct dc_hw *hw, struct dc_hw_display *display); -void dc_hw_enable_interrupt(struct dc_hw *hw, bool enable); +void dc_hw_enable_interrupt(struct dc_hw *hw, bool enable, u32 ctrc_mask); u32 dc_hw_get_interrupt(struct dc_hw *hw); bool dc_hw_check_underflow(struct dc_hw *hw); void dc_hw_enable_shadow_register(struct dc_hw *hw, bool enable); |