Skip to content

Commit

Permalink
drm/i915/gen11+: Only load DRAM information from pcode
Browse files Browse the repository at this point in the history
Up to now we were reading some DRAM information from MCHBAR register
and from pcode what is already not good but some GEN12(TGL-H and ADL-S)
platforms have MCHBAR DRAM information in different offsets.

This was notified to HW team that decided that the best alternative is
always apply the 16gb_dimm watermark adjustment for GEN12+ platforms
and read the remaning DRAM information needed to other display
programming from pcode.

So here moving the DRAM pcode function to intel_dram.c, removing
the duplicated fields from intel_qgv_info, setting and using
information from dram_info.

v2:
- bring back num_points to intel_qgv_info as num_qgv_point can be
overwritten in icl_get_qgv_points()
- add gen12_get_dram_info() and simplify gen11_get_dram_info()

Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210128164312.91160-2-jose.souza@intel.com
  • Loading branch information
José Roberto de Souza committed Jan 29, 2021
1 parent f0b2970 commit 5d0c938
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 75 deletions.
80 changes: 8 additions & 72 deletions drivers/gpu/drm/i915/display/intel_bw.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,76 +20,9 @@ struct intel_qgv_point {
struct intel_qgv_info {
struct intel_qgv_point points[I915_NUM_QGV_POINTS];
u8 num_points;
u8 num_channels;
u8 t_bl;
enum intel_dram_type dram_type;
};

static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv,
struct intel_qgv_info *qi)
{
u32 val = 0;
int ret;

ret = sandybridge_pcode_read(dev_priv,
ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SS_READ_GLOBAL_INFO,
&val, NULL);
if (ret)
return ret;

if (IS_GEN(dev_priv, 12)) {
switch (val & 0xf) {
case 0:
qi->dram_type = INTEL_DRAM_DDR4;
break;
case 3:
qi->dram_type = INTEL_DRAM_LPDDR4;
break;
case 4:
qi->dram_type = INTEL_DRAM_DDR3;
break;
case 5:
qi->dram_type = INTEL_DRAM_LPDDR3;
break;
default:
MISSING_CASE(val & 0xf);
break;
}
} else if (IS_GEN(dev_priv, 11)) {
switch (val & 0xf) {
case 0:
qi->dram_type = INTEL_DRAM_DDR4;
break;
case 1:
qi->dram_type = INTEL_DRAM_DDR3;
break;
case 2:
qi->dram_type = INTEL_DRAM_LPDDR3;
break;
case 3:
qi->dram_type = INTEL_DRAM_LPDDR4;
break;
default:
MISSING_CASE(val & 0xf);
break;
}
} else {
MISSING_CASE(INTEL_GEN(dev_priv));
qi->dram_type = INTEL_DRAM_LPDDR3; /* Conservative default */
}

qi->num_channels = (val & 0xf0) >> 4;
qi->num_points = (val & 0xf00) >> 8;

if (IS_GEN(dev_priv, 12))
qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 16;
else if (IS_GEN(dev_priv, 11))
qi->t_bl = qi->dram_type == INTEL_DRAM_DDR4 ? 4 : 8;

return 0;
}

static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
struct intel_qgv_point *sp,
int point)
Expand Down Expand Up @@ -139,11 +72,15 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
struct intel_qgv_info *qi)
{
const struct dram_info *dram_info = &dev_priv->dram_info;
int i, ret;

ret = icl_pcode_read_mem_global_info(dev_priv, qi);
if (ret)
return ret;
qi->num_points = dram_info->num_qgv_points;

if (IS_GEN(dev_priv, 12))
qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 16;
else if (IS_GEN(dev_priv, 11))
qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8;

if (drm_WARN_ON(&dev_priv->drm,
qi->num_points > ARRAY_SIZE(qi->points)))
Expand Down Expand Up @@ -209,7 +146,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
{
struct intel_qgv_info qi = {};
bool is_y_tile = true; /* assume y tile may be used */
int num_channels;
int num_channels = dev_priv->dram_info.num_channels;
int deinterleave;
int ipqdepth, ipqdepthpch;
int dclk_max;
Expand All @@ -222,7 +159,6 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
"Failed to get memory subsystem information, ignoring bandwidth limits");
return ret;
}
num_channels = qi.num_channels;

deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
dclk_max = icl_sagv_max_dclk(&qi);
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,14 +609,15 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
goto err_msi;

intel_opregion_setup(dev_priv);

intel_pcode_init(dev_priv);

/*
* Fill the dram structure to get the system dram info. This will be
* used for memory latency calculation.
*/
intel_dram_detect(dev_priv);

intel_pcode_init(dev_priv);

intel_bw_init_hw(dev_priv);

return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,7 @@ struct drm_i915_private {
INTEL_DRAM_LPDDR3,
INTEL_DRAM_LPDDR4
} type;
u8 num_qgv_points;
} dram_info;

struct intel_bw_info {
Expand Down
82 changes: 81 additions & 1 deletion drivers/gpu/drm/i915/intel_dram.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "i915_drv.h"
#include "intel_dram.h"
#include "intel_sideband.h"

struct dram_dimm_info {
u16 size;
Expand Down Expand Up @@ -408,6 +409,81 @@ static int bxt_get_dram_info(struct drm_i915_private *i915)
return 0;
}

static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv)
{
struct dram_info *dram_info = &dev_priv->dram_info;
u32 val = 0;
int ret;

ret = sandybridge_pcode_read(dev_priv,
ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SS_READ_GLOBAL_INFO,
&val, NULL);
if (ret)
return ret;

if (IS_GEN(dev_priv, 12)) {
switch (val & 0xf) {
case 0:
dram_info->type = INTEL_DRAM_DDR4;
break;
case 3:
dram_info->type = INTEL_DRAM_LPDDR4;
break;
case 4:
dram_info->type = INTEL_DRAM_DDR3;
break;
case 5:
dram_info->type = INTEL_DRAM_LPDDR3;
break;
default:
MISSING_CASE(val & 0xf);
return -1;
}
} else {
switch (val & 0xf) {
case 0:
dram_info->type = INTEL_DRAM_DDR4;
break;
case 1:
dram_info->type = INTEL_DRAM_DDR3;
break;
case 2:
dram_info->type = INTEL_DRAM_LPDDR3;
break;
case 3:
dram_info->type = INTEL_DRAM_LPDDR4;
break;
default:
MISSING_CASE(val & 0xf);
return -1;
}
}

dram_info->num_channels = (val & 0xf0) >> 4;
dram_info->num_qgv_points = (val & 0xf00) >> 8;

return 0;
}

static int gen11_get_dram_info(struct drm_i915_private *i915)
{
int ret = skl_get_dram_info(i915);

if (ret)
return ret;

return icl_pcode_read_mem_global_info(i915);
}

static int gen12_get_dram_info(struct drm_i915_private *i915)
{
/* Always needed for GEN12+ */
i915->dram_info.is_16gb_dimm = true;

return icl_pcode_read_mem_global_info(i915);
}

void intel_dram_detect(struct drm_i915_private *i915)
{
struct dram_info *dram_info = &i915->dram_info;
Expand All @@ -423,7 +499,11 @@ void intel_dram_detect(struct drm_i915_private *i915)
if (INTEL_GEN(i915) < 9 || !HAS_DISPLAY(i915))
return;

if (IS_GEN9_LP(i915))
if (INTEL_GEN(i915) >= 12)
ret = gen12_get_dram_info(i915);
else if (INTEL_GEN(i915) >= 11)
ret = gen11_get_dram_info(i915);
else if (IS_GEN9_LP(i915))
ret = bxt_get_dram_info(i915);
else
ret = skl_get_dram_info(i915);
Expand Down

0 comments on commit 5d0c938

Please sign in to comment.