*/
#include "dm_services.h"
-#include "dc.h"
-#include "core_dc.h"
#include "core_types.h"
-#include "core_status.h"
#include "resource.h"
+#include "custom_float.h"
#include "dcn10_hw_sequencer.h"
#include "dce110/dce110_hw_sequencer.h"
#include "dce/dce_hwseq.h"
#include "abm.h"
-
-#include "dcn10/dcn10_transform.h"
+#include "dcn10/dcn10_mem_input.h"
+#include "dcn10/dcn10_dpp.h"
#include "dcn10/dcn10_mpc.h"
-#include "dcn10/dcn10_timing_generator.h"
-
-#include "mem_input.h"
#include "timing_generator.h"
#include "opp.h"
#include "ipp.h"
-
-#include "dc_bios_types.h"
-
+#include "mpc.h"
#include "raven1/DCN/dcn_1_0_offset.h"
#include "raven1/DCN/dcn_1_0_sh_mask.h"
#include "vega10/soc15ip.h"
+#include "reg_helper.h"
-#include "custom_float.h"
+#define CTX \
+ hws->ctx
+#define REG(reg)\
+ hws->regs->reg
+#undef FN
+#define FN(reg_name, field_name) \
+ hws->shifts->field_name, hws->masks->field_name
-struct dcn10_hwseq_reg_offsets {
- uint32_t dchubp;
- uint32_t dpp;
- uint32_t otg;
- uint32_t vtg;
- uint32_t fmt;
-};
-
-/* TODO: move to resource */
-static const struct dcn10_hwseq_reg_offsets reg_offsets[] = {
- {
- .dchubp = (mmHUBP0_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
- .dpp = (mmCM0_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
- .otg = (mmOTG0_OTG_CONTROL - mmOTG0_OTG_CONTROL),
- .vtg = (mmVTG0_CONTROL - mmVTG0_CONTROL),
- .fmt = (mmFMT0_FMT_BIT_DEPTH_CONTROL -
- mmFMT0_FMT_BIT_DEPTH_CONTROL),
- },
- {
- .dchubp = (mmHUBP1_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
- .dpp = (mmCM1_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
- .otg = (mmOTG1_OTG_CONTROL - mmOTG0_OTG_CONTROL),
- .vtg = (mmVTG1_CONTROL - mmVTG0_CONTROL),
- .fmt = (mmFMT1_FMT_BIT_DEPTH_CONTROL -
- mmFMT0_FMT_BIT_DEPTH_CONTROL),
- },
- {
- .dchubp = (mmHUBP2_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
- .dpp = (mmCM2_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
- .otg = (mmOTG2_OTG_CONTROL - mmOTG0_OTG_CONTROL),
- .vtg = (mmVTG2_CONTROL - mmVTG0_CONTROL),
- .fmt = (mmFMT2_FMT_BIT_DEPTH_CONTROL -
- mmFMT0_FMT_BIT_DEPTH_CONTROL),
- },
- {
- .dchubp = (mmHUBP3_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL),
- .dpp = (mmCM3_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL),
- .otg = (mmOTG3_OTG_CONTROL - mmOTG0_OTG_CONTROL),
- .vtg = (mmVTG3_CONTROL - mmVTG0_CONTROL),
- .fmt = (mmFMT3_FMT_BIT_DEPTH_CONTROL -
- mmFMT0_FMT_BIT_DEPTH_CONTROL),
- }
-};
-
-#define HWSEQ_REG_UPDATE_N(reg_name, n, ...) \
- generic_reg_update_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__)
-#define HWSEQ_REG_SET_N(reg_name, n, ...) \
- generic_reg_set_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__)
-
-#define HWSEQ_REG_UPDATE(reg, field, val) \
- HWSEQ_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-
-#define HWSEQ_REG_UPDATE_2(reg, field1, val1, field2, val2) \
- HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)
-
-#define HWSEQ_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \
- HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)
-
-
-#define HWSEQ_REG_SET(reg, field, val) \
- HWSEQ_REG_SET_N(reg, 1, FD(reg##__##field), val)
-
-/* TODO should be moved to OTG */
-
-static bool unlock_master_tg_and_wait(
- struct dc_context *ctx,
- uint8_t inst)
+static void verify_allow_pstate_change_high(
+ struct dce_hwseq *hws)
{
- uint32_t inst_offset = reg_offsets[inst].otg;
+ /* pstate latency is ~20us so if we wait over 40us and pstate allow
+ * still not asserted, we are probably stuck and going to hang
+ */
+ static unsigned int pstate_wait_timeout_us = 40;
+ static unsigned int max_sampled_pstate_wait_us; /* data collection */
+ static bool forced_pstate_allow; /* help with revert wa */
- HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_SYNC_STATUS,
- VUPDATE_NO_LOCK_EVENT_CLEAR, 1);
- HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, 0);
+ unsigned int debug_index = 0x7;
+ unsigned int debug_data;
+ unsigned int force_allow_pstate = 0x30;
+ unsigned int i;
- if (!wait_reg(ctx, inst_offset, OTG0_OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_OCCURRED, 1)) {
- dm_logger_write(ctx->logger, LOG_ERROR,
- "wait for VUPDATE_NO_LOCK_EVENT_OCCURRED failed\n");
- BREAK_TO_DEBUGGER();
- return false;
+ if (forced_pstate_allow) {
+ /* we hacked to force pstate allow to prevent hang last time
+ * we verify_allow_pstate_change_high. so disable force
+ * here so we can check status
+ */
+ REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0);
+ forced_pstate_allow = false;
}
- return true;
-}
-
-static void wait_no_outstanding_request(
- struct dc_context *ctx,
- uint8_t plane_id)
-{
- uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
- if (!wait_reg(ctx, inst_offset, HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, 1))
- BREAK_TO_DEBUGGER();
-}
-
-static void disable_clocks(
- struct dc_context *ctx,
- uint8_t plane_id)
-{
- uint32_t inst_offset = reg_offsets[plane_id].dchubp;
- generic_reg_update_soc15(ctx, inst_offset, HUBP0_HUBP_CLK_CNTL, 1,
- FD(HUBP0_HUBP_CLK_CNTL__HUBP_CLOCK_ENABLE), 0);
-
- inst_offset = reg_offsets[plane_id].dpp;
- generic_reg_update_soc15(ctx, inst_offset, DPP_TOP0_DPP_CONTROL, 1,
- FD(DPP_TOP0_DPP_CONTROL__DPP_CLOCK_ENABLE), 0);
-}
-
-/* TODO: This is one time program during system boot up,
- * this should be done within BIOS or CAIL
- */
-static void dchubp_map_fb_to_mc(struct dc_context *ctx)
-{
- /* TODO: do not know where to program
- * DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB
+ /* description "3-0: Pipe0 cursor0 QOS
+ * 7-4: Pipe1 cursor0 QOS
+ * 11-8: Pipe2 cursor0 QOS
+ * 15-12: Pipe3 cursor0 QOS
+ * 16: Pipe0 Plane0 Allow Pstate Change
+ * 17: Pipe1 Plane0 Allow Pstate Change
+ * 18: Pipe2 Plane0 Allow Pstate Change
+ * 19: Pipe3 Plane0 Allow Pstate Change
+ * 20: Pipe0 Plane1 Allow Pstate Change
+ * 21: Pipe1 Plane1 Allow Pstate Change
+ * 22: Pipe2 Plane1 Allow Pstate Change
+ * 23: Pipe3 Plane1 Allow Pstate Change
+ * 24: Pipe0 cursor0 Allow Pstate Change
+ * 25: Pipe1 cursor0 Allow Pstate Change
+ * 26: Pipe2 cursor0 Allow Pstate Change
+ * 27: Pipe3 cursor0 Allow Pstate Change
+ * 28: WB0 Allow Pstate Change
+ * 29: WB1 Allow Pstate Change
+ * 30: Arbiter's allow_pstate_change
+ * 31: SOC pstate change request
*/
- /*
- * TODO: For real ASIC, FB_OFFSET may be need change to the same value
- * as FB_BASE. Need re-visit this for real ASIC.
- */
- dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_BASE, 0, 0x80);
- dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_OFFSET, 0, 0);
- dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_TOP, 0, 0xFF);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG0, 7,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_DATA_RESPONSE_STATUS_CLEAR), 0,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_ERROR_CLEAR), 0,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_FLUSH_REQ_CREDIT_EN), 0,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_EN), 0,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_PORT_CONTROL), 1,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_UNIT_ID_BITMASK), 0xd3,
- FD(DCHUBBUB_SDPIF_CFG0__SDPIF_CREDIT_DISCONNECT_DELAY), 0xc);
-
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG1, 4,
- FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_IO), 0,
- FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_VC), 6,
- FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_IO), 1,
- FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_VC), 6);
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_BASE, 1,
- FD(DCHUBBUB_SDPIF_FB_BASE__SDPIF_FB_BASE), 0x000080);
+ REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index);
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_TOP, 1,
- FD(DCHUBBUB_SDPIF_FB_TOP__SDPIF_FB_TOP), 0x0000ff);
+ for (i = 0; i < pstate_wait_timeout_us; i++) {
+ debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BOT, 1,
- FD(DCHUBBUB_SDPIF_AGP_BOT__SDPIF_AGP_BOT), 0x0000040);
+ if (debug_data & (1 << 30))
+ return;
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_TOP, 1,
- FD(DCHUBBUB_SDPIF_AGP_TOP__SDPIF_AGP_TOP), 0x00001ff);
+ if (max_sampled_pstate_wait_us < i)
+ max_sampled_pstate_wait_us = i;
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BASE, 1,
- FD(DCHUBBUB_SDPIF_AGP_BASE__SDPIF_AGP_BASE), 0x0000080);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_TOP, 1,
- FD(DCHUBBUB_SDPIF_APER_TOP__SDPIF_APER_TOP), 0x00007ff);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_DEF_0, 1,
- FD(DCHUBBUB_SDPIF_APER_DEF_0__SDPIF_APER_DEF_0), 0xdeadbeef);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_0, 2,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_EN_0), 0,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_RELOC_LO_0), 0x90000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_0, 1,
- FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_0__SDPIF_MARC_LENGTH_LO_0), 0x10000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_1, 1,
- FD(DCHUBBUB_SDPIF_MARC_BASE_LO_1__SDPIF_MARC_BASE_LO_1), 0x10000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_1, 2,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_EN_1), 0,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_RELOC_LO_1), 0xa0000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_1, 1,
- FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_1__SDPIF_MARC_LENGTH_LO_1), 0x10000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_2, 1,
- FD(DCHUBBUB_SDPIF_MARC_BASE_LO_2__SDPIF_MARC_BASE_LO_2), 0x20000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_2, 2,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_EN_2), 0,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_RELOC_LO_2), 0xb0000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_2, 1,
- FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_2__SDPIF_MARC_LENGTH_LO_2), 0x10000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_3, 1,
- FD(DCHUBBUB_SDPIF_MARC_BASE_LO_3__SDPIF_MARC_BASE_LO_3), 0x30000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_3, 2,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_EN_3), 0,
- FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_RELOC_LO_3), 0xc0000);
-
- generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_3, 1,
- FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_3__SDPIF_MARC_LENGTH_LO_3), 0x10000);
+ udelay(1);
+ }
- /* TODO: Is DCN_VM_SYSTEM_APERTURE address one time programming?
- * Are all 4 hubp programmed with the same address?
+ /* force pstate allow to prevent system hang
+ * and break to debugger to investigate
*/
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000);
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0);
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000);
- dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0);
-}
-
-/* TODO: This is one time program during system boot up,
- * this should be done within BIOS
- */
-static void dchubup_setup_timer(struct dc_context *ctx)
-{
- dm_write_reg_soc15(ctx, mmREFCLK_CNTL, 0, 0);
-
- generic_reg_update_soc15(ctx, 0, DCHUBBUB_GLOBAL_TIMER_CNTL, 1,
- FD(DCHUBBUB_GLOBAL_TIMER_CNTL__DCHUBBUB_GLOBAL_TIMER_ENABLE), 1);
-}
-
-/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
- * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
- * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
- */
-static void select_vtg(
- struct dc_context *ctx,
- uint8_t plane_id,
- uint8_t inst)
-{
- uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
- HWSEQ_REG_UPDATE(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, inst);
-}
-
-static void enable_dcfclk(
- struct dc_context *ctx,
- uint8_t plane_id,
- uint32_t requested_pix_clk,
- bool dppclk_div)
-{
- uint32_t inst_offset = reg_offsets[plane_id].dchubp;
-
- HWSEQ_REG_UPDATE(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, 1);
+ REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate);
+ forced_pstate_allow = true;
+ BREAK_TO_DEBUGGER();
}
static void enable_dppclk(
- struct dc_context *ctx,
+ struct dce_hwseq *hws,
uint8_t plane_id,
uint32_t requested_pix_clk,
bool dppclk_div)
{
- uint32_t inst_offset = reg_offsets[plane_id].dpp;
-
- dm_logger_write(ctx->logger, LOG_SURFACE,
+ dm_logger_write(hws->ctx->logger, LOG_SURFACE,
"dppclk_rate_control for pipe %d programed to %d\n",
plane_id,
dppclk_div);
- /* TODO: find condition for DPP clock to DISPCLK or 1/2 DISPCLK */
- if (dppclk_div) {
- /* 1/2 DISPCLK*/
- HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL,
- DPPCLK_RATE_CONTROL, 1,
+ if (hws->shifts->DPPCLK_RATE_CONTROL)
+ REG_UPDATE_2(DPP_CONTROL[plane_id],
+ DPPCLK_RATE_CONTROL, dppclk_div,
DPP_CLOCK_ENABLE, 1);
- } else {
- /* DISPCLK */
- HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL,
- DPPCLK_RATE_CONTROL, 0,
+ else
+ REG_UPDATE(DPP_CONTROL[plane_id],
DPP_CLOCK_ENABLE, 1);
- }
}
static void enable_power_gating_plane(
- struct dc_context *ctx,
+ struct dce_hwseq *hws,
bool enable)
{
- uint32_t inst_offset = 0; /* each register only has one instance */
bool force_on = 1; /* disable power gating */
if (enable)
force_on = 0;
/* DCHUBP0/1/2/3 */
- HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
/* DPP0/1/2/3 */
- HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
- HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
+ REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
+}
+
+static void disable_vga(
+ struct dce_hwseq *hws)
+{
+ REG_WRITE(D1VGA_CONTROL, 0);
+ REG_WRITE(D2VGA_CONTROL, 0);
+ REG_WRITE(D3VGA_CONTROL, 0);
+ REG_WRITE(D4VGA_CONTROL, 0);
}
static void dpp_pg_control(
- struct dc_context *ctx,
+ struct dce_hwseq *hws,
unsigned int dpp_inst,
bool power_on)
{
- uint32_t inst_offset = 0;
uint32_t power_gate = power_on ? 0 : 1;
uint32_t pwr_status = power_on ? 0 : 2;
- if (ctx->dc->debug.disable_dpp_power_gate)
+ if (hws->ctx->dc->debug.disable_dpp_power_gate)
return;
switch (dpp_inst) {
case 0: /* DPP0 */
- HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG,
+ REG_UPDATE(DOMAIN1_PG_CONFIG,
DOMAIN1_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN1_PG_STATUS,
- DOMAIN1_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN1_PG_STATUS,
+ DOMAIN1_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 1: /* DPP1 */
- HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG,
+ REG_UPDATE(DOMAIN3_PG_CONFIG,
DOMAIN3_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN3_PG_STATUS,
- DOMAIN3_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN3_PG_STATUS,
+ DOMAIN3_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 2: /* DPP2 */
- HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG,
+ REG_UPDATE(DOMAIN5_PG_CONFIG,
DOMAIN5_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN5_PG_STATUS,
- DOMAIN5_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN5_PG_STATUS,
+ DOMAIN5_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 3: /* DPP3 */
- HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG,
+ REG_UPDATE(DOMAIN7_PG_CONFIG,
DOMAIN7_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN7_PG_STATUS,
- DOMAIN7_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN7_PG_STATUS,
+ DOMAIN7_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
default:
BREAK_TO_DEBUGGER();
}
}
+static uint32_t convert_and_clamp(
+ uint32_t wm_ns,
+ uint32_t refclk_mhz,
+ uint32_t clamp_value)
+{
+ uint32_t ret_val = 0;
+ ret_val = wm_ns * refclk_mhz;
+ ret_val /= 1000;
+
+ if (ret_val > clamp_value)
+ ret_val = clamp_value;
+
+ return ret_val;
+}
+
+static void program_watermarks(
+ struct dce_hwseq *hws,
+ struct dcn_watermark_set *watermarks,
+ unsigned int refclk_mhz)
+{
+ uint32_t force_en = hws->ctx->dc->debug.disable_stutter ? 1 : 0;
+ /*
+ * Need to clamp to max of the register values (i.e. no wrap)
+ * for dcn1, all wm registers are 21-bit wide
+ */
+ uint32_t prog_wm_value;
+
+ /* Repeat for water mark set A, B, C and D. */
+ /* clock state A */
+ prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
+
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "URGENCY_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.urgent_ns, prog_wm_value);
+
+ prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.pte_meta_urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->a.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_EXIT_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->a.cstate_pstate.pstate_change_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n\n",
+ watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+
+ /* clock state B */
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "URGENCY_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.pte_meta_urgent_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.pte_meta_urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_ENTER_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_EXIT_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.cstate_pstate.pstate_change_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+ /* clock state C */
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "URGENCY_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.pte_meta_urgent_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.pte_meta_urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_ENTER_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_EXIT_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.cstate_pstate.pstate_change_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+ /* clock state D */
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "URGENCY_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.urgent_ns, prog_wm_value);
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.pte_meta_urgent_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.pte_meta_urgent_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_ENTER_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "SR_EXIT_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+
+
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.cstate_pstate.pstate_change_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n\n",
+ watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
+
+ REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+ DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
+ REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+ DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0);
+ REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
+ DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
+ REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
+ DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
+
+ REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+ DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
+ DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
+
+#if 0
+ REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
+ DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
+ DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
+#endif
+}
+
+
+static void dcn10_update_dchub(
+ struct dce_hwseq *hws,
+ struct dchub_init_data *dh_data)
+{
+ /* TODO: port code from dal2 */
+ switch (dh_data->fb_mode) {
+ case FRAME_BUFFER_MODE_ZFB_ONLY:
+ /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
+ REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP,
+ SDPIF_FB_TOP, 0);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE,
+ SDPIF_FB_BASE, 0x0FFFF);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
+ SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+ SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+ SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
+ dh_data->zfb_size_in_byte - 1) >> 22);
+ break;
+ case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
+ /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
+ SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+ SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+ SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr +
+ dh_data->zfb_size_in_byte - 1) >> 22);
+ break;
+ case FRAME_BUFFER_MODE_LOCAL_ONLY:
+ /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE,
+ SDPIF_AGP_BASE, 0);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT,
+ SDPIF_AGP_BOT, 0X03FFFF);
+
+ REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP,
+ SDPIF_AGP_TOP, 0);
+ break;
+ default:
+ break;
+ }
+
+ dh_data->dchub_initialzied = true;
+ dh_data->dchub_info_valid = false;
+}
+
static void hubp_pg_control(
- struct dc_context *ctx,
+ struct dce_hwseq *hws,
unsigned int hubp_inst,
bool power_on)
{
- uint32_t inst_offset = 0;
uint32_t power_gate = power_on ? 0 : 1;
uint32_t pwr_status = power_on ? 0 : 2;
- if (ctx->dc->debug.disable_hubp_power_gate)
+ if (hws->ctx->dc->debug.disable_hubp_power_gate)
return;
switch (hubp_inst) {
case 0: /* DCHUBP0 */
- HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG,
+ REG_UPDATE(DOMAIN0_PG_CONFIG,
DOMAIN0_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN0_PG_STATUS,
- DOMAIN0_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN0_PG_STATUS,
+ DOMAIN0_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 1: /* DCHUBP1 */
- HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG,
+ REG_UPDATE(DOMAIN2_PG_CONFIG,
DOMAIN2_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN2_PG_STATUS,
- DOMAIN2_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN2_PG_STATUS,
+ DOMAIN2_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 2: /* DCHUBP2 */
- HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG,
+ REG_UPDATE(DOMAIN4_PG_CONFIG,
DOMAIN4_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN4_PG_STATUS,
- DOMAIN4_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN4_PG_STATUS,
+ DOMAIN4_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
case 3: /* DCHUBP3 */
- HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG,
+ REG_UPDATE(DOMAIN6_PG_CONFIG,
DOMAIN6_POWER_GATE, power_gate);
- wait_reg(ctx, 0, DOMAIN6_PG_STATUS,
- DOMAIN6_PGFSM_PWR_STATUS, pwr_status);
+ REG_WAIT(DOMAIN6_PG_STATUS,
+ DOMAIN6_PGFSM_PWR_STATUS, pwr_status, 20000, 200000);
break;
default:
BREAK_TO_DEBUGGER();
}
static void power_on_plane(
- struct dc_context *ctx,
+ struct dce_hwseq *hws,
int plane_id)
{
- uint32_t inst_offset = 0;
-
- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- dpp_pg_control(ctx, plane_id, true);
- hubp_pg_control(ctx, plane_id, true);
- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+ dpp_pg_control(hws, plane_id, true);
+ hubp_pg_control(hws, plane_id, true);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
- dm_logger_write(ctx->logger, LOG_DC,
+ dm_logger_write(hws->ctx->logger, LOG_DC,
"Un-gated front end for pipe %d\n", plane_id);
}
-/* fully check bios enabledisplaypowergating table. dal only need dce init
- * other power, clock gate register will be handle by dal itself.
- * further may be put within init_hw
- */
-static bool dcn10_enable_display_power_gating(
- struct core_dc *dc,
- uint8_t controller_id,
- struct dc_bios *dcb,
- enum pipe_gating_control power_gating)
-{
- /* TODOFPGA */
-#if 0
- if (power_gating != PIPE_GATING_CONTROL_ENABLE)
- dce110_init_pte(ctx);
-#endif
-
- return true;
-}
-
static void bios_golden_init(struct core_dc *dc)
{
struct dc_bios *bp = dc->ctx->dc_bios;
}
}
-static void init_hw(struct core_dc *dc)
+static void dcn10_init_hw(struct core_dc *dc)
{
int i;
- struct dc_bios *bp;
- struct transform *xfm;
- struct abm *abm;
-
- bp = dc->ctx->dc_bios;
+ struct abm *abm = dc->res_pool->abm;
+ struct dce_hwseq *hws = dc->hwseq;
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- /* TODO: this will be moved to Diag or BIOS */
- dchubup_setup_timer(dc->ctx);
+ REG_WRITE(REFCLK_CNTL, 0);
+ REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+ REG_WRITE(DIO_MEM_PWR_CTRL, 0);
- /* TODO: dchubp_map_fb_to_mc will be moved to dchub interface
- * between dc and kmd
- */
- dchubp_map_fb_to_mc(dc->ctx);
+ if (!dc->public.debug.disable_clock_gate) {
+ /* enable all DCN clock gating */
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+
+ REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+ }
- enable_power_gating_plane(dc->ctx, true);
+ enable_power_gating_plane(dc->hwseq, true);
return;
}
/* end of FPGA. Below if real ASIC */
bios_golden_init(dc);
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- xfm = dc->res_pool->transforms[i];
- xfm->funcs->transform_reset(xfm);
-
- /* TODOFPGA: may need later */
-#if 0
- xfm->funcs->transform_power_up(xfm);
- dc->hwss.enable_display_pipe_clock_gating(
- dc->ctx,
- true);
-#endif
- }
- /* TODOFPGA: light sleep */
-#if 0
- dc->hwss.clock_gating_power_up(dc->ctx, false);
-#endif
+ disable_vga(dc->hwseq);
for (i = 0; i < dc->link_count; i++) {
/* Power up AND update implementation according to the
* required signal (which may be different from the
* default signal on connector).
*/
- struct core_link *link = dc->links[i];
+ struct dc_link *link = dc->links[i];
link->link_enc->funcs->hw_init(link->link_enc);
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- struct timing_generator *tg =
- dc->res_pool->timing_generators[i];
- struct mpcc *mpcc =
- dc->res_pool->mpcc[i];
- struct mpcc_cfg mpcc_cfg;
-
- tg->funcs->lock(tg);
- mpcc_cfg.opp_id = 0xf;
- mpcc_cfg.top_dpp_id = 0xf;
- mpcc_cfg.bot_mpcc_id = 0xf;
- mpcc_cfg.top_of_tree = true;
- mpcc->funcs->set(mpcc, &mpcc_cfg);
- tg->funcs->unlock(tg);
-
- tg->funcs->disable_vga(tg);
+ struct transform *xfm = dc->res_pool->transforms[i];
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+ xfm->funcs->transform_reset(xfm);
+ dc->res_pool->mpc->funcs->remove(
+ dc->res_pool->mpc, dc->res_pool->opps[i], i);
+
/* Blank controller using driver code instead of
* command table.
*/
audio->funcs->hw_init(audio);
}
- abm = dc->res_pool->abm;
if (abm != NULL) {
abm->funcs->init_backlight(abm);
abm->funcs->abm_init(abm);
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- generic_reg_set_soc15(dc->ctx, 0, DIO_MEM_PWR_CTRL, 7,
- FD(DIO_MEM_PWR_CTRL__HDMI0_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI1_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI2_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI3_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI4_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI5_MEM_PWR_FORCE), 0,
- FD(DIO_MEM_PWR_CTRL__HDMI6_MEM_PWR_FORCE), 0);
+ REG_WRITE(DIO_MEM_PWR_CTRL, 0);
if (!dc->public.debug.disable_clock_gate) {
/* enable all DCN clock gating */
- generic_reg_set_soc15(dc->ctx, 0, DCCG_GATE_DISABLE_CNTL, 19,
- FD(DCCG_GATE_DISABLE_CNTL__DISPCLK_DCCG_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DISPCLK_R_DCCG_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__SOCCLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DPREFCLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DACACLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DVOACLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DPREFCLK_R_DCCG_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DPPCLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__AOMCLK0_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__AOMCLK1_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__AOMCLK2_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__AUDIO_DTO2_CLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DPREFCLK_GTC_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__UNB_DB_CLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__REFCLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__REFCLK_R_DIG_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__DSICLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__BYTECLK_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL__ESCCLK_GATE_DISABLE), 0);
-
- generic_reg_set_soc15(dc->ctx, 0, DCCG_GATE_DISABLE_CNTL2, 14,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKA_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKB_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKC_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKD_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKE_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKF_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKG_FE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKA_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKB_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKC_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKD_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKE_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKF_GATE_DISABLE), 0,
- FD(DCCG_GATE_DISABLE_CNTL2__SYMCLKG_GATE_DISABLE), 0);
-
- generic_reg_update_soc15(dc->ctx, 0, DCFCLK_CNTL, 1,
- FD(DCFCLK_CNTL__DCFCLK_GATE_DIS), 0);
- }
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
- /* This power gating should be one-time program for DAL.
- * It can only change by registry key
- * TODO: new task will for this.
- * if power gating is disable, power_on_plane and power_off_plane
- * should be skip. Otherwise, hand will be met in power_off_plane
- */
- enable_power_gating_plane(dc->ctx, true);
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
+ }
+ enable_power_gating_plane(dc->hwseq, true);
}
static enum dc_status dcn10_prog_pixclk_crtc_otg(
struct validate_context *context,
struct core_dc *dc)
{
- struct core_stream *stream = pipe_ctx->stream;
+ struct dc_stream_state *stream = pipe_ctx->stream;
enum dc_color_space color_space;
struct tg_color black_color = {0};
- bool enableStereo = stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
+ bool enableStereo = stream->timing.timing_3d_format == TIMING_3D_FORMAT_NONE ?
false:true;
- bool rightEyePolarity = stream->public.timing.flags.RIGHT_EYE_3D_POLARITY;
+ bool rightEyePolarity = stream->timing.flags.RIGHT_EYE_3D_POLARITY;
/* by upper caller loop, pipe0 is parent pipe and be called first.
pipe_ctx->tg->funcs->program_timing(
pipe_ctx->tg,
- &stream->public.timing,
+ &stream->timing,
true);
pipe_ctx->opp->funcs->opp_set_stereo_polarity(
&stream->clamping);
#endif
/* program otg blank color */
- color_space = stream->public.output_color_space;
+ color_space = stream->output_color_space;
color_space_to_black_color(dc, color_space, &black_color);
pipe_ctx->tg->funcs->set_blank_color(
pipe_ctx->tg,
struct validate_context *context)
{
int i;
- struct dc_bios *bp;
-
- bp = dc->ctx->dc_bios;
if (pipe_ctx->stream_enc == NULL) {
pipe_ctx->stream = NULL;
pipe_ctx->pipe_idx, pipe_ctx->tg->inst);
}
-static void reset_front_end(
- struct core_dc *dc,
+/* trigger HW to start disconnect plane from stream on the next vsync */
+static void plane_atomic_disconnect(struct core_dc *dc,
int fe_idx)
{
- struct mpcc_cfg mpcc_cfg;
struct mem_input *mi = dc->res_pool->mis[fe_idx];
- struct transform *xfm = dc->res_pool->transforms[fe_idx];
- struct mpcc *mpcc = dc->res_pool->mpcc[fe_idx];
- struct timing_generator *tg = dc->res_pool->timing_generators[mpcc->opp_id];
+ struct mpc *mpc = dc->res_pool->mpc;
+ int opp_id, z_idx;
+ int mpcc_id = -1;
+
+ /* look at tree rather than mi here to know if we already reset */
+ for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
+ struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
+ for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
+ if (opp->mpc_tree.dpp[z_idx] == fe_idx) {
+ mpcc_id = opp->mpc_tree.mpcc[z_idx];
+ break;
+ }
+ }
+ if (mpcc_id != -1)
+ break;
+ }
/*Already reset*/
- if (mpcc->opp_id == 0xf)
+ if (opp_id == dc->res_pool->pipe_count)
return;
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
mi->funcs->dcc_control(mi, false, false);
- tg->funcs->lock(tg);
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+
+ mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx);
+}
+
+/* disable HW used by plane.
+ * note: cannot disable until disconnect is complete */
+static void plane_atomic_disable(struct core_dc *dc,
+ int fe_idx)
+{
+ struct dce_hwseq *hws = dc->hwseq;
+ struct mem_input *mi = dc->res_pool->mis[fe_idx];
+ struct mpc *mpc = dc->res_pool->mpc;
+ int opp_id = mi->opp_id;
+
+ if (opp_id == 0xf)
+ return;
- mpcc_cfg.opp_id = 0xf;
- mpcc_cfg.top_dpp_id = 0xf;
- mpcc_cfg.bot_mpcc_id = 0xf;
- mpcc_cfg.top_of_tree = tg->inst == mpcc->inst;
- mpcc->funcs->set(mpcc, &mpcc_cfg);
+ mpc->funcs->wait_for_idle(mpc, mi->mpcc_id);
+ dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false;
+ /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+ "[debug_mpo: atomic disable finished on mpcc %d]\n",
+ fe_idx);*/
- unlock_master_tg_and_wait(dc->ctx, tg->inst);
- mpcc->funcs->wait_for_idle(mpcc);
mi->funcs->set_blank(mi, true);
- wait_no_outstanding_request(dc->ctx, fe_idx);
- disable_clocks(dc->ctx, fe_idx);
+ /*todo: unhack this*/
+ mi->opp_id = 0xf;
+ mi->mpcc_id = 0xf;
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+
+ REG_UPDATE(HUBP_CLK_CNTL[fe_idx],
+ HUBP_CLOCK_ENABLE, 0);
+ REG_UPDATE(DPP_CONTROL[fe_idx],
+ DPP_CLOCK_ENABLE, 0);
+
+ if (dc->res_pool->opps[opp_id]->mpc_tree.num_pipes == 0)
+ REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
+ OPP_PIPE_CLOCK_EN, 0);
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+}
+
+/*
+ * kill power to plane hw
+ * note: cannot power down until plane is disable
+ */
+static void plane_atomic_power_down(struct core_dc *dc, int fe_idx)
+{
+ struct dce_hwseq *hws = dc->hwseq;
+ struct transform *xfm = dc->res_pool->transforms[fe_idx];
+
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 1);
+ dpp_pg_control(hws, fe_idx, false);
+ hubp_pg_control(hws, fe_idx, false);
xfm->funcs->transform_reset(xfm);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 0);
+ dm_logger_write(dc->ctx->logger, LOG_DC,
+ "Power gated front end %d\n", fe_idx);
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+}
+
+
+static void reset_front_end(
+ struct core_dc *dc,
+ int fe_idx)
+{
+ struct dce_hwseq *hws = dc->hwseq;
+ struct timing_generator *tg;
+ int opp_id = dc->res_pool->mis[fe_idx]->opp_id;
+
+ /*Already reset*/
+ if (opp_id == 0xf)
+ return;
+
+ tg = dc->res_pool->timing_generators[opp_id];
+ tg->funcs->lock(tg);
+
+ plane_atomic_disconnect(dc, fe_idx);
+
+ REG_UPDATE(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_CLEAR, 1);
+ tg->funcs->unlock(tg);
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(hws);
+
+ if (tg->ctx->dce_environment != DCE_ENV_FPGA_MAXIMUS)
+ REG_WAIT(OTG_GLOBAL_SYNC_STATUS[tg->inst],
+ VUPDATE_NO_LOCK_EVENT_OCCURRED, 1, 20000, 200000);
+
+ plane_atomic_disable(dc, fe_idx);
dm_logger_write(dc->ctx->logger, LOG_DC,
"Reset front end %d\n",
static void dcn10_power_down_fe(struct core_dc *dc, int fe_idx)
{
- struct dc_context *ctx = dc->ctx;
- uint32_t inst_offset = 0;
+ struct dce_hwseq *hws = dc->hwseq;
+ struct transform *xfm = dc->res_pool->transforms[fe_idx];
reset_front_end(dc, fe_idx);
- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- dpp_pg_control(ctx, fe_idx, false);
- hubp_pg_control(ctx, fe_idx, false);
- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL,
+ dpp_pg_control(hws, fe_idx, false);
+ hubp_pg_control(hws, fe_idx, false);
+ xfm->funcs->transform_reset(xfm);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(dc->ctx->logger, LOG_DC,
"Power gated front end %d\n", fe_idx);
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
}
static void reset_hw_ctx_wrap(
int i;
/* Reset Front End*/
+ /* Lock*/
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *cur_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i];
+ struct timing_generator *tg = cur_pipe_ctx->tg;
+
+ if (cur_pipe_ctx->stream)
+ tg->funcs->lock(tg);
+ }
+ /* Disconnect*/
+ for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
+ struct pipe_ctx *pipe_ctx_old =
+ &dc->current_context->res_ctx.pipe_ctx[i];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe_ctx->stream ||
+ !pipe_ctx->plane_state ||
+ pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+
+ plane_atomic_disconnect(dc, i);
+ }
+ }
+ /* Unlock*/
+ for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
+ struct pipe_ctx *cur_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i];
+ struct timing_generator *tg = cur_pipe_ctx->tg;
+
+ if (cur_pipe_ctx->stream)
+ tg->funcs->unlock(tg);
+ }
+
+ /* Disable and Powerdown*/
for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
struct pipe_ctx *pipe_ctx_old =
&dc->current_context->res_ctx.pipe_ctx[i];
/*if (!pipe_ctx_old->stream)
continue;*/
- if (!pipe_ctx->stream || !pipe_ctx->surface)
- dcn10_power_down_fe(dc, i);
- else if (pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
- reset_front_end(dc, i);
+ if (pipe_ctx->stream && pipe_ctx->plane_state
+ && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
+ continue;
+
+ plane_atomic_disable(dc, i);
+
+ if (!pipe_ctx->stream || !pipe_ctx->plane_state)
+ plane_atomic_power_down(dc, i);
}
+
/* Reset Back End*/
for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
struct pipe_ctx *pipe_ctx_old =
}
}
-
static bool patch_address_for_sbs_tb_stereo(
struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
{
- struct core_surface *surface = pipe_ctx->surface;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
bool sec_split = pipe_ctx->top_pipe &&
- pipe_ctx->top_pipe->surface == pipe_ctx->surface;
- if (sec_split && surface->public.address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
- (pipe_ctx->stream->public.timing.timing_3d_format ==
+ pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
+ if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+ (pipe_ctx->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_SIDE_BY_SIDE ||
- pipe_ctx->stream->public.timing.timing_3d_format ==
+ pipe_ctx->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
- *addr = surface->public.address.grph_stereo.left_addr;
- surface->public.address.grph_stereo.left_addr =\
- surface->public.address.grph_stereo.right_addr;
+ *addr = plane_state->address.grph_stereo.left_addr;
+ plane_state->address.grph_stereo.left_addr =
+ plane_state->address.grph_stereo.right_addr;
return true;
+ } else {
+ if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
+ plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
+ plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
+ plane_state->address.grph_stereo.right_addr =
+ plane_state->address.grph_stereo.left_addr;
+ }
}
-
return false;
}
{
bool addr_patched = false;
PHYSICAL_ADDRESS_LOC addr;
- struct core_surface *surface = pipe_ctx->surface;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
- if (surface == NULL)
+ if (plane_state == NULL)
return;
addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr(
pipe_ctx->mi,
- &surface->public.address,
- surface->public.flip_immediate);
- surface->status.requested_address = surface->public.address;
+ &plane_state->address,
+ plane_state->flip_immediate);
+ plane_state->status.requested_address = plane_state->address;
if (addr_patched)
- pipe_ctx->surface->public.address.grph_stereo.left_addr = addr;
+ pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
}
static bool dcn10_set_input_transfer_func(
- struct pipe_ctx *pipe_ctx, const struct core_surface *surface)
+ struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
{
struct input_pixel_processor *ipp = pipe_ctx->ipp;
- const struct core_transfer_func *tf = NULL;
+ const struct dc_transfer_func *tf = NULL;
bool result = true;
if (ipp == NULL)
return false;
- if (surface->public.in_transfer_func)
- tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func);
+ if (plane_state->in_transfer_func)
+ tf = plane_state->in_transfer_func;
- if (surface->public.gamma_correction && dce_use_lut(surface))
+ if (plane_state->gamma_correction && dce_use_lut(plane_state))
ipp->funcs->ipp_program_input_lut(ipp,
- surface->public.gamma_correction);
+ plane_state->gamma_correction);
if (tf == NULL)
ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
- else if (tf->public.type == TF_TYPE_PREDEFINED) {
- switch (tf->public.tf) {
+ else if (tf->type == TF_TYPE_PREDEFINED) {
+ switch (tf->tf) {
case TRANSFER_FUNCTION_SRGB:
ipp->funcs->ipp_set_degamma(ipp,
IPP_DEGAMMA_MODE_HW_sRGB);
result = false;
break;
}
- } else if (tf->public.type == TF_TYPE_BYPASS) {
+ } else if (tf->type == TF_TYPE_BYPASS) {
ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS);
} else {
/*TF_TYPE_DISTRIBUTED_POINTS*/
static bool dcn10_set_output_transfer_func(
struct pipe_ctx *pipe_ctx,
- const struct core_stream *stream)
+ const struct dc_stream_state *stream)
{
- struct output_pixel_processor *opp = pipe_ctx->opp;
+ struct transform *xfm = pipe_ctx->xfm;
- if (opp == NULL)
+ if (xfm == NULL)
return false;
- opp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+ xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
- if (stream->public.out_transfer_func &&
- stream->public.out_transfer_func->type ==
+ if (stream->out_transfer_func &&
+ stream->out_transfer_func->type ==
TF_TYPE_PREDEFINED &&
- stream->public.out_transfer_func->tf ==
+ stream->out_transfer_func->tf ==
TRANSFER_FUNCTION_SRGB) {
- opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB);
+ xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
} else if (dcn10_translate_regamma_to_hw_format(
- stream->public.out_transfer_func, &opp->regamma_params)) {
- opp->funcs->opp_program_regamma_pwl(opp, &opp->regamma_params);
- opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
+ stream->out_transfer_func, &xfm->regamma_params)) {
+ xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
+ xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
} else {
- opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS);
+ xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
}
return true;
struct pipe_ctx *pipe,
bool lock)
{
+ struct mem_input *mi = NULL;
+ mi = dc->res_pool->mis[pipe->pipe_idx];
/* use TG master update lock to lock everything on the TG
* therefore only top pipe need to lock
*/
if (pipe->top_pipe)
return;
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+
if (lock)
pipe->tg->funcs->lock(pipe->tg);
else
pipe->tg->funcs->unlock(pipe->tg);
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
}
static bool wait_for_reset_trigger_to_occur(
struct pipe_ctx *pipe_ctx,
struct validate_context *context)
{
- struct dc_surface *dc_surface = &pipe_ctx->surface->public;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ struct dce_hwseq *hws = dc->hwseq;
- power_on_plane(dc->ctx,
+ power_on_plane(dc->hwseq,
pipe_ctx->pipe_idx);
/* enable DCFCLK current DCHUB */
- enable_dcfclk(dc->ctx,
- pipe_ctx->pipe_idx,
- pipe_ctx->pix_clk_params.requested_pix_clk,
- context->bw.dcn.calc_clk.dppclk_div);
- dc->current_context->bw.dcn.cur_clk.dppclk_div =
- context->bw.dcn.calc_clk.dppclk_div;
- context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
+ REG_UPDATE(HUBP_CLK_CNTL[pipe_ctx->pipe_idx],
+ HUBP_CLOCK_ENABLE, 1);
+
+ /* make sure OPP_PIPE_CLOCK_EN = 1 */
+ REG_UPDATE(OPP_PIPE_CONTROL[pipe_ctx->tg->inst],
+ OPP_PIPE_CLOCK_EN, 1);
+ /*TODO: REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, 0x1f);*/
- if (dc_surface) {
+ if (plane_state) {
dm_logger_write(dc->ctx->logger, LOG_DC,
"Pipe:%d 0x%x: addr hi:0x%x, "
"addr low:0x%x, "
"src: %d, %d, %d,"
" %d; dst: %d, %d, %d, %d;\n",
pipe_ctx->pipe_idx,
- dc_surface,
- dc_surface->address.grph.addr.high_part,
- dc_surface->address.grph.addr.low_part,
- dc_surface->src_rect.x,
- dc_surface->src_rect.y,
- dc_surface->src_rect.width,
- dc_surface->src_rect.height,
- dc_surface->dst_rect.x,
- dc_surface->dst_rect.y,
- dc_surface->dst_rect.width,
- dc_surface->dst_rect.height);
+ plane_state,
+ plane_state->address.grph.addr.high_part,
+ plane_state->address.grph.addr.low_part,
+ plane_state->src_rect.x,
+ plane_state->src_rect.y,
+ plane_state->src_rect.width,
+ plane_state->src_rect.height,
+ plane_state->dst_rect.x,
+ plane_state->dst_rect.y,
+ plane_state->dst_rect.width,
+ plane_state->dst_rect.height);
dm_logger_write(dc->ctx->logger, LOG_HW_SET_MODE,
"Pipe %d: width, height, x, y\n"
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
- if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) {
+ if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
adjust.temperature_matrix[0] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[0];
+ gamut_remap_matrix.matrix[0];
adjust.temperature_matrix[1] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[1];
+ gamut_remap_matrix.matrix[1];
adjust.temperature_matrix[2] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[2];
+ gamut_remap_matrix.matrix[2];
adjust.temperature_matrix[3] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[4];
+ gamut_remap_matrix.matrix[4];
adjust.temperature_matrix[4] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[5];
+ gamut_remap_matrix.matrix[5];
adjust.temperature_matrix[5] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[6];
+ gamut_remap_matrix.matrix[6];
adjust.temperature_matrix[6] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[8];
+ gamut_remap_matrix.matrix[8];
adjust.temperature_matrix[7] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[9];
+ gamut_remap_matrix.matrix[9];
adjust.temperature_matrix[8] =
pipe_ctx->stream->
- public.gamut_remap_matrix.matrix[10];
+ gamut_remap_matrix.matrix[10];
}
pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust);
int i;
struct out_csc_color_matrix tbl_entry;
- if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
== true) {
enum dc_color_space color_space =
- pipe_ctx->stream->public.output_color_space;
+ pipe_ctx->stream->output_color_space;
//uint16_t matrix[12];
for (i = 0; i < 12; i++)
- tbl_entry.regval[i] = pipe_ctx->stream->public.csc_color_matrix.matrix[i];
+ tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
tbl_entry.color_space = color_space;
//tbl_entry.regval = matrix;
- pipe_ctx->opp->funcs->opp_set_csc_adjustment(pipe_ctx->opp, &tbl_entry);
+ pipe_ctx->xfm->funcs->opp_set_csc_adjustment(pipe_ctx->xfm, &tbl_entry);
}
}
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
{
- if (pipe_ctx->surface->public.visible)
+ if (pipe_ctx->plane_state->visible)
return true;
if (pipe_ctx->bottom_pipe && is_lower_pipe_tree_visible(pipe_ctx->bottom_pipe))
return true;
static bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
{
- if (pipe_ctx->surface->public.visible)
+ if (pipe_ctx->plane_state->visible)
return true;
if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe))
return true;
static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
{
- if (pipe_ctx->surface->public.visible)
+ if (pipe_ctx->plane_state->visible)
return true;
if (pipe_ctx->top_pipe && is_upper_pipe_tree_visible(pipe_ctx->top_pipe))
return true;
}
}
+static void dcn10_get_surface_visual_confirm_color(
+ const struct pipe_ctx *pipe_ctx,
+ struct tg_color *color)
+{
+ uint32_t color_value = MAX_TG_COLOR_VALUE;
+
+ switch (pipe_ctx->scl_data.format) {
+ case PIXEL_FORMAT_ARGB8888:
+ /* set boarder color to red */
+ color->color_r_cr = color_value;
+ break;
+
+ case PIXEL_FORMAT_ARGB2101010:
+ /* set boarder color to blue */
+ color->color_b_cb = color_value;
+ break;
+ case PIXEL_FORMAT_420BPP8:
+ /* set boarder color to green */
+ color->color_g_y = color_value;
+ break;
+ case PIXEL_FORMAT_420BPP10:
+ /* set boarder color to yellow */
+ color->color_g_y = color_value;
+ color->color_r_cr = color_value;
+ break;
+ case PIXEL_FORMAT_FP16:
+ /* set boarder color to white */
+ color->color_r_cr = color_value;
+ color->color_b_cb = color_value;
+ color->color_g_y = color_value;
+ break;
+ default:
+ break;
+ }
+}
+
static void update_dchubp_dpp(
struct core_dc *dc,
struct pipe_ctx *pipe_ctx,
struct validate_context *context)
{
+ struct dce_hwseq *hws = dc->hwseq;
struct mem_input *mi = pipe_ctx->mi;
struct input_pixel_processor *ipp = pipe_ctx->ipp;
- struct core_surface *surface = pipe_ctx->surface;
- union plane_size size = surface->public.plane_size;
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ union plane_size size = plane_state->plane_size;
struct default_adjustment ocsc = {0};
- struct tg_color black_color = {0};
- struct mpcc_cfg mpcc_cfg;
- bool per_pixel_alpha = surface->public.per_pixel_alpha && pipe_ctx->bottom_pipe;
+ struct mpcc_cfg mpcc_cfg = {0};
+ struct pipe_ctx *top_pipe;
+ bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
/* TODO: proper fix once fpga works */
/* depends on DML calculation, DPP clock value may change dynamically */
enable_dppclk(
- dc->ctx,
+ dc->hwseq,
pipe_ctx->pipe_idx,
pipe_ctx->pix_clk_params.requested_pix_clk,
context->bw.dcn.calc_clk.dppclk_div);
context->bw.dcn.calc_clk.dppclk_div;
context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
- select_vtg(dc->ctx, pipe_ctx->pipe_idx, pipe_ctx->tg->inst);
+ /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
+ * VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
+ * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
+ */
+ REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->tg->inst);
update_plane_addr(dc, pipe_ctx);
if (dc->public.config.gpu_vm_support)
mi->funcs->mem_input_program_pte_vm(
pipe_ctx->mi,
- surface->public.format,
- &surface->public.tiling_info,
- surface->public.rotation);
+ plane_state->format,
+ &plane_state->tiling_info,
+ plane_state->rotation);
ipp->funcs->ipp_setup(ipp,
- surface->public.format,
+ plane_state->format,
1,
IPP_OUTPUT_FORMAT_12_BIT_FIX);
- pipe_ctx->scl_data.lb_params.alpha_en = per_pixel_alpha;
- mpcc_cfg.top_dpp_id = pipe_ctx->pipe_idx;
- if (pipe_ctx->bottom_pipe)
- mpcc_cfg.bot_mpcc_id = pipe_ctx->bottom_pipe->mpcc->inst;
+ mpcc_cfg.mi = mi;
+ mpcc_cfg.opp = pipe_ctx->opp;
+ for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
+ mpcc_cfg.z_index++;
+ if (dc->public.debug.surface_visual_confirm)
+ dcn10_get_surface_visual_confirm_color(
+ pipe_ctx, &mpcc_cfg.black_color);
else
- mpcc_cfg.bot_mpcc_id = 0xf;
- mpcc_cfg.opp_id = pipe_ctx->tg->inst;
- mpcc_cfg.top_of_tree = pipe_ctx->pipe_idx == pipe_ctx->tg->inst;
+ color_space_to_black_color(
+ dc, pipe_ctx->stream->output_color_space,
+ &mpcc_cfg.black_color);
mpcc_cfg.per_pixel_alpha = per_pixel_alpha;
/* DCN1.0 has output CM before MPC which seems to screw with
* pre-multiplied alpha.
*/
mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
- pipe_ctx->stream->public.output_color_space)
+ pipe_ctx->stream->output_color_space)
&& per_pixel_alpha;
- pipe_ctx->mpcc->funcs->set(pipe_ctx->mpcc, &mpcc_cfg);
-
- color_space_to_black_color(
- dc, pipe_ctx->stream->public.output_color_space, &black_color);
- pipe_ctx->mpcc->funcs->set_bg_color(pipe_ctx->mpcc, &black_color);
+ dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
+ pipe_ctx->scl_data.lb_params.alpha_en = per_pixel_alpha;
pipe_ctx->scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
/* scaler configuration */
pipe_ctx->xfm->funcs->transform_set_scaler(
pipe_ctx->xfm, &pipe_ctx->scl_data);
+ mi->funcs->mem_program_viewport(mi,
+ &pipe_ctx->scl_data.viewport, &pipe_ctx->scl_data.viewport_c);
/*gamut remap*/
program_gamut_remap(pipe_ctx);
/*TODO add adjustments parameters*/
- ocsc.out_color_space = pipe_ctx->stream->public.output_color_space;
- pipe_ctx->opp->funcs->opp_set_csc_default(pipe_ctx->opp, &ocsc);
+ ocsc.out_color_space = pipe_ctx->stream->output_color_space;
+ pipe_ctx->xfm->funcs->opp_set_csc_default(pipe_ctx->xfm, &ocsc);
mi->funcs->mem_input_program_surface_config(
mi,
- surface->public.format,
- &surface->public.tiling_info,
+ plane_state->format,
+ &plane_state->tiling_info,
&size,
- surface->public.rotation,
- &surface->public.dcc,
- surface->public.horizontal_mirror);
+ plane_state->rotation,
+ &plane_state->dcc,
+ plane_state->horizontal_mirror);
mi->funcs->set_blank(mi, !is_pipe_tree_visible(pipe_ctx));
}
* this OTG. this is done only one time.
*/
/* watermark is for all pipes */
- pipe_ctx->mi->funcs->program_watermarks(
- pipe_ctx->mi, &context->bw.dcn.watermarks, ref_clk_mhz);
+ program_watermarks(dc->hwseq, &context->bw.dcn.watermarks, ref_clk_mhz);
+
+ if (dc->public.debug.sanity_checks) {
+ /* pstate stuck check after watermark update */
+ verify_allow_pstate_change_high(dc->hwseq);
+ }
+
pipe_ctx->tg->funcs->lock(pipe_ctx->tg);
pipe_ctx->tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset;
pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, !is_pipe_tree_visible(pipe_ctx));
}
- if (pipe_ctx->surface != NULL) {
+ if (pipe_ctx->plane_state != NULL) {
dcn10_power_on_fe(dc, pipe_ctx, context);
update_dchubp_dpp(dc, pipe_ctx, context);
}
+ if (dc->public.debug.sanity_checks) {
+ /* pstate stuck check after each pipe is programmed */
+ verify_allow_pstate_change_high(dc->hwseq);
+ }
+
if (pipe_ctx->bottom_pipe != NULL)
program_all_pipe_in_tree(dc, pipe_ctx->bottom_pipe, context);
}
static void dcn10_apply_ctx_for_surface(
struct core_dc *dc,
- struct core_surface *surface,
+ const struct dc_plane_state *plane_state,
struct validate_context *context)
{
- int i;
+ int i, be_idx;
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+
+ if (!plane_state)
+ return;
+
+ for (be_idx = 0; be_idx < dc->res_pool->pipe_count; be_idx++)
+ if (plane_state == context->res_ctx.pipe_ctx[be_idx].plane_state)
+ break;
/* reset unused mpcc */
- /*for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *old_pipe_ctx =
&dc->current_context->res_ctx.pipe_ctx[i];
- if ((!pipe_ctx->surface && old_pipe_ctx->surface)
+ if (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state)
+ continue;
+
+ /*
+ * Powergate reused pipes that are not powergated
+ * fairly hacky right now, using opp_id as indicator
+ */
+
+ if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
+ if (pipe_ctx->mi->opp_id != 0xf && pipe_ctx->tg->inst == be_idx) {
+ dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
+ /*
+ * power down fe will unlock when calling reset, need
+ * to lock it back here. Messy, need rework.
+ */
+ pipe_ctx->tg->funcs->lock(pipe_ctx->tg);
+ }
+ }
+
+
+ if ((!pipe_ctx->plane_state && old_pipe_ctx->plane_state)
|| (!pipe_ctx->stream && old_pipe_ctx->stream)) {
- struct mpcc_cfg mpcc_cfg;
+ if (old_pipe_ctx->tg->inst != be_idx)
+ continue;
+
+ if (!old_pipe_ctx->top_pipe) {
+ ASSERT(0);
+ continue;
+ }
+
+ /* reset mpc */
+ dc->res_pool->mpc->funcs->remove(
+ dc->res_pool->mpc,
+ old_pipe_ctx->opp,
+ old_pipe_ctx->pipe_idx);
+ old_pipe_ctx->opp->mpcc_disconnect_pending[old_pipe_ctx->mi->mpcc_id] = true;
- mpcc_cfg.opp_id = 0xf;
- mpcc_cfg.top_dpp_id = 0xf;
- mpcc_cfg.bot_mpcc_id = 0xf;
- mpcc_cfg.top_of_tree = !old_pipe_ctx->top_pipe;
- old_pipe_ctx->mpcc->funcs->set(old_pipe_ctx->mpcc, &mpcc_cfg);
+ /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+ "[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
+ old_pipe_ctx->mpcc->inst);*/
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
old_pipe_ctx->top_pipe = NULL;
old_pipe_ctx->bottom_pipe = NULL;
- old_pipe_ctx->surface = NULL;
+ old_pipe_ctx->plane_state = NULL;
dm_logger_write(dc->ctx->logger, LOG_DC,
"Reset mpcc for pipe %d\n",
old_pipe_ctx->pipe_idx);
}
- }*/
-
- if (!surface)
- return;
+ }
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
- if (pipe_ctx->surface != surface)
+ if (pipe_ctx->plane_state != plane_state)
continue;
/* looking for top pipe to program */
context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns,
context->bw.dcn.watermarks.d.pte_meta_urgent_ns
);
+
+ if (dc->public.debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
}
static void dcn10_set_bandwidth(
context->bw.dcn.calc_clk.min_active_dram_ccm_us;
}
dcn10_pplib_apply_display_requirements(dc, context);
+
+ /* need to fix this function. not doing the right thing here */
}
static void set_drr(struct pipe_ctx **pipe_ctx,
program_gamut_remap(pipe_ctx);
}
-static void dcn10_config_stereo_parameters(struct core_stream *stream,\
- struct crtc_stereo_flags *flags)
+static void dcn10_config_stereo_parameters(
+ struct dc_stream_state *stream, struct crtc_stereo_flags *flags)
{
- enum view_3d_format view_format = stream->public.view_format;
+ enum view_3d_format view_format = stream->view_format;
enum dc_timing_3d_format timing_3d_format =\
- stream->public.timing.timing_3d_format;
+ stream->timing.timing_3d_format;
bool non_stereo_timing = false;
if (timing_3d_format == TIMING_3D_FORMAT_NONE ||
timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
enum display_dongle_type dongle = \
- stream->sink->link->public.ddc->dongle_type;
+ stream->sink->link->ddc->dongle_type;
if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
flags->DISABLE_STEREO_DP_SYNC = 1;
}
flags->RIGHT_EYE_POLARITY =\
- stream->public.timing.flags.RIGHT_EYE_3D_POLARITY;
+ stream->timing.flags.RIGHT_EYE_3D_POLARITY;
if (timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
flags->FRAME_PACKED = 1;
}
return;
}
-static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx,
- struct core_dc *dc)
+static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct core_dc *dc)
{
struct crtc_stereo_flags flags = { 0 };
- struct core_stream *stream = pipe_ctx->stream;
+ struct dc_stream_state *stream = pipe_ctx->stream;
dcn10_config_stereo_parameters(stream, &flags);
pipe_ctx->opp->funcs->opp_set_stereo_polarity(
pipe_ctx->opp,
flags.PROGRAM_STEREO == 1 ? true:false,
- stream->public.timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
+ stream->timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
pipe_ctx->tg->funcs->program_stereo(
pipe_ctx->tg,
- &stream->public.timing,
+ &stream->timing,
&flags);
+ return;
+}
- return;
+static void log_mpc_crc(struct core_dc *dc)
+{
+ struct dc_context *dc_ctx = dc->ctx;
+ struct dce_hwseq *hws = dc->hwseq;
+
+ if (REG(MPC_CRC_RESULT_GB))
+ DTN_INFO("MPC_CRC_RESULT_GB:%d MPC_CRC_RESULT_C:%d MPC_CRC_RESULT_AR:%d\n",
+ REG_READ(MPC_CRC_RESULT_GB), REG_READ(MPC_CRC_RESULT_C), REG_READ(MPC_CRC_RESULT_AR));
+ if (REG(DPP_TOP0_DPP_CRC_VAL_B_A))
+ DTN_INFO("DPP_TOP0_DPP_CRC_VAL_B_A:%d DPP_TOP0_DPP_CRC_VAL_R_G:%d\n",
+ REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G));
+}
+
+static void dcn10_log_hw_state(struct core_dc *dc)
+{
+ struct dc_context *dc_ctx = dc->ctx;
+ struct resource_pool *pool = dc->res_pool;
+ int i;
+
+ DTN_INFO_BEGIN();
+
+ DTN_INFO("HUBP:\t format \t addr_hi \t width \t height \t rotation \t"
+ "mirror \t sw_mode \t dcc_en \t blank_en \t ttu_dis \t"
+ "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
+
+ for (i = 0; i < pool->pipe_count; i++) {
+ struct mem_input *mi = pool->mis[i];
+ struct dcn_hubp_state s;
+
+ dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s);
+
+ DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t %xh \t %xh \t "
+ "%d \t %d \t %d \t %d \t"
+ "%d \t %d \t %d \n",
+ i,
+ s.pixel_format,
+ s.inuse_addr_hi,
+ s.viewport_width,
+ s.viewport_height,
+ s.rotation_angle,
+ s.h_mirror_en,
+ s.sw_mode,
+ s.dcc_en,
+ s.blank_en,
+ s.ttu_disable,
+ s.min_ttu_vblank,
+ s.qos_level_low_wm,
+ s.qos_level_high_wm);
+ }
+ DTN_INFO("\n");
+
+ log_mpc_crc(dc);
+
+ DTN_INFO_END();
+}
+
+static void dcn10_wait_for_mpcc_disconnect(
+ struct core_dc *dc,
+ struct resource_pool *res_pool,
+ struct pipe_ctx *pipe_ctx)
+{
+ int i;
+
+ if (!pipe_ctx->opp)
+ return;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ if (pipe_ctx->opp->mpcc_disconnect_pending[i]) {
+ res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
+ pipe_ctx->opp->mpcc_disconnect_pending[i] = false;
+ res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true);
+ /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+ "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
+ i);*/
+ }
+ }
+
+}
+
+static bool dcn10_dummy_display_power_gating(
+ struct core_dc *dc,
+ uint8_t controller_id,
+ struct dc_bios *dcb,
+ enum pipe_gating_control power_gating)
+{
+ return true;
+}
+
+void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ struct timing_generator *tg = pipe_ctx->tg;
+
+ if (plane_state->ctx->dc->debug.sanity_checks) {
+ struct core_dc *dc = DC_TO_CORE(plane_state->ctx->dc);
+
+ verify_allow_pstate_change_high(dc->hwseq);
+ }
+
+ if (plane_state == NULL)
+ return;
+
+ plane_state->status.is_flip_pending =
+ pipe_ctx->mi->funcs->mem_input_is_flip_pending(
+ pipe_ctx->mi);
+
+ /* DCN we read INUSE address in MI, do we still need this wa? */
+ if (plane_state->status.is_flip_pending &&
+ !plane_state->visible) {
+ pipe_ctx->mi->current_address =
+ pipe_ctx->mi->request_address;
+ BREAK_TO_DEBUGGER();
+ }
+
+ plane_state->status.current_address = pipe_ctx->mi->current_address;
+ if (pipe_ctx->mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+ tg->funcs->is_stereo_left_eye) {
+ plane_state->status.is_right_eye =
+ !tg->funcs->is_stereo_left_eye(pipe_ctx->tg);
+ }
}
static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap,
.program_csc_matrix = program_csc_matrix,
- .init_hw = init_hw,
+ .init_hw = dcn10_init_hw,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
.set_plane_config = set_plane_config,
.update_plane_addr = update_plane_addr,
- .update_pending_status = dce110_update_pending_status,
+ .update_dchub = dcn10_update_dchub,
+ .update_pending_status = dcn10_update_pending_status,
.set_input_transfer_func = dcn10_set_input_transfer_func,
.set_output_transfer_func = dcn10_set_output_transfer_func,
.power_down = dce110_power_down,
.enable_stream = dce110_enable_stream,
.disable_stream = dce110_disable_stream,
.unblank_stream = dce110_unblank_stream,
- .enable_display_pipe_clock_gating = NULL, /* TODOFPGA */
- .enable_display_power_gating = dcn10_enable_display_power_gating,
+ .enable_display_power_gating = dcn10_dummy_display_power_gating,
.power_down_front_end = dcn10_power_down_fe,
.power_on_front_end = dcn10_power_on_fe,
.pipe_control_lock = dcn10_pipe_control_lock,
.set_drr = set_drr,
.get_position = get_position,
.set_static_screen_control = set_static_screen_control,
- .setup_stereo = dcn10_setup_stereo
+ .setup_stereo = dcn10_setup_stereo,
+ .set_avmute = dce110_set_avmute,
+ .log_hw_state = dcn10_log_hw_state,
+ .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect
};
-bool dcn10_hw_sequencer_construct(struct core_dc *dc)
+void dcn10_hw_sequencer_construct(struct core_dc *dc)
{
dc->hwss = dcn10_funcs;
- return true;
}