|
@@ -1224,26 +1224,46 @@ void dce110_timing_generator_setup_global_swap_lock(
|
|
|
|
|
|
/* This pipe will belong to GSL Group zero. */
|
|
/* This pipe will belong to GSL Group zero. */
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 1,
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL0_EN);
|
|
|
|
|
|
+ 1,
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL0_EN);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- gsl_params->gsl_master == tg->inst,
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL_MASTER_EN);
|
|
|
|
|
|
+ gsl_params->gsl_master == tg->inst,
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL_MASTER_EN);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- HFLIP_READY_DELAY,
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
|
|
|
|
|
|
+ HFLIP_READY_DELAY,
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
|
|
|
|
|
|
/* Keep signal low (pending high) during 6 lines.
|
|
/* Keep signal low (pending high) during 6 lines.
|
|
* Also defines minimum interval before re-checking signal. */
|
|
* Also defines minimum interval before re-checking signal. */
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- HFLIP_CHECK_DELAY,
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
|
|
|
|
|
|
+ HFLIP_CHECK_DELAY,
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmDCP_GSL_CONTROL), value);
|
|
|
|
+ value = 0;
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ gsl_params->gsl_master,
|
|
|
|
+ DCIO_GSL0_CNTL,
|
|
|
|
+ DCIO_GSL0_VSYNC_SEL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0,
|
|
|
|
+ DCIO_GSL0_CNTL,
|
|
|
|
+ DCIO_GSL0_TIMING_SYNC_SEL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0,
|
|
|
|
+ DCIO_GSL0_CNTL,
|
|
|
|
+ DCIO_GSL0_GLOBAL_UNLOCK_SEL);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmDCIO_GSL0_CNTL), value);
|
|
|
|
|
|
|
|
|
|
{
|
|
{
|
|
@@ -1253,38 +1273,38 @@ void dce110_timing_generator_setup_global_swap_lock(
|
|
CRTC_REG(mmCRTC_V_TOTAL));
|
|
CRTC_REG(mmCRTC_V_TOTAL));
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL_SYNC_SOURCE);
|
|
|
|
|
|
+ 0,/* DCP_GSL_PURPOSE_SURFACE_FLIP */
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL_SYNC_SOURCE);
|
|
|
|
|
|
/* Checkpoint relative to end of frame */
|
|
/* Checkpoint relative to end of frame */
|
|
check_point = get_reg_field_value(value_crtc_vtotal,
|
|
check_point = get_reg_field_value(value_crtc_vtotal,
|
|
- CRTC_V_TOTAL,
|
|
|
|
- CRTC_V_TOTAL);
|
|
|
|
|
|
+ CRTC_V_TOTAL,
|
|
|
|
+ CRTC_V_TOTAL);
|
|
|
|
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_GSL_WINDOW), 0);
|
|
}
|
|
}
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 1,
|
|
|
|
- DCP_GSL_CONTROL,
|
|
|
|
- DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
|
|
|
|
|
|
+ 1,
|
|
|
|
+ DCP_GSL_CONTROL,
|
|
|
|
+ DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
|
|
|
|
|
|
dm_write_reg(tg->ctx, address, value);
|
|
dm_write_reg(tg->ctx, address, value);
|
|
|
|
|
|
/********************************************************************/
|
|
/********************************************************************/
|
|
address = CRTC_REG(mmCRTC_GSL_CONTROL);
|
|
address = CRTC_REG(mmCRTC_GSL_CONTROL);
|
|
|
|
|
|
- value = 0;
|
|
|
|
|
|
+ value = dm_read_reg(tg->ctx, address);
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- check_point - FLIP_READY_BACK_LOOKUP,
|
|
|
|
- CRTC_GSL_CONTROL,
|
|
|
|
- CRTC_GSL_CHECK_LINE_NUM);
|
|
|
|
|
|
+ check_point - FLIP_READY_BACK_LOOKUP,
|
|
|
|
+ CRTC_GSL_CONTROL,
|
|
|
|
+ CRTC_GSL_CHECK_LINE_NUM);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- VFLIP_READY_DELAY,
|
|
|
|
- CRTC_GSL_CONTROL,
|
|
|
|
- CRTC_GSL_FORCE_DELAY);
|
|
|
|
|
|
+ VFLIP_READY_DELAY,
|
|
|
|
+ CRTC_GSL_CONTROL,
|
|
|
|
+ CRTC_GSL_FORCE_DELAY);
|
|
|
|
|
|
dm_write_reg(tg->ctx, address, value);
|
|
dm_write_reg(tg->ctx, address, value);
|
|
}
|
|
}
|
|
@@ -1555,6 +1575,138 @@ void dce110_timing_generator_enable_reset_trigger(
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void dce110_timing_generator_enable_crtc_reset(
|
|
|
|
+ struct timing_generator *tg,
|
|
|
|
+ int source_tg_inst,
|
|
|
|
+ struct crtc_trigger_info *crtc_tp)
|
|
|
|
+{
|
|
|
|
+ uint32_t value = 0;
|
|
|
|
+ uint32_t rising_edge = 0;
|
|
|
|
+ uint32_t falling_edge = 0;
|
|
|
|
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
|
|
|
+
|
|
|
|
+ /* Setup trigger edge */
|
|
|
|
+ switch (crtc_tp->event) {
|
|
|
|
+ case CRTC_EVENT_VSYNC_RISING:
|
|
|
|
+ rising_edge = 1;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case CRTC_EVENT_VSYNC_FALLING:
|
|
|
|
+ falling_edge = 1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ source_tg_inst,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_SOURCE_SELECT);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_POLARITY_SELECT);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ rising_edge,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ falling_edge,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1, /* clear trigger status */
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_CLEAR);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
|
|
|
|
+
|
|
|
|
+ /**************************************************************/
|
|
|
|
+
|
|
|
|
+ switch (crtc_tp->delay) {
|
|
|
|
+ case TRIGGER_DELAY_NEXT_LINE:
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0, /* force H count to H_TOTAL and V count to V_TOTAL */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_MODE);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0, /* TriggerB - we never use TriggerA */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_TRIG_SEL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1, /* clear trigger status */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CLEAR);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
|
|
+
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 2,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_AUTO_FORCE_VSYNC_MODE);
|
|
|
|
+
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case TRIGGER_DELAY_NEXT_PIXEL:
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_AUTO_FORCE_VSYNC_MODE);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
|
|
|
|
+
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 2, /* force H count to H_TOTAL and V count to V_TOTAL */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_MODE);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1, /* TriggerB - we never use TriggerA */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_TRIG_SEL);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1, /* clear trigger status */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CLEAR);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 2,
|
|
|
|
+ CRTC_MASTER_UPDATE_MODE,
|
|
|
|
+ MASTER_UPDATE_MODE);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value);
|
|
|
|
+}
|
|
void dce110_timing_generator_disable_reset_trigger(
|
|
void dce110_timing_generator_disable_reset_trigger(
|
|
struct timing_generator *tg)
|
|
struct timing_generator *tg)
|
|
{
|
|
{
|
|
@@ -1564,34 +1716,48 @@ void dce110_timing_generator_disable_reset_trigger(
|
|
value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 0, /* force counter now mode is disabled */
|
|
|
|
- CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
- CRTC_FORCE_COUNT_NOW_MODE);
|
|
|
|
|
|
+ 0, /* force counter now mode is disabled */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_MODE);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 1, /* clear trigger status */
|
|
|
|
- CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
- CRTC_FORCE_COUNT_NOW_CLEAR);
|
|
|
|
|
|
+ 1, /* clear trigger status */
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CLEAR);
|
|
|
|
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL), value);
|
|
|
|
|
|
|
|
+ value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 1,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_FORCE_VSYNC_NEXT_LINE_CLEAR);
|
|
|
|
+
|
|
|
|
+ set_reg_field_value(value,
|
|
|
|
+ 0,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_AUTO_FORCE_VSYNC_MODE);
|
|
|
|
+
|
|
|
|
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERT_SYNC_CONTROL), value);
|
|
|
|
+
|
|
/********************************************************************/
|
|
/********************************************************************/
|
|
value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
|
|
value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL));
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
|
|
|
|
- CRTC_TRIGB_CNTL,
|
|
|
|
- CRTC_TRIGB_SOURCE_SELECT);
|
|
|
|
|
|
+ TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_SOURCE_SELECT);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
|
|
|
|
- CRTC_TRIGB_CNTL,
|
|
|
|
- CRTC_TRIGB_POLARITY_SELECT);
|
|
|
|
|
|
+ TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_POLARITY_SELECT);
|
|
|
|
|
|
set_reg_field_value(value,
|
|
set_reg_field_value(value,
|
|
- 1, /* clear trigger status */
|
|
|
|
- CRTC_TRIGB_CNTL,
|
|
|
|
- CRTC_TRIGB_CLEAR);
|
|
|
|
|
|
+ 1, /* clear trigger status */
|
|
|
|
+ CRTC_TRIGB_CNTL,
|
|
|
|
+ CRTC_TRIGB_CLEAR);
|
|
|
|
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
|
|
dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_TRIGB_CNTL), value);
|
|
}
|
|
}
|
|
@@ -1611,10 +1777,16 @@ bool dce110_timing_generator_did_triggered_reset_occur(
|
|
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
|
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
|
uint32_t value = dm_read_reg(tg->ctx,
|
|
uint32_t value = dm_read_reg(tg->ctx,
|
|
CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
CRTC_REG(mmCRTC_FORCE_COUNT_NOW_CNTL));
|
|
-
|
|
|
|
- return get_reg_field_value(value,
|
|
|
|
- CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
- CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
|
|
|
|
|
|
+ uint32_t value1 = dm_read_reg(tg->ctx,
|
|
|
|
+ CRTC_REG(mmCRTC_VERT_SYNC_CONTROL));
|
|
|
|
+ bool force = get_reg_field_value(value,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_CNTL,
|
|
|
|
+ CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
|
|
|
|
+ bool vert_sync = get_reg_field_value(value1,
|
|
|
|
+ CRTC_VERT_SYNC_CONTROL,
|
|
|
|
+ CRTC_FORCE_VSYNC_NEXT_LINE_OCCURRED) != 0;
|
|
|
|
+
|
|
|
|
+ return (force || vert_sync);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1928,6 +2100,7 @@ static const struct timing_generator_funcs dce110_tg_funcs = {
|
|
.setup_global_swap_lock =
|
|
.setup_global_swap_lock =
|
|
dce110_timing_generator_setup_global_swap_lock,
|
|
dce110_timing_generator_setup_global_swap_lock,
|
|
.enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
|
|
.enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
|
|
|
|
+ .enable_crtc_reset = dce110_timing_generator_enable_crtc_reset,
|
|
.disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
|
|
.disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
|
|
.tear_down_global_swap_lock =
|
|
.tear_down_global_swap_lock =
|
|
dce110_timing_generator_tear_down_global_swap_lock,
|
|
dce110_timing_generator_tear_down_global_swap_lock,
|