summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkeith.zhao <keith.zhao@starfivetech.com>2023-12-27 10:19:46 +0300
committerkeith.zhao <keith.zhao@starfivetech.com>2023-12-27 12:29:50 +0300
commit4fb6817942d06bb50554ab3a574b614bd3c2499e (patch)
tree335869f6ec100f79b45bbbb891fa46451796da23
parent1e48db4ca973e1a62efd3dd892514ea70c2f08f0 (diff)
downloadlinux-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.c118
-rw-r--r--drivers/gpu/drm/verisilicon/vs_crtc.c9
-rw-r--r--drivers/gpu/drm/verisilicon/vs_crtc.h2
-rw-r--r--drivers/gpu/drm/verisilicon/vs_dc.c65
-rw-r--r--drivers/gpu/drm/verisilicon/vs_dc_hw.c61
-rw-r--r--drivers/gpu/drm/verisilicon/vs_dc_hw.h2
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);