From e4bf6c255c1d8f5d49ac002ae1b206881e3b6872 Mon Sep 17 00:00:00 2001 From: "keith.zhao" Date: Wed, 27 Dec 2023 18:20:54 +0800 Subject: vout: divide interrupt into 2 crtc0 and ctrc1 use the diff bit instead of common one Signed-off-by: keith.zhao --- drivers/gpu/drm/drm_atomic_helper.c | 114 +++++++++++++++++---------------- drivers/gpu/drm/verisilicon/vs_crtc.c | 9 ++- drivers/gpu/drm/verisilicon/vs_crtc.h | 2 +- drivers/gpu/drm/verisilicon/vs_dc.c | 65 +++---------------- drivers/gpu/drm/verisilicon/vs_dc_hw.c | 61 +++++++++--------- drivers/gpu/drm/verisilicon/vs_dc_hw.h | 2 +- 6 files changed, 104 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 02b4a7dc92f5..342b451cd77c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1134,6 +1134,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_dbg_atomic(dev, "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; @@ -1194,41 +1230,7 @@ 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_dbg_atomic(dev, "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); - } } /** @@ -1464,27 +1466,7 @@ 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_dbg_atomic(dev, "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; @@ -1523,6 +1505,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_dbg_atomic(dev, "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); @@ -1629,7 +1633,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 98f952a72e2e..cb9c0c3776f4 100644 --- a/drivers/gpu/drm/verisilicon/vs_crtc.c +++ b/drivers/gpu/drm/verisilicon/vs_crtc.c @@ -192,8 +192,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; } @@ -201,8 +203,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 99db76c349cd..2fce762256c9 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 5ebc8abd6039..72203d7c8f32 100644 --- a/drivers/gpu/drm/verisilicon/vs_dc_hw.c +++ b/drivers/gpu/drm/verisilicon/vs_dc_hw.c @@ -1163,6 +1163,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); @@ -1488,16 +1498,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) @@ -1945,29 +1951,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); -- cgit v1.2.3