Commit 95534263 authored by Li Peng's avatar Li Peng Committed by Eric Anholt

drm/i915: Add CxSR support on Pineview DDR3

Pineview with DDR3 memory has different latencies to enable CxSR.
This patch updates CxSR latency table to add Pineview DDR3 latency
configuration. It also adds one flag "is_ddr3" for checking DDR3
setting in MCHBAR.

Cc: Shaohua Li <shaohua.li@intel.com>
Cc: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: default avatarLi Peng <peng.li@intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent d8201ab6
...@@ -1491,6 +1491,10 @@ static void i915_pineview_get_mem_freq(struct drm_device *dev) ...@@ -1491,6 +1491,10 @@ static void i915_pineview_get_mem_freq(struct drm_device *dev)
dev_priv->mem_freq = 800; dev_priv->mem_freq = 800;
break; break;
} }
/* detect pineview DDR3 setting */
tmp = I915_READ(CSHRDDR3CTL);
dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
} }
static void i915_ironlake_get_mem_freq(struct drm_device *dev) static void i915_ironlake_get_mem_freq(struct drm_device *dev)
......
...@@ -326,7 +326,7 @@ typedef struct drm_i915_private { ...@@ -326,7 +326,7 @@ typedef struct drm_i915_private {
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */
unsigned int fsb_freq, mem_freq; unsigned int fsb_freq, mem_freq, is_ddr3;
spinlock_t error_lock; spinlock_t error_lock;
struct drm_i915_error_state *first_error; struct drm_i915_error_state *first_error;
......
...@@ -817,6 +817,10 @@ ...@@ -817,6 +817,10 @@
#define DCC_CHANNEL_XOR_DISABLE (1 << 10) #define DCC_CHANNEL_XOR_DISABLE (1 << 10)
#define DCC_CHANNEL_XOR_BIT_17 (1 << 9) #define DCC_CHANNEL_XOR_BIT_17 (1 << 9)
/** Pineview MCH register contains DDR3 setting */
#define CSHRDDR3CTL 0x101a8
#define CSHRDDR3CTL_DDR3 (1 << 2)
/** 965 MCH register controlling DRAM channel configuration */ /** 965 MCH register controlling DRAM channel configuration */
#define C0DRB3 0x10206 #define C0DRB3 0x10206
#define C1DRB3 0x10606 #define C1DRB3 0x10606
......
...@@ -2640,6 +2640,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, ...@@ -2640,6 +2640,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
struct cxsr_latency { struct cxsr_latency {
int is_desktop; int is_desktop;
int is_ddr3;
unsigned long fsb_freq; unsigned long fsb_freq;
unsigned long mem_freq; unsigned long mem_freq;
unsigned long display_sr; unsigned long display_sr;
...@@ -2649,33 +2650,45 @@ struct cxsr_latency { ...@@ -2649,33 +2650,45 @@ struct cxsr_latency {
}; };
static struct cxsr_latency cxsr_latency_table[] = { static struct cxsr_latency cxsr_latency_table[] = {
{1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */
{1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */
{1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */
{1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */
{1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */
{1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */
{1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */
{1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */
{1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */
{1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */
{1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */
{0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */
{0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */
{0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */
{1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */
{0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */
{0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */
{0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */
{0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */
{0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */
{0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */
{0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */
{0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */
{0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */
{0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */
{0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */
{0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */
{0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */
{0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */
{0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */
{0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */
{0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */
}; };
static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3,
int mem) int fsb, int mem)
{ {
int i; int i;
struct cxsr_latency *latency; struct cxsr_latency *latency;
...@@ -2686,6 +2699,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, ...@@ -2686,6 +2699,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
latency = &cxsr_latency_table[i]; latency = &cxsr_latency_table[i];
if (is_desktop == latency->is_desktop && if (is_desktop == latency->is_desktop &&
is_ddr3 == latency->is_ddr3 &&
fsb == latency->fsb_freq && mem == latency->mem_freq) fsb == latency->fsb_freq && mem == latency->mem_freq)
return latency; return latency;
} }
...@@ -2800,8 +2814,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, ...@@ -2800,8 +2814,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
struct cxsr_latency *latency; struct cxsr_latency *latency;
int sr_clock; int sr_clock;
latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3,
dev_priv->mem_freq); dev_priv->fsb_freq, dev_priv->mem_freq);
if (!latency) { if (!latency) {
DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
pineview_disable_cxsr(dev); pineview_disable_cxsr(dev);
...@@ -5406,11 +5420,13 @@ static void intel_init_display(struct drm_device *dev) ...@@ -5406,11 +5420,13 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_wm = NULL; dev_priv->display.update_wm = NULL;
} else if (IS_PINEVIEW(dev)) { } else if (IS_PINEVIEW(dev)) {
if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
dev_priv->is_ddr3,
dev_priv->fsb_freq, dev_priv->fsb_freq,
dev_priv->mem_freq)) { dev_priv->mem_freq)) {
DRM_INFO("failed to find known CxSR latency " DRM_INFO("failed to find known CxSR latency "
"(found fsb freq %d, mem freq %d), " "(found ddr%s fsb freq %d, mem freq %d), "
"disabling CxSR\n", "disabling CxSR\n",
(dev_priv->is_ddr3 == 1) ? "3": "2",
dev_priv->fsb_freq, dev_priv->mem_freq); dev_priv->fsb_freq, dev_priv->mem_freq);
/* Disable CxSR and never update its watermark again */ /* Disable CxSR and never update its watermark again */
pineview_disable_cxsr(dev); pineview_disable_cxsr(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment