summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandy.hu <andy.hu@starfivetech.com>2024-01-05 09:07:47 +0300
committerandy.hu <andy.hu@starfivetech.com>2024-01-05 09:07:47 +0300
commitc4a881c67fb437294d14ce0abbe6ddd13ac73570 (patch)
tree921c32bf019e66ab39cc6729fe0b4fd2b2f752fd
parentbb509f27e05139f715c9cf16819903b120a63bb6 (diff)
parente4bf6c255c1d8f5d49ac002ae1b206881e3b6872 (diff)
downloadlinux-c4a881c67fb437294d14ce0abbe6ddd13ac73570.tar.xz
Merge branch 'CR_7964_evb_6-1_4K_mipi4lane_keith.zhao' into 'jh7110-6.1.y-devel'
CR_7964 vout: divide interrupt into 2 See merge request sdk/linux!1003
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c114
-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, 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);