diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.29.1/linux-2.6.29-pnv-drm.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.29.1/linux-2.6.29-pnv-drm.patch | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.29.1/linux-2.6.29-pnv-drm.patch b/meta-moblin/packages/linux/linux-moblin-2.6.29.1/linux-2.6.29-pnv-drm.patch new file mode 100644 index 000000000..1e7b86694 --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.29.1/linux-2.6.29-pnv-drm.patch @@ -0,0 +1,336 @@ +From 8b941bea1d0fe0c5cf0de938cd0bd89ce6640dbb Mon Sep 17 00:00:00 2001 +From: Shaohua Li <shaohua.li@intel.com> +Date: Mon, 23 Feb 2009 15:19:19 +0800 +Subject: drm/i915: Add support for new G33-like chipset. + +This chip is nearly the same, but has new clock settings required. + +Signed-off-by: Shaohua Li <shaohua.li@intel.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +--- + drivers/gpu/drm/i915/i915_drv.h | 10 +++- + drivers/gpu/drm/i915/i915_reg.h | 4 + + drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++++++++++++++++++++----- + include/drm/drm_pciids.h | 2 + + 4 files changed, 109 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0e27854..36d6bc3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -787,15 +787,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + (dev)->pci_device == 0x2E22 || \ + IS_GM45(dev)) + ++#define IS_IGDG(dev) ((dev)->pci_device == 0xa001) ++#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011) ++#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev)) ++ + #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ +- (dev)->pci_device == 0x29D2) ++ (dev)->pci_device == 0x29D2 || \ ++ (IS_IGD(dev))) + + #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) + + #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ +- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) ++ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ ++ IS_IGD(dev)) + + #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) + /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 9d6539a..f07d315 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -358,6 +358,7 @@ + #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ + #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ + #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ ++#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */ + + #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) + #define I915_CRC_ERROR_ENABLE (1UL<<29) +@@ -434,6 +435,7 @@ + */ + #define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 + #define DPLL_FPA01_P1_POST_DIV_SHIFT 16 ++#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15 + /* i830, required in DVO non-gang */ + #define PLL_P2_DIVIDE_BY_4 (1 << 23) + #define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +@@ -500,10 +502,12 @@ + #define FPB0 0x06048 + #define FPB1 0x0604c + #define FP_N_DIV_MASK 0x003f0000 ++#define FP_N_IGD_DIV_MASK 0x00ff0000 + #define FP_N_DIV_SHIFT 16 + #define FP_M1_DIV_MASK 0x00003f00 + #define FP_M1_DIV_SHIFT 8 + #define FP_M2_DIV_MASK 0x0000003f ++#define FP_M2_IGD_DIV_MASK 0x000000ff + #define FP_M2_DIV_SHIFT 0 + #define DPLL_TEST 0x606c + #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index a283427..1702564 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -90,18 +90,32 @@ typedef struct { + #define I9XX_DOT_MAX 400000 + #define I9XX_VCO_MIN 1400000 + #define I9XX_VCO_MAX 2800000 ++#define IGD_VCO_MIN 1700000 ++#define IGD_VCO_MAX 3500000 + #define I9XX_N_MIN 1 + #define I9XX_N_MAX 6 ++/* IGD's Ncounter is a ring counter */ ++#define IGD_N_MIN 3 ++#define IGD_N_MAX 6 + #define I9XX_M_MIN 70 + #define I9XX_M_MAX 120 ++#define IGD_M_MIN 2 ++#define IGD_M_MAX 256 + #define I9XX_M1_MIN 10 + #define I9XX_M1_MAX 22 + #define I9XX_M2_MIN 5 + #define I9XX_M2_MAX 9 ++/* IGD M1 is reserved, and must be 0 */ ++#define IGD_M1_MIN 0 ++#define IGD_M1_MAX 0 ++#define IGD_M2_MIN 0 ++#define IGD_M2_MAX 254 + #define I9XX_P_SDVO_DAC_MIN 5 + #define I9XX_P_SDVO_DAC_MAX 80 + #define I9XX_P_LVDS_MIN 7 + #define I9XX_P_LVDS_MAX 98 ++#define IGD_P_LVDS_MIN 7 ++#define IGD_P_LVDS_MAX 112 + #define I9XX_P1_MIN 1 + #define I9XX_P1_MAX 8 + #define I9XX_P2_SDVO_DAC_SLOW 10 +@@ -115,6 +129,8 @@ typedef struct { + #define INTEL_LIMIT_I8XX_LVDS 1 + #define INTEL_LIMIT_I9XX_SDVO_DAC 2 + #define INTEL_LIMIT_I9XX_LVDS 3 ++#define INTEL_LIMIT_IGD_SDVO_DAC 4 ++#define INTEL_LIMIT_IGD_LVDS 5 + + static const intel_limit_t intel_limits[] = { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ +@@ -168,6 +184,32 @@ static const intel_limit_t intel_limits[] = { + .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, + .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, + }, ++ { /* INTEL_LIMIT_IGD_SDVO */ ++ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, ++ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, ++ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, ++ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, ++ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, ++ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, ++ .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, ++ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, ++ .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, ++ .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, ++ }, ++ { /* INTEL_LIMIT_IGD_LVDS */ ++ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, ++ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, ++ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, ++ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, ++ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, ++ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, ++ .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX }, ++ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, ++ /* IGD only supports single-channel mode. */ ++ .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, ++ .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, ++ }, ++ + }; + + static const intel_limit_t *intel_limit(struct drm_crtc *crtc) +@@ -175,11 +217,16 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) + struct drm_device *dev = crtc->dev; + const intel_limit_t *limit; + +- if (IS_I9XX(dev)) { ++ if (IS_I9XX(dev) && !IS_IGD(dev)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; + else + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; ++ } else if (IS_IGD(dev)) { ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) ++ limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; ++ else ++ limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; + } else { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; +@@ -189,8 +236,21 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) + return limit; + } + +-static void intel_clock(int refclk, intel_clock_t *clock) ++/* m1 is reserved as 0 in IGD, n is a ring counter */ ++static void igd_clock(int refclk, intel_clock_t *clock) + { ++ clock->m = clock->m2 + 2; ++ clock->p = clock->p1 * clock->p2; ++ clock->vco = refclk * clock->m / clock->n; ++ clock->dot = clock->vco / clock->p; ++} ++ ++static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) ++{ ++ if (IS_IGD(dev)) { ++ igd_clock(refclk, clock); ++ return; ++ } + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); +@@ -226,6 +286,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) + static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) + { + const intel_limit_t *limit = intel_limit (crtc); ++ struct drm_device *dev = crtc->dev; + + if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) + INTELPllInvalid ("p1 out of range\n"); +@@ -235,7 +296,7 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) + INTELPllInvalid ("m2 out of range\n"); + if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) + INTELPllInvalid ("m1 out of range\n"); +- if (clock->m1 <= clock->m2) ++ if (clock->m1 <= clock->m2 && !IS_IGD(dev)) + INTELPllInvalid ("m1 <= m2\n"); + if (clock->m < limit->m.min || limit->m.max < clock->m) + INTELPllInvalid ("m out of range\n"); +@@ -289,15 +350,17 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, + memset (best_clock, 0, sizeof (*best_clock)); + + for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { +- for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 && +- clock.m2 <= limit->m2.max; clock.m2++) { ++ for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { ++ /* m1 is always 0 in IGD */ ++ if (clock.m2 >= clock.m1 && !IS_IGD(dev)) ++ break; + for (clock.n = limit->n.min; clock.n <= limit->n.max; + clock.n++) { + for (clock.p1 = limit->p1.min; + clock.p1 <= limit->p1.max; clock.p1++) { + int this_err; + +- intel_clock(refclk, &clock); ++ intel_clock(dev, refclk, &clock); + + if (!intel_PLL_is_valid(crtc, &clock)) + continue; +@@ -634,7 +697,7 @@ static int intel_get_core_clock_speed(struct drm_device *dev) + return 400000; + else if (IS_I915G(dev)) + return 333000; +- else if (IS_I945GM(dev) || IS_845G(dev)) ++ else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) + return 200000; + else if (IS_I915GM(dev)) { + u16 gcfgc = 0; +@@ -782,7 +845,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + return -EINVAL; + } + +- fp = clock.n << 16 | clock.m1 << 8 | clock.m2; ++ if (IS_IGD(dev)) ++ fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; ++ else ++ fp = clock.n << 16 | clock.m1 << 8 | clock.m2; + + dpll = DPLL_VGA_MODE_DIS; + if (IS_I9XX(dev)) { +@@ -799,7 +865,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + } + + /* compute bitmask from p1 value */ +- dpll |= (1 << (clock.p1 - 1)) << 16; ++ if (IS_IGD(dev)) ++ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD; ++ else ++ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + switch (clock.p2) { + case 5: + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; +@@ -1279,10 +1348,20 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + fp = I915_READ((pipe == 0) ? FPA1 : FPB1); + + clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; +- clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; +- clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; ++ if (IS_IGD(dev)) { ++ clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; ++ clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT; ++ } else { ++ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; ++ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; ++ } ++ + if (IS_I9XX(dev)) { +- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> ++ if (IS_IGD(dev)) ++ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> ++ DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); ++ else ++ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + + switch (dpll & DPLL_MODE_MASK) { +@@ -1301,7 +1380,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + } + + /* XXX: Handle the 100Mhz refclk */ +- intel_clock(96000, &clock); ++ intel_clock(dev, 96000, &clock); + } else { + bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); + +@@ -1313,9 +1392,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ +- intel_clock(66000, &clock); ++ intel_clock(dev, 66000, &clock); + } else +- intel_clock(48000, &clock); ++ intel_clock(dev, 48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; +@@ -1328,7 +1407,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + else + clock.p2 = 2; + +- intel_clock(48000, &clock); ++ intel_clock(dev, 48000, &clock); + } + } + +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 5165f24..76c4c82 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -418,4 +418,6 @@ + {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ ++ {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ ++ {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0, 0, 0} +-- +1.6.1.3 + |