summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/soc/intel_dram.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2023-03-15 05:59:19 +0100
committerDave Airlie <airlied@redhat.com>2023-03-15 05:59:31 +0100
commit8bf6e20253b2d2b614f2c0b491f840e956fa6b05 (patch)
treea85e9082d69fba0707cb57ec217bc02cf5214f03 /drivers/gpu/drm/i915/soc/intel_dram.c
parentMerge tag 'drm-misc-next-2023-03-07' of git://anongit.freedesktop.org/drm/drm... (diff)
parentdrm/i915: Get rid of the gm45 HPD live state nonsense (diff)
downloadlinux-8bf6e20253b2d2b614f2c0b491f840e956fa6b05.tar.xz
linux-8bf6e20253b2d2b614f2c0b491f840e956fa6b05.zip
Merge tag 'drm-intel-next-2023-03-07' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Cross-subsystem Changes: - MEI patches to fix suspend/resume issues with the i915's PXP. (Alexander) Driver Changes: - Registers helpers and clean-ups. (Lucas) - PXP fixes and clean-ups. (Alan, Alexander) - CDCLK related fixes and w/a (Chaitanya, Stanislav) - Move display code to use RMW whenever possible (Andrzej) - PSR fixes (Jouni, Ville) - Implement async_flip mode per plane tracking (Andrzej) - Remove pre-production Workarounds (Matt) - HDMI related fixes (Ankit) - LVDS cleanup (Ville) - Watermark fixes and cleanups (Ville, Jani, Stanilav) - DMC code related fixes, cleanups and improvements (Jani) - Implement fb_dirty for PSR,FBC,DRRS fixes (Jouni) - Initial DSB improvements targeting LUTs loading (Ville) - HWMON related fixes (Ashutosh) - PCI ID updates (Jonathan, Matt Roper) - Fix leak in scatterlist (Matt Atwood) - Fix eDP+DSI dual panel systems (Ville) - Cast iomem to avoid sparese warnings (Jani) - Set default backlight controller index (Jani) - More MTL enabling (RK) - Conversion of display dev_priv towards i915 (Nirmoy) - Improvements in log/debug messages (Ville) - Increase slice_height for DP VDSC (Suraj) - VBT ports improvements (Ville) - Fix platforms without Display (Imre) - Other generic display code clean-ups (Ville, Jani, Rodrigo) - Add RPL-U sub platform (Chaitanya) - Add inverted backlight quirk for HP 14-r206nv (Mavroudis) - Transcoder timing improvements (Ville) - Track audio state per-transcoder (Ville) - Error/underrun interrupt fixes (Ville) - Update combo PHY init sequence (Matt Roper) - Get HDR DPCD refresh timeout (Ville) - Vblank improvements (Ville) - DSS fixes and cleanups (Jani) - PM code cleanup (Jani) - Split display parts related to RPS (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/ZAez4aekcob8fTeh@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/soc/intel_dram.c')
-rw-r--r--drivers/gpu/drm/i915/soc/intel_dram.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
index bba8cb6e8ae4..9f0651d48d41 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.c
+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
@@ -10,6 +10,7 @@
#include "intel_dram.h"
#include "intel_mchbar_regs.h"
#include "intel_pcode.h"
+#include "vlv_sideband.h"
struct dram_dimm_info {
u16 size;
@@ -42,6 +43,155 @@ static const char *intel_dram_type_str(enum intel_dram_type type)
#undef DRAM_TYPE_STR
+static void pnv_detect_mem_freq(struct drm_i915_private *dev_priv)
+{
+ u32 tmp;
+
+ tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG);
+
+ switch (tmp & CLKCFG_FSB_MASK) {
+ case CLKCFG_FSB_533:
+ dev_priv->fsb_freq = 533; /* 133*4 */
+ break;
+ case CLKCFG_FSB_800:
+ dev_priv->fsb_freq = 800; /* 200*4 */
+ break;
+ case CLKCFG_FSB_667:
+ dev_priv->fsb_freq = 667; /* 167*4 */
+ break;
+ case CLKCFG_FSB_400:
+ dev_priv->fsb_freq = 400; /* 100*4 */
+ break;
+ }
+
+ switch (tmp & CLKCFG_MEM_MASK) {
+ case CLKCFG_MEM_533:
+ dev_priv->mem_freq = 533;
+ break;
+ case CLKCFG_MEM_667:
+ dev_priv->mem_freq = 667;
+ break;
+ case CLKCFG_MEM_800:
+ dev_priv->mem_freq = 800;
+ break;
+ }
+
+ /* detect pineview DDR3 setting */
+ tmp = intel_uncore_read(&dev_priv->uncore, CSHRDDR3CTL);
+ dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
+}
+
+static void ilk_detect_mem_freq(struct drm_i915_private *dev_priv)
+{
+ u16 ddrpll, csipll;
+
+ ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1);
+ switch (ddrpll & 0xff) {
+ case 0xc:
+ dev_priv->mem_freq = 800;
+ break;
+ case 0x10:
+ dev_priv->mem_freq = 1066;
+ break;
+ case 0x14:
+ dev_priv->mem_freq = 1333;
+ break;
+ case 0x18:
+ dev_priv->mem_freq = 1600;
+ break;
+ default:
+ drm_dbg(&dev_priv->drm, "unknown memory frequency 0x%02x\n",
+ ddrpll & 0xff);
+ dev_priv->mem_freq = 0;
+ break;
+ }
+
+ csipll = intel_uncore_read16(&dev_priv->uncore, CSIPLL0);
+ switch (csipll & 0x3ff) {
+ case 0x00c:
+ dev_priv->fsb_freq = 3200;
+ break;
+ case 0x00e:
+ dev_priv->fsb_freq = 3733;
+ break;
+ case 0x010:
+ dev_priv->fsb_freq = 4266;
+ break;
+ case 0x012:
+ dev_priv->fsb_freq = 4800;
+ break;
+ case 0x014:
+ dev_priv->fsb_freq = 5333;
+ break;
+ case 0x016:
+ dev_priv->fsb_freq = 5866;
+ break;
+ case 0x018:
+ dev_priv->fsb_freq = 6400;
+ break;
+ default:
+ drm_dbg(&dev_priv->drm, "unknown fsb frequency 0x%04x\n",
+ csipll & 0x3ff);
+ dev_priv->fsb_freq = 0;
+ break;
+ }
+}
+
+static void chv_detect_mem_freq(struct drm_i915_private *i915)
+{
+ u32 val;
+
+ vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_CCK));
+ val = vlv_cck_read(i915, CCK_FUSE_REG);
+ vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_CCK));
+
+ switch ((val >> 2) & 0x7) {
+ case 3:
+ i915->mem_freq = 2000;
+ break;
+ default:
+ i915->mem_freq = 1600;
+ break;
+ }
+}
+
+static void vlv_detect_mem_freq(struct drm_i915_private *i915)
+{
+ u32 val;
+
+ vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_PUNIT));
+ val = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
+ vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_PUNIT));
+
+ switch ((val >> 6) & 3) {
+ case 0:
+ case 1:
+ i915->mem_freq = 800;
+ break;
+ case 2:
+ i915->mem_freq = 1066;
+ break;
+ case 3:
+ i915->mem_freq = 1333;
+ break;
+ }
+}
+
+static void detect_mem_freq(struct drm_i915_private *i915)
+{
+ if (IS_PINEVIEW(i915))
+ pnv_detect_mem_freq(i915);
+ else if (GRAPHICS_VER(i915) == 5)
+ ilk_detect_mem_freq(i915);
+ else if (IS_CHERRYVIEW(i915))
+ chv_detect_mem_freq(i915);
+ else if (IS_VALLEYVIEW(i915))
+ vlv_detect_mem_freq(i915);
+
+ if (i915->mem_freq)
+ drm_dbg(&i915->drm, "DDR speed: %d MHz\n", i915->mem_freq);
+}
+
static int intel_dimm_num_devices(const struct dram_dimm_info *dimm)
{
return dimm->ranks * 64 / (dimm->width ?: 1);
@@ -507,6 +657,8 @@ void intel_dram_detect(struct drm_i915_private *i915)
struct dram_info *dram_info = &i915->dram_info;
int ret;
+ detect_mem_freq(i915);
+
if (GRAPHICS_VER(i915) < 9 || IS_DG2(i915) || !HAS_DISPLAY(i915))
return;