mirror of https://gitee.com/openkylin/linux.git
drm/i915: move clock gating functionality into intel_pm module
This moves the clock gating-related functions into intel_pm module. Also, please note that we do change the function type from static to non-static in this patch for the move, to prevent breaking bisecting with non-working intermediate commit. Those are returned back to static form in the following patch which setups a generic PM initialization function, which was split into a different one to simplify review. v2: rebase on top of latest drm-intel-next-queued to incorporate all the changes that went there meanwhile. Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Acked-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
dde18883de
commit
6f1d69b04f
|
@ -1515,7 +1515,7 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
|
|||
* Plane regs are double buffered, going from enabled->disabled needs a
|
||||
* trigger in order to latch. The display address reg provides this.
|
||||
*/
|
||||
static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
|
||||
void intel_flush_display_plane(struct drm_i915_private *dev_priv,
|
||||
enum plane plane)
|
||||
{
|
||||
I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane)));
|
||||
|
@ -6351,359 +6351,6 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
|
|||
.output_poll_changed = intel_fb_output_poll_changed,
|
||||
};
|
||||
|
||||
static void ironlake_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
/* Required for FBC */
|
||||
dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
|
||||
DPFCRUNIT_CLOCK_GATE_DISABLE |
|
||||
DPFDUNIT_CLOCK_GATE_DISABLE;
|
||||
/* Required for CxSR */
|
||||
dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_3DCGDIS0,
|
||||
MARIUNIT_CLOCK_GATE_DISABLE |
|
||||
SVSMUNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(PCH_3DCGDIS1,
|
||||
VFMUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
/*
|
||||
* According to the spec the following bits should be set in
|
||||
* order to enable memory self-refresh
|
||||
* The bit 22/21 of 0x42004
|
||||
* The bit 5 of 0x42020
|
||||
* The bit 15 of 0x45000
|
||||
*/
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
(I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE | ILK_VSDPFD_FULL));
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
(I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPARB_CLK_GATE));
|
||||
I915_WRITE(DISP_ARB_CTL,
|
||||
(I915_READ(DISP_ARB_CTL) |
|
||||
DISP_FBC_WM_DIS));
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/*
|
||||
* Based on the document from hardware guys the following bits
|
||||
* should be set unconditionally in order to enable FBC.
|
||||
* The bit 22 of 0x42000
|
||||
* The bit 22 of 0x42004
|
||||
* The bit 7,8,9 of 0x42020.
|
||||
*/
|
||||
if (IS_IRONLAKE_M(dev)) {
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN1,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN1) |
|
||||
ILK_FBCQ_DIS);
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE);
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPFC_DIS1 |
|
||||
ILK_DPFC_DIS2 |
|
||||
ILK_CLK_FBC);
|
||||
}
|
||||
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_ELPIN_409_SELECT);
|
||||
I915_WRITE(_3D_CHICKEN2,
|
||||
_3D_CHICKEN2_WM_READ_PIPELINED << 16 |
|
||||
_3D_CHICKEN2_WM_READ_PIPELINED);
|
||||
}
|
||||
|
||||
static void gen6_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_ELPIN_409_SELECT);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* clear masked bit */
|
||||
I915_WRITE(CACHE_MODE_0,
|
||||
CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);
|
||||
|
||||
I915_WRITE(GEN6_UCGCTL1,
|
||||
I915_READ(GEN6_UCGCTL1) |
|
||||
GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
|
||||
GEN6_CSUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
|
||||
* gating disable must be set. Failure to set it results in
|
||||
* flickering pixels due to Z write ordering failures after
|
||||
* some amount of runtime in the Mesa "fire" demo, and Unigine
|
||||
* Sanctuary and Tropics, and apparently anything else with
|
||||
* alpha test or pixel discard.
|
||||
*
|
||||
* According to the spec, bit 11 (RCCUNIT) must also be set,
|
||||
* but we didn't debug actual testcases to find it out.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2,
|
||||
GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
|
||||
GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* Bspec says we need to always set all mask bits. */
|
||||
I915_WRITE(_3D_CHICKEN, (0xFFFF << 16) |
|
||||
_3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL);
|
||||
|
||||
/*
|
||||
* According to the spec the following bits should be
|
||||
* set in order to enable memory self-refresh and fbc:
|
||||
* The bit21 and bit22 of 0x42000
|
||||
* The bit21 and bit22 of 0x42004
|
||||
* The bit5 and bit7 of 0x42020
|
||||
* The bit14 of 0x70180
|
||||
* The bit14 of 0x71180
|
||||
*/
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN1,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN1) |
|
||||
ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE | ILK_VSDPFD_FULL);
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPARB_CLK_GATE |
|
||||
ILK_DPFD_CLK_GATE);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
}
|
||||
|
||||
static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
|
||||
|
||||
reg &= ~GEN7_FF_SCHED_MASK;
|
||||
reg |= GEN7_FF_TS_SCHED_HW;
|
||||
reg |= GEN7_FF_VS_SCHED_HW;
|
||||
reg |= GEN7_FF_DS_SCHED_HW;
|
||||
|
||||
I915_WRITE(GEN7_FF_THREAD_MODE, reg);
|
||||
}
|
||||
|
||||
static void ivybridge_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
|
||||
* This implements the WaDisableRCZUnitClockGating workaround.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
|
||||
|
||||
I915_WRITE(IVB_CHICKEN3,
|
||||
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
|
||||
CHICKEN3_DGMG_DONE_FIX_DISABLE);
|
||||
|
||||
/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
|
||||
I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
|
||||
GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
|
||||
|
||||
/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
|
||||
I915_WRITE(GEN7_L3CNTLREG1,
|
||||
GEN7_WA_FOR_GEN7_L3_CONTROL);
|
||||
I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
|
||||
GEN7_WA_L3_CHICKEN_MODE);
|
||||
|
||||
/* This is required by WaCatErrorRejectionIssue */
|
||||
I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||
I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
||||
GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
|
||||
gen7_setup_fixed_func_scheduler(dev_priv);
|
||||
}
|
||||
|
||||
static void valleyview_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
|
||||
* This implements the WaDisableRCZUnitClockGating workaround.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
|
||||
|
||||
I915_WRITE(IVB_CHICKEN3,
|
||||
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
|
||||
CHICKEN3_DGMG_DONE_FIX_DISABLE);
|
||||
|
||||
/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
|
||||
I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
|
||||
GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
|
||||
|
||||
/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
|
||||
I915_WRITE(GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL);
|
||||
I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
|
||||
|
||||
/* This is required by WaCatErrorRejectionIssue */
|
||||
I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||
I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
||||
GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
|
||||
I915_WRITE(CACHE_MODE_1, I915_READ(CACHE_MODE_1) |
|
||||
(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE << 16) |
|
||||
PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
|
||||
}
|
||||
|
||||
static void g4x_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t dspclk_gate;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, 0);
|
||||
I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
|
||||
GS_UNIT_CLOCK_GATE_DISABLE |
|
||||
CL_UNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
|
||||
OVRUNIT_CLOCK_GATE_DISABLE |
|
||||
OVCUNIT_CLOCK_GATE_DISABLE;
|
||||
if (IS_GM45(dev))
|
||||
dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
|
||||
I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
|
||||
}
|
||||
|
||||
static void crestline_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
I915_WRITE(DSPCLK_GATE_D, 0);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
I915_WRITE16(DEUC, 0);
|
||||
}
|
||||
|
||||
static void broadwater_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
|
||||
I965_RCC_CLOCK_GATE_DISABLE |
|
||||
I965_RCPB_CLOCK_GATE_DISABLE |
|
||||
I965_ISC_CLOCK_GATE_DISABLE |
|
||||
I965_FBC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
}
|
||||
|
||||
static void gen3_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 dstate = I915_READ(D_STATE);
|
||||
|
||||
dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
|
||||
DSTATE_DOT_CLOCK_GATING;
|
||||
I915_WRITE(D_STATE, dstate);
|
||||
}
|
||||
|
||||
static void i85x_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
static void i830_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
static void ibx_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
/*
|
||||
* On Ibex Peak and Cougar Point, we need to disable clock
|
||||
* gating for the panel power sequencer or it will fail to
|
||||
* start up when no ports are active.
|
||||
*/
|
||||
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
static void cpt_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
/*
|
||||
* On Ibex Peak and Cougar Point, we need to disable clock
|
||||
* gating for the panel power sequencer or it will fail to
|
||||
* start up when no ports are active.
|
||||
*/
|
||||
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
|
||||
DPLS_EDP_PPS_FIX_DIS);
|
||||
/* Without this, mode sets may fail silently on FDI */
|
||||
for_each_pipe(pipe)
|
||||
I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS);
|
||||
}
|
||||
|
||||
void intel_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
dev_priv->display.init_clock_gating(dev);
|
||||
|
||||
if (dev_priv->display.init_pch_clock_gating)
|
||||
dev_priv->display.init_pch_clock_gating(dev);
|
||||
}
|
||||
|
||||
/* Set up chip specific display functions */
|
||||
static void intel_init_display(struct drm_device *dev)
|
||||
{
|
||||
|
|
|
@ -339,6 +339,8 @@ extern bool intel_dpd_is_edp(struct drm_device *dev);
|
|||
extern void intel_edp_link_config(struct intel_encoder *, int *, int *);
|
||||
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
|
||||
extern int intel_plane_init(struct drm_device *dev, enum pipe pipe);
|
||||
extern void intel_flush_display_plane(struct drm_i915_private *dev_priv,
|
||||
enum plane plane);
|
||||
|
||||
/* intel_panel.c */
|
||||
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
|
||||
|
@ -490,4 +492,18 @@ extern int i85x_get_fifo_size(struct drm_device *dev, int plane);
|
|||
extern int i845_get_fifo_size(struct drm_device *dev, int plane);
|
||||
extern int i830_get_fifo_size(struct drm_device *dev, int plane);
|
||||
|
||||
/* Clock gating */
|
||||
extern void ironlake_init_clock_gating(struct drm_device *dev);
|
||||
extern void gen6_init_clock_gating(struct drm_device *dev);
|
||||
extern void ivybridge_init_clock_gating(struct drm_device *dev);
|
||||
extern void valleyview_init_clock_gating(struct drm_device *dev);
|
||||
extern void g4x_init_clock_gating(struct drm_device *dev);
|
||||
extern void crestline_init_clock_gating(struct drm_device *dev);
|
||||
extern void broadwater_init_clock_gating(struct drm_device *dev);
|
||||
extern void gen3_init_clock_gating(struct drm_device *dev);
|
||||
extern void i85x_init_clock_gating(struct drm_device *dev);
|
||||
extern void i830_init_clock_gating(struct drm_device *dev);
|
||||
extern void ibx_init_clock_gating(struct drm_device *dev);
|
||||
extern void cpt_init_clock_gating(struct drm_device *dev);
|
||||
|
||||
#endif /* __INTEL_DRV_H__ */
|
||||
|
|
|
@ -2578,3 +2578,356 @@ void intel_init_emon(struct drm_device *dev)
|
|||
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
|
||||
}
|
||||
|
||||
void ironlake_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
/* Required for FBC */
|
||||
dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
|
||||
DPFCRUNIT_CLOCK_GATE_DISABLE |
|
||||
DPFDUNIT_CLOCK_GATE_DISABLE;
|
||||
/* Required for CxSR */
|
||||
dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_3DCGDIS0,
|
||||
MARIUNIT_CLOCK_GATE_DISABLE |
|
||||
SVSMUNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(PCH_3DCGDIS1,
|
||||
VFMUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
/*
|
||||
* According to the spec the following bits should be set in
|
||||
* order to enable memory self-refresh
|
||||
* The bit 22/21 of 0x42004
|
||||
* The bit 5 of 0x42020
|
||||
* The bit 15 of 0x45000
|
||||
*/
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
(I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE | ILK_VSDPFD_FULL));
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
(I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPARB_CLK_GATE));
|
||||
I915_WRITE(DISP_ARB_CTL,
|
||||
(I915_READ(DISP_ARB_CTL) |
|
||||
DISP_FBC_WM_DIS));
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/*
|
||||
* Based on the document from hardware guys the following bits
|
||||
* should be set unconditionally in order to enable FBC.
|
||||
* The bit 22 of 0x42000
|
||||
* The bit 22 of 0x42004
|
||||
* The bit 7,8,9 of 0x42020.
|
||||
*/
|
||||
if (IS_IRONLAKE_M(dev)) {
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN1,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN1) |
|
||||
ILK_FBCQ_DIS);
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE);
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPFC_DIS1 |
|
||||
ILK_DPFC_DIS2 |
|
||||
ILK_CLK_FBC);
|
||||
}
|
||||
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_ELPIN_409_SELECT);
|
||||
I915_WRITE(_3D_CHICKEN2,
|
||||
_3D_CHICKEN2_WM_READ_PIPELINED << 16 |
|
||||
_3D_CHICKEN2_WM_READ_PIPELINED);
|
||||
}
|
||||
|
||||
void gen6_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_ELPIN_409_SELECT);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* clear masked bit */
|
||||
I915_WRITE(CACHE_MODE_0,
|
||||
CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);
|
||||
|
||||
I915_WRITE(GEN6_UCGCTL1,
|
||||
I915_READ(GEN6_UCGCTL1) |
|
||||
GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
|
||||
GEN6_CSUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
|
||||
* gating disable must be set. Failure to set it results in
|
||||
* flickering pixels due to Z write ordering failures after
|
||||
* some amount of runtime in the Mesa "fire" demo, and Unigine
|
||||
* Sanctuary and Tropics, and apparently anything else with
|
||||
* alpha test or pixel discard.
|
||||
*
|
||||
* According to the spec, bit 11 (RCCUNIT) must also be set,
|
||||
* but we didn't debug actual testcases to find it out.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2,
|
||||
GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
|
||||
GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* Bspec says we need to always set all mask bits. */
|
||||
I915_WRITE(_3D_CHICKEN, (0xFFFF << 16) |
|
||||
_3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL);
|
||||
|
||||
/*
|
||||
* According to the spec the following bits should be
|
||||
* set in order to enable memory self-refresh and fbc:
|
||||
* The bit21 and bit22 of 0x42000
|
||||
* The bit21 and bit22 of 0x42004
|
||||
* The bit5 and bit7 of 0x42020
|
||||
* The bit14 of 0x70180
|
||||
* The bit14 of 0x71180
|
||||
*/
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN1,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN1) |
|
||||
ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
|
||||
I915_WRITE(ILK_DISPLAY_CHICKEN2,
|
||||
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
||||
ILK_DPARB_GATE | ILK_VSDPFD_FULL);
|
||||
I915_WRITE(ILK_DSPCLK_GATE,
|
||||
I915_READ(ILK_DSPCLK_GATE) |
|
||||
ILK_DPARB_CLK_GATE |
|
||||
ILK_DPFD_CLK_GATE);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
}
|
||||
|
||||
static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
|
||||
|
||||
reg &= ~GEN7_FF_SCHED_MASK;
|
||||
reg |= GEN7_FF_TS_SCHED_HW;
|
||||
reg |= GEN7_FF_VS_SCHED_HW;
|
||||
reg |= GEN7_FF_DS_SCHED_HW;
|
||||
|
||||
I915_WRITE(GEN7_FF_THREAD_MODE, reg);
|
||||
}
|
||||
|
||||
void ivybridge_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
|
||||
* This implements the WaDisableRCZUnitClockGating workaround.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
|
||||
|
||||
I915_WRITE(IVB_CHICKEN3,
|
||||
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
|
||||
CHICKEN3_DGMG_DONE_FIX_DISABLE);
|
||||
|
||||
/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
|
||||
I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
|
||||
GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
|
||||
|
||||
/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
|
||||
I915_WRITE(GEN7_L3CNTLREG1,
|
||||
GEN7_WA_FOR_GEN7_L3_CONTROL);
|
||||
I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
|
||||
GEN7_WA_L3_CHICKEN_MODE);
|
||||
|
||||
/* This is required by WaCatErrorRejectionIssue */
|
||||
I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||
I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
||||
GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
|
||||
gen7_setup_fixed_func_scheduler(dev_priv);
|
||||
}
|
||||
|
||||
void valleyview_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
|
||||
|
||||
I915_WRITE(WM3_LP_ILK, 0);
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
|
||||
* This implements the WaDisableRCZUnitClockGating workaround.
|
||||
*/
|
||||
I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
|
||||
|
||||
I915_WRITE(IVB_CHICKEN3,
|
||||
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
|
||||
CHICKEN3_DGMG_DONE_FIX_DISABLE);
|
||||
|
||||
/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
|
||||
I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
|
||||
GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
|
||||
|
||||
/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
|
||||
I915_WRITE(GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL);
|
||||
I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
|
||||
|
||||
/* This is required by WaCatErrorRejectionIssue */
|
||||
I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
|
||||
I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
|
||||
GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
I915_WRITE(DSPCNTR(pipe),
|
||||
I915_READ(DSPCNTR(pipe)) |
|
||||
DISPPLANE_TRICKLE_FEED_DISABLE);
|
||||
intel_flush_display_plane(dev_priv, pipe);
|
||||
}
|
||||
|
||||
I915_WRITE(CACHE_MODE_1, I915_READ(CACHE_MODE_1) |
|
||||
(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE << 16) |
|
||||
PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
|
||||
}
|
||||
|
||||
void g4x_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t dspclk_gate;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, 0);
|
||||
I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
|
||||
GS_UNIT_CLOCK_GATE_DISABLE |
|
||||
CL_UNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
|
||||
OVRUNIT_CLOCK_GATE_DISABLE |
|
||||
OVCUNIT_CLOCK_GATE_DISABLE;
|
||||
if (IS_GM45(dev))
|
||||
dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
|
||||
I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
|
||||
}
|
||||
|
||||
void crestline_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
I915_WRITE(DSPCLK_GATE_D, 0);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
I915_WRITE16(DEUC, 0);
|
||||
}
|
||||
|
||||
void broadwater_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
|
||||
I965_RCC_CLOCK_GATE_DISABLE |
|
||||
I965_RCPB_CLOCK_GATE_DISABLE |
|
||||
I965_ISC_CLOCK_GATE_DISABLE |
|
||||
I965_FBC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
}
|
||||
|
||||
void gen3_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 dstate = I915_READ(D_STATE);
|
||||
|
||||
dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
|
||||
DSTATE_DOT_CLOCK_GATING;
|
||||
I915_WRITE(D_STATE, dstate);
|
||||
}
|
||||
|
||||
void i85x_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
void i830_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
void ibx_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
/*
|
||||
* On Ibex Peak and Cougar Point, we need to disable clock
|
||||
* gating for the panel power sequencer or it will fail to
|
||||
* start up when no ports are active.
|
||||
*/
|
||||
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
|
||||
void cpt_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
/*
|
||||
* On Ibex Peak and Cougar Point, we need to disable clock
|
||||
* gating for the panel power sequencer or it will fail to
|
||||
* start up when no ports are active.
|
||||
*/
|
||||
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
|
||||
DPLS_EDP_PPS_FIX_DIS);
|
||||
/* Without this, mode sets may fail silently on FDI */
|
||||
for_each_pipe(pipe)
|
||||
I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS);
|
||||
}
|
||||
|
||||
void intel_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
dev_priv->display.init_clock_gating(dev);
|
||||
|
||||
if (dev_priv->display.init_pch_clock_gating)
|
||||
dev_priv->display.init_pch_clock_gating(dev);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue