Merge tag 'drm-fixes-for-v4.7-rc5' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "This is the drm fixes tree for 4.7-rc5. It's a bit larger than normal, due to fixes for production AMD Polaris GPUs. We only merged support for these in 4.7-rc1 so it would be good if we got all the fixes into final. The changes don't hit any other hardware. Other than the amdgpu Polaris changes: - A single fix for atomic modesetting WARN - Nouveau fix for when fbdev is disabled - i915 fixes for FBC on Haswell and displayport regression - Exynos fix for a display panel regression and some other minor changes - Atmel fixes for scaling and OF graph interaction - Allwiinner build, warning and probing fixes - AMD GPU non-polaris fix for num_rbs and some minor fixes Also I've just moved house, and my new place is Internet challenged due to incompetent incumbent ISPs, hopefully sorted out in a couple of weeks, so I might not be too responsive over the next while. It also helps Daniel is on holidays for those couple of weeks as well" * tag 'drm-fixes-for-v4.7-rc5' of git://people.freedesktop.org/~airlied/linux: (38 commits) drm/atomic: Make drm_atomic_legacy_backoff reset crtc->acquire_ctx drm/nouveau: fix for disabled fbdev emulation drm/i915/fbc: Disable on HSW by default for now drm/i915: Revert DisplayPort fast link training feature drm/amd/powerplay: enable clock stretch feature for polaris drm/amdgpu/gfx8: update golden setting for polaris10 drm/amd/powerplay: enable avfs feature for polaris drm/amdgpu/atombios: add avfs struct for Polaris10/11 drm/amd/powerplay: add avfs related define for polaris drm/amd/powrplay: enable stutter_mode for polaris. drm/amd/powerplay: disable UVD SMU handshake for MCLK. drm/amd/powerplay: initialize variables which were missed. drm/amd/powerplay: enable PowerContainment feature for polaris10/11. drm/amd/powerplay: need to notify system bios pcie device ready drm/amd/powerplay: fix bug that function parameter was incorect. drm/amd/powerplay: fix logic error. drm: atmel-hlcdc: Fix OF graph parsing drm: atmel-hlcdc: actually disable scaling when no scaling is required drm/amdgpu: initialize amdgpu_cgs_acpi_eval_object result value drm/amdgpu: precedence bug in amdgpu_device_init() ...
This commit is contained in:
commit
0bf0ea431f
40 changed files with 598 additions and 256 deletions
|
@ -909,7 +909,7 @@ static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
|
|||
struct cgs_acpi_method_argument *argument = NULL;
|
||||
uint32_t i, count;
|
||||
acpi_status status;
|
||||
int result;
|
||||
int result = 0;
|
||||
uint32_t func_no = 0xFFFFFFFF;
|
||||
|
||||
handle = ACPI_HANDLE(&adev->pdev->dev);
|
||||
|
|
|
@ -1535,7 +1535,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
/* Post card if necessary */
|
||||
if (!amdgpu_card_posted(adev) ||
|
||||
(adev->virtualization.is_virtual &&
|
||||
!adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) {
|
||||
!(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) {
|
||||
if (!adev->bios) {
|
||||
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -447,7 +447,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
dev_info.max_memory_clock = adev->pm.default_mclk * 10;
|
||||
}
|
||||
dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
|
||||
dev_info.num_rb_pipes = adev->gfx.config.num_rbs;
|
||||
dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
|
||||
adev->gfx.config.max_shader_engines;
|
||||
dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;
|
||||
dev_info._pad = 0;
|
||||
dev_info.ids_flags = 0;
|
||||
|
|
|
@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
|
|||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amd_pm_state_type state = 0;
|
||||
long idx;
|
||||
unsigned long idx;
|
||||
int ret;
|
||||
|
||||
if (strlen(buf) == 1)
|
||||
adev->pp_force_state_enabled = false;
|
||||
else {
|
||||
ret = kstrtol(buf, 0, &idx);
|
||||
else if (adev->pp_enabled) {
|
||||
struct pp_states_info data;
|
||||
|
||||
if (ret) {
|
||||
ret = kstrtoul(buf, 0, &idx);
|
||||
if (ret || idx >= ARRAY_SIZE(data.states)) {
|
||||
count = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (adev->pp_enabled) {
|
||||
struct pp_states_info data;
|
||||
amdgpu_dpm_get_pp_num_states(adev, &data);
|
||||
state = data.states[idx];
|
||||
/* only set user selected power states */
|
||||
if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
|
||||
state != POWER_STATE_TYPE_DEFAULT) {
|
||||
amdgpu_dpm_dispatch_task(adev,
|
||||
AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
|
||||
adev->pp_force_state_enabled = true;
|
||||
}
|
||||
amdgpu_dpm_get_pp_num_states(adev, &data);
|
||||
state = data.states[idx];
|
||||
/* only set user selected power states */
|
||||
if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
|
||||
state != POWER_STATE_TYPE_DEFAULT) {
|
||||
amdgpu_dpm_dispatch_task(adev,
|
||||
AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
|
||||
adev->pp_force_state_enabled = true;
|
||||
}
|
||||
}
|
||||
fail:
|
||||
|
|
|
@ -297,7 +297,8 @@ static const u32 polaris11_golden_common_all[] =
|
|||
static const u32 golden_settings_polaris10_a11[] =
|
||||
{
|
||||
mmATC_MISC_CG, 0x000c0fc0, 0x000c0200,
|
||||
mmCB_HW_CONTROL, 0xfffdf3cf, 0x00006208,
|
||||
mmCB_HW_CONTROL, 0xfffdf3cf, 0x00007208,
|
||||
mmCB_HW_CONTROL_2, 0, 0x0f000000,
|
||||
mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040,
|
||||
mmDB_DEBUG2, 0xf00fffff, 0x00000400,
|
||||
mmPA_SC_ENHANCE, 0xffffffff, 0x20000001,
|
||||
|
|
|
@ -5538,6 +5538,78 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V3_5
|
|||
ULONG ulReserved[12];
|
||||
}ATOM_ASIC_PROFILING_INFO_V3_5;
|
||||
|
||||
/* for Polars10/11 AVFS parameters */
|
||||
typedef struct _ATOM_ASIC_PROFILING_INFO_V3_6
|
||||
{
|
||||
ATOM_COMMON_TABLE_HEADER asHeader;
|
||||
ULONG ulMaxVddc;
|
||||
ULONG ulMinVddc;
|
||||
USHORT usLkgEuseIndex;
|
||||
UCHAR ucLkgEfuseBitLSB;
|
||||
UCHAR ucLkgEfuseLength;
|
||||
ULONG ulLkgEncodeLn_MaxDivMin;
|
||||
ULONG ulLkgEncodeMax;
|
||||
ULONG ulLkgEncodeMin;
|
||||
EFUSE_LINEAR_FUNC_PARAM sRoFuse;
|
||||
ULONG ulEvvDefaultVddc;
|
||||
ULONG ulEvvNoCalcVddc;
|
||||
ULONG ulSpeed_Model;
|
||||
ULONG ulSM_A0;
|
||||
ULONG ulSM_A1;
|
||||
ULONG ulSM_A2;
|
||||
ULONG ulSM_A3;
|
||||
ULONG ulSM_A4;
|
||||
ULONG ulSM_A5;
|
||||
ULONG ulSM_A6;
|
||||
ULONG ulSM_A7;
|
||||
UCHAR ucSM_A0_sign;
|
||||
UCHAR ucSM_A1_sign;
|
||||
UCHAR ucSM_A2_sign;
|
||||
UCHAR ucSM_A3_sign;
|
||||
UCHAR ucSM_A4_sign;
|
||||
UCHAR ucSM_A5_sign;
|
||||
UCHAR ucSM_A6_sign;
|
||||
UCHAR ucSM_A7_sign;
|
||||
ULONG ulMargin_RO_a;
|
||||
ULONG ulMargin_RO_b;
|
||||
ULONG ulMargin_RO_c;
|
||||
ULONG ulMargin_fixed;
|
||||
ULONG ulMargin_Fmax_mean;
|
||||
ULONG ulMargin_plat_mean;
|
||||
ULONG ulMargin_Fmax_sigma;
|
||||
ULONG ulMargin_plat_sigma;
|
||||
ULONG ulMargin_DC_sigma;
|
||||
ULONG ulLoadLineSlop;
|
||||
ULONG ulaTDClimitPerDPM[8];
|
||||
ULONG ulaNoCalcVddcPerDPM[8];
|
||||
ULONG ulAVFS_meanNsigma_Acontant0;
|
||||
ULONG ulAVFS_meanNsigma_Acontant1;
|
||||
ULONG ulAVFS_meanNsigma_Acontant2;
|
||||
USHORT usAVFS_meanNsigma_DC_tol_sigma;
|
||||
USHORT usAVFS_meanNsigma_Platform_mean;
|
||||
USHORT usAVFS_meanNsigma_Platform_sigma;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a0;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a1;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSOFF_a2;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a0;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a1;
|
||||
ULONG ulGB_VDROOP_TABLE_CKSON_a2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
|
||||
USHORT usAVFSGB_FUSE_TABLE_CKSOFF_m2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSOFF_b;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSON_m1;
|
||||
USHORT usAVFSGB_FUSE_TABLE_CKSON_m2;
|
||||
ULONG ulAVFSGB_FUSE_TABLE_CKSON_b;
|
||||
USHORT usMaxVoltage_0_25mv;
|
||||
UCHAR ucEnableGB_VDROOP_TABLE_CKSOFF;
|
||||
UCHAR ucEnableGB_VDROOP_TABLE_CKSON;
|
||||
UCHAR ucEnableGB_FUSE_TABLE_CKSOFF;
|
||||
UCHAR ucEnableGB_FUSE_TABLE_CKSON;
|
||||
USHORT usPSM_Age_ComFactor;
|
||||
UCHAR ucEnableApplyAVFS_CKS_OFF_Voltage;
|
||||
UCHAR ucReserved;
|
||||
}ATOM_ASIC_PROFILING_INFO_V3_6;
|
||||
|
||||
|
||||
typedef struct _ATOM_SCLK_FCW_RANGE_ENTRY_V1{
|
||||
ULONG ulMaxSclkFreq;
|
||||
|
|
|
@ -633,6 +633,8 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = FIJI_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = FIJI_VOLTAGE_CONTROL_NONE;
|
||||
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
|
||||
data->voltage_control = FIJI_VOLTAGE_CONTROL_BY_SVID2;
|
||||
|
|
|
@ -306,10 +306,14 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
|
|||
{
|
||||
PHM_FUNC_CHECK(hwmgr);
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data == NULL)
|
||||
if (display_config == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
hwmgr->display_config = *display_config;
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* to do pass other display configuration in furture */
|
||||
|
||||
if (hwmgr->hwmgr_func->store_cc6_data)
|
||||
|
|
|
@ -1296,7 +1296,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
|
|||
}
|
||||
|
||||
mem_level->MclkFrequency = clock;
|
||||
mem_level->StutterEnable = 0;
|
||||
mem_level->EnabledForThrottle = 1;
|
||||
mem_level->EnabledForActivity = 0;
|
||||
mem_level->UpHyst = 0;
|
||||
|
@ -1304,7 +1303,6 @@ static int polaris10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
|
|||
mem_level->VoltageDownHyst = 0;
|
||||
mem_level->ActivityLevel = (uint16_t)data->mclk_activity_target;
|
||||
mem_level->StutterEnable = false;
|
||||
|
||||
mem_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW;
|
||||
|
||||
data->display_timing.num_existing_displays = info.display_count;
|
||||
|
@ -1363,7 +1361,7 @@ static int polaris10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
|
|||
* a higher state by default such that we are not effected by
|
||||
* up threshold or and MCLK DPM latency.
|
||||
*/
|
||||
levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target;
|
||||
levels[0].ActivityLevel = 0x1f;
|
||||
CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel);
|
||||
|
||||
data->smc_state_table.MemoryDpmLevelCount =
|
||||
|
@ -1761,12 +1759,9 @@ static int polaris10_populate_smc_initailial_state(struct pp_hwmgr *hwmgr)
|
|||
|
||||
static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
uint32_t ro, efuse, efuse2, clock_freq, volt_without_cks,
|
||||
volt_with_cks, value;
|
||||
uint16_t clock_freq_u16;
|
||||
uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min;
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
uint8_t type, i, j, cks_setting, stretch_amount, stretch_amount2,
|
||||
volt_offset = 0;
|
||||
uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0;
|
||||
struct phm_ppt_v1_information *table_info =
|
||||
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
||||
struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
|
||||
|
@ -1778,50 +1773,38 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
|||
* if the part is SS or FF. if RO >= 1660MHz, part is FF.
|
||||
*/
|
||||
efuse = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixSMU_EFUSE_0 + (146 * 4));
|
||||
efuse2 = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixSMU_EFUSE_0 + (148 * 4));
|
||||
ixSMU_EFUSE_0 + (67 * 4));
|
||||
efuse &= 0xFF000000;
|
||||
efuse = efuse >> 24;
|
||||
efuse2 &= 0xF;
|
||||
|
||||
if (efuse2 == 1)
|
||||
ro = (2300 - 1350) * efuse / 255 + 1350;
|
||||
else
|
||||
ro = (2500 - 1000) * efuse / 255 + 1000;
|
||||
if (hwmgr->chip_id == CHIP_POLARIS10) {
|
||||
min = 1000;
|
||||
max = 2300;
|
||||
} else {
|
||||
min = 1100;
|
||||
max = 2100;
|
||||
}
|
||||
|
||||
if (ro >= 1660)
|
||||
type = 0;
|
||||
else
|
||||
type = 1;
|
||||
|
||||
/* Populate Stretch amount */
|
||||
data->smc_state_table.ClockStretcherAmount = stretch_amount;
|
||||
ro = efuse * (max -min)/255 + min;
|
||||
|
||||
/* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
|
||||
for (i = 0; i < sclk_table->count; i++) {
|
||||
data->smc_state_table.Sclk_CKS_masterEn0_7 |=
|
||||
sclk_table->entries[i].cks_enable << i;
|
||||
volt_without_cks = (uint32_t)((14041 *
|
||||
(sclk_table->entries[i].clk/100) / 10000 + 3571 + 75 - ro) * 1000 /
|
||||
(4026 - (13924 * (sclk_table->entries[i].clk/100) / 10000)));
|
||||
volt_with_cks = (uint32_t)((13946 *
|
||||
(sclk_table->entries[i].clk/100) / 10000 + 3320 + 45 - ro) * 1000 /
|
||||
(3664 - (11454 * (sclk_table->entries[i].clk/100) / 10000)));
|
||||
|
||||
volt_without_cks = (uint32_t)(((ro - 40) * 1000 - 2753594 - sclk_table->entries[i].clk/100 * 136418 /1000) / \
|
||||
(sclk_table->entries[i].clk/100 * 1132925 /10000 - 242418)/100);
|
||||
|
||||
volt_with_cks = (uint32_t)((ro * 1000 -2396351 - sclk_table->entries[i].clk/100 * 329021/1000) / \
|
||||
(sclk_table->entries[i].clk/10000 * 649434 /1000 - 18005)/10);
|
||||
|
||||
if (volt_without_cks >= volt_with_cks)
|
||||
volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
|
||||
sclk_table->entries[i].cks_voffset) * 100 / 625) + 1);
|
||||
|
||||
data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
|
||||
}
|
||||
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
STRETCH_ENABLE, 0x0);
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
masterReset, 0x1);
|
||||
/* PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE, staticEnable, 0x1); */
|
||||
PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
|
||||
masterReset, 0x0);
|
||||
|
||||
/* Populate CKS Lookup Table */
|
||||
if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
|
||||
stretch_amount2 = 0;
|
||||
|
@ -1835,69 +1818,6 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
|
|||
return -EINVAL);
|
||||
}
|
||||
|
||||
value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixPWR_CKS_CNTL);
|
||||
value &= 0xFFC2FF87;
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][0];
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][1];
|
||||
clock_freq_u16 = (uint16_t)(PP_SMC_TO_HOST_UL(data->smc_state_table.
|
||||
GraphicsLevel[data->smc_state_table.GraphicsDpmLevelCount - 1].SclkSetting.SclkFrequency) / 100);
|
||||
if (polaris10_clock_stretcher_lookup_table[stretch_amount2][0] < clock_freq_u16
|
||||
&& polaris10_clock_stretcher_lookup_table[stretch_amount2][1] > clock_freq_u16) {
|
||||
/* Program PWR_CKS_CNTL. CKS_USE_FOR_LOW_FREQ */
|
||||
value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 16;
|
||||
/* Program PWR_CKS_CNTL. CKS_LDO_REFSEL */
|
||||
value |= (polaris10_clock_stretcher_lookup_table[stretch_amount2][2]) << 18;
|
||||
/* Program PWR_CKS_CNTL. CKS_STRETCH_AMOUNT */
|
||||
value |= (polaris10_clock_stretch_amount_conversion
|
||||
[polaris10_clock_stretcher_lookup_table[stretch_amount2][3]]
|
||||
[stretch_amount]) << 3;
|
||||
}
|
||||
CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].minFreq);
|
||||
CONVERT_FROM_HOST_TO_SMC_US(data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].maxFreq);
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting =
|
||||
polaris10_clock_stretcher_lookup_table[stretch_amount2][2] & 0x7F;
|
||||
data->smc_state_table.CKS_LOOKUPTable.CKS_LOOKUPTableEntry[0].setting |=
|
||||
(polaris10_clock_stretcher_lookup_table[stretch_amount2][3]) << 7;
|
||||
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
ixPWR_CKS_CNTL, value);
|
||||
|
||||
/* Populate DDT Lookup Table */
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* Assign the minimum and maximum VID stored
|
||||
* in the last row of Clock Stretcher Voltage Table.
|
||||
*/
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].minVID =
|
||||
(uint8_t) polaris10_clock_stretcher_ddt_table[type][i][2];
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].maxVID =
|
||||
(uint8_t) polaris10_clock_stretcher_ddt_table[type][i][3];
|
||||
/* Loop through each SCLK and check the frequency
|
||||
* to see if it lies within the frequency for clock stretcher.
|
||||
*/
|
||||
for (j = 0; j < data->smc_state_table.GraphicsDpmLevelCount; j++) {
|
||||
cks_setting = 0;
|
||||
clock_freq = PP_SMC_TO_HOST_UL(
|
||||
data->smc_state_table.GraphicsLevel[j].SclkSetting.SclkFrequency);
|
||||
/* Check the allowed frequency against the sclk level[j].
|
||||
* Sclk's endianness has already been converted,
|
||||
* and it's in 10Khz unit,
|
||||
* as opposed to Data table, which is in Mhz unit.
|
||||
*/
|
||||
if (clock_freq >= (polaris10_clock_stretcher_ddt_table[type][i][0]) * 100) {
|
||||
cks_setting |= 0x2;
|
||||
if (clock_freq < (polaris10_clock_stretcher_ddt_table[type][i][1]) * 100)
|
||||
cks_setting |= 0x1;
|
||||
}
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting
|
||||
|= cks_setting << (j * 2);
|
||||
}
|
||||
CONVERT_FROM_HOST_TO_SMC_US(
|
||||
data->smc_state_table.ClockStretcherDataTable.ClockStretcherDataTableEntry[i].setting);
|
||||
}
|
||||
|
||||
value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL);
|
||||
value &= 0xFFFFFFFE;
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixPWR_CKS_CNTL, value);
|
||||
|
@ -1956,6 +1876,90 @@ static int polaris10_populate_vr_config(struct pp_hwmgr *hwmgr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
SMU74_Discrete_DpmTable *table = &(data->smc_state_table);
|
||||
int result = 0;
|
||||
struct pp_atom_ctrl__avfs_parameters avfs_params = {0};
|
||||
AVFS_meanNsigma_t AVFS_meanNsigma = { {0} };
|
||||
AVFS_Sclk_Offset_t AVFS_SclkOffset = { {0} };
|
||||
uint32_t tmp, i;
|
||||
struct pp_smumgr *smumgr = hwmgr->smumgr;
|
||||
struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
|
||||
|
||||
struct phm_ppt_v1_information *table_info =
|
||||
(struct phm_ppt_v1_information *)hwmgr->pptable;
|
||||
struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
|
||||
table_info->vdd_dep_on_sclk;
|
||||
|
||||
|
||||
if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
|
||||
return result;
|
||||
|
||||
result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
|
||||
|
||||
if (0 == result) {
|
||||
table->BTCGB_VDROOP_TABLE[0].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a0);
|
||||
table->BTCGB_VDROOP_TABLE[0].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a1);
|
||||
table->BTCGB_VDROOP_TABLE[0].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSON_a2);
|
||||
table->BTCGB_VDROOP_TABLE[1].a0 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a0);
|
||||
table->BTCGB_VDROOP_TABLE[1].a1 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a1);
|
||||
table->BTCGB_VDROOP_TABLE[1].a2 = PP_HOST_TO_SMC_UL(avfs_params.ulGB_VDROOP_TABLE_CKSOFF_a2);
|
||||
table->AVFSGB_VDROOP_TABLE[0].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_m1);
|
||||
table->AVFSGB_VDROOP_TABLE[0].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSON_m2);
|
||||
table->AVFSGB_VDROOP_TABLE[0].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSON_b);
|
||||
table->AVFSGB_VDROOP_TABLE[0].m1_shift = 24;
|
||||
table->AVFSGB_VDROOP_TABLE[0].m2_shift = 12;
|
||||
table->AVFSGB_VDROOP_TABLE[1].m1 = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_m1);
|
||||
table->AVFSGB_VDROOP_TABLE[1].m2 = PP_HOST_TO_SMC_US(avfs_params.usAVFSGB_FUSE_TABLE_CKSOFF_m2);
|
||||
table->AVFSGB_VDROOP_TABLE[1].b = PP_HOST_TO_SMC_UL(avfs_params.ulAVFSGB_FUSE_TABLE_CKSOFF_b);
|
||||
table->AVFSGB_VDROOP_TABLE[1].m1_shift = 24;
|
||||
table->AVFSGB_VDROOP_TABLE[1].m2_shift = 12;
|
||||
table->MaxVoltage = PP_HOST_TO_SMC_US(avfs_params.usMaxVoltage_0_25mv);
|
||||
AVFS_meanNsigma.Aconstant[0] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant0);
|
||||
AVFS_meanNsigma.Aconstant[1] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant1);
|
||||
AVFS_meanNsigma.Aconstant[2] = PP_HOST_TO_SMC_UL(avfs_params.ulAVFS_meanNsigma_Acontant2);
|
||||
AVFS_meanNsigma.DC_tol_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_DC_tol_sigma);
|
||||
AVFS_meanNsigma.Platform_mean = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_mean);
|
||||
AVFS_meanNsigma.PSM_Age_CompFactor = PP_HOST_TO_SMC_US(avfs_params.usPSM_Age_ComFactor);
|
||||
AVFS_meanNsigma.Platform_sigma = PP_HOST_TO_SMC_US(avfs_params.usAVFS_meanNsigma_Platform_sigma);
|
||||
|
||||
for (i = 0; i < NUM_VFT_COLUMNS; i++) {
|
||||
AVFS_meanNsigma.Static_Voltage_Offset[i] = (uint8_t)(sclk_table->entries[i].cks_voffset * 100 / 625);
|
||||
AVFS_SclkOffset.Sclk_Offset[i] = PP_HOST_TO_SMC_US((uint16_t)(sclk_table->entries[i].sclk_offset) / 100);
|
||||
}
|
||||
|
||||
result = polaris10_read_smc_sram_dword(smumgr,
|
||||
SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsMeanNSigma),
|
||||
&tmp, data->sram_end);
|
||||
|
||||
polaris10_copy_bytes_to_smc(smumgr,
|
||||
tmp,
|
||||
(uint8_t *)&AVFS_meanNsigma,
|
||||
sizeof(AVFS_meanNsigma_t),
|
||||
data->sram_end);
|
||||
|
||||
result = polaris10_read_smc_sram_dword(smumgr,
|
||||
SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU74_Firmware_Header, AvfsSclkOffsetTable),
|
||||
&tmp, data->sram_end);
|
||||
polaris10_copy_bytes_to_smc(smumgr,
|
||||
tmp,
|
||||
(uint8_t *)&AVFS_SclkOffset,
|
||||
sizeof(AVFS_Sclk_Offset_t),
|
||||
data->sram_end);
|
||||
|
||||
data->avfs_vdroop_override_setting = (avfs_params.ucEnableGB_VDROOP_TABLE_CKSON << BTCGB0_Vdroop_Enable_SHIFT) |
|
||||
(avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) |
|
||||
(avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) |
|
||||
(avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT);
|
||||
data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the SMC table and uploads it
|
||||
*
|
||||
|
@ -2056,6 +2060,10 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr)
|
|||
"Failed to populate Clock Stretcher Data Table!",
|
||||
return result);
|
||||
}
|
||||
|
||||
result = polaris10_populate_avfs_parameters(hwmgr);
|
||||
PP_ASSERT_WITH_CODE(0 == result, "Failed to populate AVFS Parameters!", return result;);
|
||||
|
||||
table->CurrSclkPllRange = 0xff;
|
||||
table->GraphicsVoltageChangeEnable = 1;
|
||||
table->GraphicsThermThrottleEnable = 1;
|
||||
|
@ -2252,6 +2260,9 @@ static int polaris10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
|
|||
static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
uint32_t soft_register_value = 0;
|
||||
uint32_t handshake_disables_offset = data->soft_regs_start
|
||||
+ offsetof(SMU74_SoftRegisters, HandshakeDisables);
|
||||
|
||||
/* enable SCLK dpm */
|
||||
if (!data->sclk_dpm_key_disabled)
|
||||
|
@ -2262,6 +2273,12 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
|||
|
||||
/* enable MCLK dpm */
|
||||
if (0 == data->mclk_dpm_key_disabled) {
|
||||
/* Disable UVD - SMU handshake for MCLK. */
|
||||
soft_register_value = cgs_read_ind_register(hwmgr->device,
|
||||
CGS_IND_REG__SMC, handshake_disables_offset);
|
||||
soft_register_value |= SMU7_UVD_MCLK_HANDSHAKE_DISABLE;
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
|
||||
handshake_disables_offset, soft_register_value);
|
||||
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(0 == smum_send_msg_to_smc(hwmgr->smumgr,
|
||||
|
@ -2269,7 +2286,6 @@ static int polaris10_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
|
|||
"Failed to enable MCLK DPM during DPM Start Function!",
|
||||
return -1);
|
||||
|
||||
|
||||
PHM_WRITE_FIELD(hwmgr->device, MC_SEQ_CNTL_3, CAC_EN, 0x1);
|
||||
|
||||
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixLCAC_MC0_CNTL, 0x5);
|
||||
|
@ -2606,6 +2622,7 @@ int polaris10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
|
|||
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_FanSpeedInTableIsRPM);
|
||||
|
||||
if (hwmgr->chip_id == CHIP_POLARIS11)
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_SPLLShutdownSupport);
|
||||
|
@ -2938,6 +2955,11 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = POLARIS10_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = POLARIS10_VOLTAGE_CONTROL_NONE;
|
||||
|
||||
data->enable_tdc_limit_feature = true;
|
||||
data->enable_pkg_pwr_tracking_feature = true;
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
data->mclk_stutter_mode_threshold = 40000;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2))
|
||||
data->voltage_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2;
|
||||
|
@ -2962,6 +2984,10 @@ int polaris10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vddci_control = POLARIS10_VOLTAGE_CONTROL_BY_SVID2;
|
||||
}
|
||||
|
||||
if (table_info->cac_dtp_table->usClockStretchAmount != 0)
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_ClockStretcher);
|
||||
|
||||
polaris10_set_features_platform_caps(hwmgr);
|
||||
|
||||
polaris10_init_dpm_defaults(hwmgr);
|
||||
|
|
|
@ -312,6 +312,9 @@ struct polaris10_hwmgr {
|
|||
|
||||
/* soft pptable for re-uploading into smu */
|
||||
void *soft_pp_table;
|
||||
|
||||
uint32_t avfs_vdroop_override_setting;
|
||||
bool apply_avfs_cks_off_voltage;
|
||||
};
|
||||
|
||||
/* To convert to Q8.8 format for firmware */
|
||||
|
|
|
@ -625,10 +625,14 @@ static int tf_polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
|
|||
int ret;
|
||||
struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
|
||||
struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
|
||||
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
|
||||
|
||||
if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS)
|
||||
if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
|
||||
return 0;
|
||||
|
||||
ret = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
|
||||
PPSMC_MSG_SetGBDroopSettings, data->avfs_vdroop_override_setting);
|
||||
|
||||
ret = (smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs) == 0) ?
|
||||
0 : -1;
|
||||
|
||||
|
|
|
@ -44,6 +44,20 @@ bool acpi_atcs_functions_supported(void *device, uint32_t index)
|
|||
return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
|
||||
}
|
||||
|
||||
bool acpi_atcs_notify_pcie_device_ready(void *device)
|
||||
{
|
||||
int32_t temp_buffer = 1;
|
||||
|
||||
return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
|
||||
ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
|
||||
&temp_buffer,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(temp_buffer),
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
||||
{
|
||||
struct atcs_pref_req_input atcs_input;
|
||||
|
@ -52,7 +66,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
|||
int result;
|
||||
struct cgs_system_info info = {0};
|
||||
|
||||
if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
|
||||
if( 0 != acpi_atcs_notify_pcie_device_ready(device))
|
||||
return -EINVAL;
|
||||
|
||||
info.size = sizeof(struct cgs_system_info);
|
||||
|
@ -77,7 +91,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
|
|||
ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
|
||||
&atcs_input,
|
||||
&atcs_output,
|
||||
0,
|
||||
1,
|
||||
sizeof(atcs_input),
|
||||
sizeof(atcs_output));
|
||||
if (result != 0)
|
||||
|
|
|
@ -1302,3 +1302,46 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param)
|
||||
{
|
||||
ATOM_ASIC_PROFILING_INFO_V3_6 *profile = NULL;
|
||||
|
||||
if (param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
profile = (ATOM_ASIC_PROFILING_INFO_V3_6 *)
|
||||
cgs_atom_get_data_table(hwmgr->device,
|
||||
GetIndexIntoMasterTable(DATA, ASIC_ProfilingInfo),
|
||||
NULL, NULL, NULL);
|
||||
if (!profile)
|
||||
return -1;
|
||||
|
||||
param->ulAVFS_meanNsigma_Acontant0 = profile->ulAVFS_meanNsigma_Acontant0;
|
||||
param->ulAVFS_meanNsigma_Acontant1 = profile->ulAVFS_meanNsigma_Acontant1;
|
||||
param->ulAVFS_meanNsigma_Acontant2 = profile->ulAVFS_meanNsigma_Acontant2;
|
||||
param->usAVFS_meanNsigma_DC_tol_sigma = profile->usAVFS_meanNsigma_DC_tol_sigma;
|
||||
param->usAVFS_meanNsigma_Platform_mean = profile->usAVFS_meanNsigma_Platform_mean;
|
||||
param->usAVFS_meanNsigma_Platform_sigma = profile->usAVFS_meanNsigma_Platform_sigma;
|
||||
param->ulGB_VDROOP_TABLE_CKSOFF_a0 = profile->ulGB_VDROOP_TABLE_CKSOFF_a0;
|
||||
param->ulGB_VDROOP_TABLE_CKSOFF_a1 = profile->ulGB_VDROOP_TABLE_CKSOFF_a1;
|
||||
param->ulGB_VDROOP_TABLE_CKSOFF_a2 = profile->ulGB_VDROOP_TABLE_CKSOFF_a2;
|
||||
param->ulGB_VDROOP_TABLE_CKSON_a0 = profile->ulGB_VDROOP_TABLE_CKSON_a0;
|
||||
param->ulGB_VDROOP_TABLE_CKSON_a1 = profile->ulGB_VDROOP_TABLE_CKSON_a1;
|
||||
param->ulGB_VDROOP_TABLE_CKSON_a2 = profile->ulGB_VDROOP_TABLE_CKSON_a2;
|
||||
param->ulAVFSGB_FUSE_TABLE_CKSOFF_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
|
||||
param->usAVFSGB_FUSE_TABLE_CKSOFF_m2 = profile->usAVFSGB_FUSE_TABLE_CKSOFF_m2;
|
||||
param->ulAVFSGB_FUSE_TABLE_CKSOFF_b = profile->ulAVFSGB_FUSE_TABLE_CKSOFF_b;
|
||||
param->ulAVFSGB_FUSE_TABLE_CKSON_m1 = profile->ulAVFSGB_FUSE_TABLE_CKSON_m1;
|
||||
param->usAVFSGB_FUSE_TABLE_CKSON_m2 = profile->usAVFSGB_FUSE_TABLE_CKSON_m2;
|
||||
param->ulAVFSGB_FUSE_TABLE_CKSON_b = profile->ulAVFSGB_FUSE_TABLE_CKSON_b;
|
||||
param->usMaxVoltage_0_25mv = profile->usMaxVoltage_0_25mv;
|
||||
param->ucEnableGB_VDROOP_TABLE_CKSOFF = profile->ucEnableGB_VDROOP_TABLE_CKSOFF;
|
||||
param->ucEnableGB_VDROOP_TABLE_CKSON = profile->ucEnableGB_VDROOP_TABLE_CKSON;
|
||||
param->ucEnableGB_FUSE_TABLE_CKSOFF = profile->ucEnableGB_FUSE_TABLE_CKSOFF;
|
||||
param->ucEnableGB_FUSE_TABLE_CKSON = profile->ucEnableGB_FUSE_TABLE_CKSON;
|
||||
param->usPSM_Age_ComFactor = profile->usPSM_Age_ComFactor;
|
||||
param->ucEnableApplyAVFS_CKS_OFF_Voltage = profile->ucEnableApplyAVFS_CKS_OFF_Voltage;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -250,6 +250,35 @@ struct pp_atomctrl_gpio_pin_assignment {
|
|||
};
|
||||
typedef struct pp_atomctrl_gpio_pin_assignment pp_atomctrl_gpio_pin_assignment;
|
||||
|
||||
struct pp_atom_ctrl__avfs_parameters {
|
||||
uint32_t ulAVFS_meanNsigma_Acontant0;
|
||||
uint32_t ulAVFS_meanNsigma_Acontant1;
|
||||
uint32_t ulAVFS_meanNsigma_Acontant2;
|
||||
uint16_t usAVFS_meanNsigma_DC_tol_sigma;
|
||||
uint16_t usAVFS_meanNsigma_Platform_mean;
|
||||
uint16_t usAVFS_meanNsigma_Platform_sigma;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSOFF_a0;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSOFF_a1;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSOFF_a2;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSON_a0;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSON_a1;
|
||||
uint32_t ulGB_VDROOP_TABLE_CKSON_a2;
|
||||
uint32_t ulAVFSGB_FUSE_TABLE_CKSOFF_m1;
|
||||
uint16_t usAVFSGB_FUSE_TABLE_CKSOFF_m2;
|
||||
uint32_t ulAVFSGB_FUSE_TABLE_CKSOFF_b;
|
||||
uint32_t ulAVFSGB_FUSE_TABLE_CKSON_m1;
|
||||
uint16_t usAVFSGB_FUSE_TABLE_CKSON_m2;
|
||||
uint32_t ulAVFSGB_FUSE_TABLE_CKSON_b;
|
||||
uint16_t usMaxVoltage_0_25mv;
|
||||
uint8_t ucEnableGB_VDROOP_TABLE_CKSOFF;
|
||||
uint8_t ucEnableGB_VDROOP_TABLE_CKSON;
|
||||
uint8_t ucEnableGB_FUSE_TABLE_CKSOFF;
|
||||
uint8_t ucEnableGB_FUSE_TABLE_CKSON;
|
||||
uint16_t usPSM_Age_ComFactor;
|
||||
uint8_t ucEnableApplyAVFS_CKS_OFF_Voltage;
|
||||
uint8_t ucReserved;
|
||||
};
|
||||
|
||||
extern bool atomctrl_get_pp_assign_pin(struct pp_hwmgr *hwmgr, const uint32_t pinId, pp_atomctrl_gpio_pin_assignment *gpio_pin_assignment);
|
||||
extern int atomctrl_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
|
||||
extern uint32_t atomctrl_get_mpll_reference_clock(struct pp_hwmgr *hwmgr);
|
||||
|
@ -278,5 +307,8 @@ extern int atomctrl_set_ac_timing_ai(struct pp_hwmgr *hwmgr, uint32_t memory_clo
|
|||
extern int atomctrl_get_voltage_evv_on_sclk_ai(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
|
||||
uint32_t sclk, uint16_t virtual_voltage_Id, uint16_t *voltage);
|
||||
extern int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl_sclk_range_table *table);
|
||||
|
||||
extern int atomctrl_get_avfs_information(struct pp_hwmgr *hwmgr, struct pp_atom_ctrl__avfs_parameters *param);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4489,6 +4489,7 @@ int tonga_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
data->vdd_ci_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->vdd_gfx_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->mvdd_control = TONGA_VOLTAGE_CONTROL_NONE;
|
||||
data->force_pcie_gen = PP_PCIEGenInvalid;
|
||||
|
||||
if (atomctrl_is_voltage_controled_by_gpio_v3(hwmgr,
|
||||
VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#define PPSMC_MSG_SetGBDroopSettings ((uint16_t) 0x305)
|
||||
|
||||
#define PPSMC_SWSTATE_FLAG_DC 0x01
|
||||
#define PPSMC_SWSTATE_FLAG_UVD 0x02
|
||||
|
|
|
@ -26,3 +26,4 @@ extern bool acpi_atcs_functions_supported(void *device,
|
|||
extern int acpi_pcie_perf_request(void *device,
|
||||
uint8_t perf_req,
|
||||
bool advertise);
|
||||
extern bool acpi_atcs_notify_pcie_device_ready(void *device);
|
||||
|
|
|
@ -34,6 +34,30 @@
|
|||
#define SMU__NUM_LCLK_DPM_LEVELS 8
|
||||
#define SMU__NUM_PCIE_DPM_LEVELS 8
|
||||
|
||||
#define EXP_M1 35
|
||||
#define EXP_M2 92821
|
||||
#define EXP_B 66629747
|
||||
|
||||
#define EXP_M1_1 365
|
||||
#define EXP_M2_1 658700
|
||||
#define EXP_B_1 305506134
|
||||
|
||||
#define EXP_M1_2 189
|
||||
#define EXP_M2_2 379692
|
||||
#define EXP_B_2 194609469
|
||||
|
||||
#define EXP_M1_3 99
|
||||
#define EXP_M2_3 217915
|
||||
#define EXP_B_3 122255994
|
||||
|
||||
#define EXP_M1_4 51
|
||||
#define EXP_M2_4 122643
|
||||
#define EXP_B_4 74893384
|
||||
|
||||
#define EXP_M1_5 423
|
||||
#define EXP_M2_5 1103326
|
||||
#define EXP_B_5 728122621
|
||||
|
||||
enum SID_OPTION {
|
||||
SID_OPTION_HI,
|
||||
SID_OPTION_LO,
|
||||
|
@ -548,20 +572,20 @@ struct SMU74_Firmware_Header {
|
|||
uint32_t CacConfigTable;
|
||||
uint32_t CacStatusTable;
|
||||
|
||||
|
||||
uint32_t mcRegisterTable;
|
||||
|
||||
|
||||
uint32_t mcArbDramTimingTable;
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t PmFuseTable;
|
||||
uint32_t Globals;
|
||||
uint32_t ClockStretcherTable;
|
||||
uint32_t VftTable;
|
||||
uint32_t Reserved[21];
|
||||
uint32_t Reserved1;
|
||||
uint32_t AvfsTable;
|
||||
uint32_t AvfsCksOffGbvTable;
|
||||
uint32_t AvfsMeanNSigma;
|
||||
uint32_t AvfsSclkOffsetTable;
|
||||
uint32_t Reserved[16];
|
||||
uint32_t Signature;
|
||||
};
|
||||
|
||||
|
@ -701,8 +725,6 @@ VR Config info is contained in dpmTable.VRConfig */
|
|||
struct SMU_ClockStretcherDataTableEntry {
|
||||
uint8_t minVID;
|
||||
uint8_t maxVID;
|
||||
|
||||
|
||||
uint16_t setting;
|
||||
};
|
||||
typedef struct SMU_ClockStretcherDataTableEntry SMU_ClockStretcherDataTableEntry;
|
||||
|
@ -769,6 +791,43 @@ struct VFT_TABLE_t {
|
|||
typedef struct VFT_TABLE_t VFT_TABLE_t;
|
||||
|
||||
|
||||
/* Total margin, root mean square of Fmax + DC + Platform */
|
||||
struct AVFS_Margin_t {
|
||||
VFT_CELL_t Cell[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_Margin_t AVFS_Margin_t;
|
||||
|
||||
#define BTCGB_VDROOP_TABLE_MAX_ENTRIES 2
|
||||
#define AVFSGB_VDROOP_TABLE_MAX_ENTRIES 2
|
||||
|
||||
struct GB_VDROOP_TABLE_t {
|
||||
int32_t a0;
|
||||
int32_t a1;
|
||||
int32_t a2;
|
||||
uint32_t spare;
|
||||
};
|
||||
typedef struct GB_VDROOP_TABLE_t GB_VDROOP_TABLE_t;
|
||||
|
||||
struct AVFS_CksOff_Gbv_t {
|
||||
VFT_CELL_t Cell[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_CksOff_Gbv_t AVFS_CksOff_Gbv_t;
|
||||
|
||||
struct AVFS_meanNsigma_t {
|
||||
uint32_t Aconstant[3];
|
||||
uint16_t DC_tol_sigma;
|
||||
uint16_t Platform_mean;
|
||||
uint16_t Platform_sigma;
|
||||
uint16_t PSM_Age_CompFactor;
|
||||
uint8_t Static_Voltage_Offset[NUM_VFT_COLUMNS];
|
||||
};
|
||||
typedef struct AVFS_meanNsigma_t AVFS_meanNsigma_t;
|
||||
|
||||
struct AVFS_Sclk_Offset_t {
|
||||
uint16_t Sclk_Offset[8];
|
||||
};
|
||||
typedef struct AVFS_Sclk_Offset_t AVFS_Sclk_Offset_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -223,6 +223,16 @@ struct SMU74_Discrete_StateInfo {
|
|||
|
||||
typedef struct SMU74_Discrete_StateInfo SMU74_Discrete_StateInfo;
|
||||
|
||||
struct SMU_QuadraticCoeffs {
|
||||
int32_t m1;
|
||||
uint32_t b;
|
||||
|
||||
int16_t m2;
|
||||
uint8_t m1_shift;
|
||||
uint8_t m2_shift;
|
||||
};
|
||||
typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
|
||||
|
||||
struct SMU74_Discrete_DpmTable {
|
||||
|
||||
SMU74_PIDController GraphicsPIDController;
|
||||
|
@ -258,7 +268,14 @@ struct SMU74_Discrete_DpmTable {
|
|||
uint8_t ThermOutPolarity;
|
||||
uint8_t ThermOutMode;
|
||||
uint8_t BootPhases;
|
||||
uint32_t Reserved[4];
|
||||
|
||||
uint8_t VRHotLevel;
|
||||
uint8_t Reserved1[3];
|
||||
uint16_t FanStartTemperature;
|
||||
uint16_t FanStopTemperature;
|
||||
uint16_t MaxVoltage;
|
||||
uint16_t Reserved2;
|
||||
uint32_t Reserved[1];
|
||||
|
||||
SMU74_Discrete_GraphicsLevel GraphicsLevel[SMU74_MAX_LEVELS_GRAPHICS];
|
||||
SMU74_Discrete_MemoryLevel MemoryACPILevel;
|
||||
|
@ -347,6 +364,8 @@ struct SMU74_Discrete_DpmTable {
|
|||
|
||||
uint32_t CurrSclkPllRange;
|
||||
sclkFcwRange_t SclkFcwRangeTable[NUM_SCLK_RANGE];
|
||||
GB_VDROOP_TABLE_t BTCGB_VDROOP_TABLE[BTCGB_VDROOP_TABLE_MAX_ENTRIES];
|
||||
SMU_QuadraticCoeffs AVFSGB_VDROOP_TABLE[AVFSGB_VDROOP_TABLE_MAX_ENTRIES];
|
||||
};
|
||||
|
||||
typedef struct SMU74_Discrete_DpmTable SMU74_Discrete_DpmTable;
|
||||
|
@ -550,16 +569,6 @@ struct SMU7_AcpiScoreboard {
|
|||
|
||||
typedef struct SMU7_AcpiScoreboard SMU7_AcpiScoreboard;
|
||||
|
||||
struct SMU_QuadraticCoeffs {
|
||||
int32_t m1;
|
||||
uint32_t b;
|
||||
|
||||
int16_t m2;
|
||||
uint8_t m1_shift;
|
||||
uint8_t m2_shift;
|
||||
};
|
||||
typedef struct SMU_QuadraticCoeffs SMU_QuadraticCoeffs;
|
||||
|
||||
struct SMU74_Discrete_PmFuses {
|
||||
uint8_t BapmVddCVidHiSidd[8];
|
||||
uint8_t BapmVddCVidLoSidd[8];
|
||||
|
@ -821,6 +830,17 @@ typedef struct SMU7_GfxCuPgScoreboard SMU7_GfxCuPgScoreboard;
|
|||
#define DB_PCC_SHIFT 26
|
||||
#define DB_EDC_SHIFT 27
|
||||
|
||||
#define BTCGB0_Vdroop_Enable_MASK 0x1
|
||||
#define BTCGB1_Vdroop_Enable_MASK 0x2
|
||||
#define AVFSGB0_Vdroop_Enable_MASK 0x4
|
||||
#define AVFSGB1_Vdroop_Enable_MASK 0x8
|
||||
|
||||
#define BTCGB0_Vdroop_Enable_SHIFT 0
|
||||
#define BTCGB1_Vdroop_Enable_SHIFT 1
|
||||
#define AVFSGB0_Vdroop_Enable_SHIFT 2
|
||||
#define AVFSGB1_Vdroop_Enable_SHIFT 3
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
|
|
|
@ -52,19 +52,18 @@
|
|||
static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = {
|
||||
/* Min pcie DeepSleep Activity CgSpll CgSpll CcPwr CcPwr Sclk Enabled Enabled Voltage Power */
|
||||
/* Voltage, DpmLevel, DivId, Level, FuncCntl3, FuncCntl4, DynRm, DynRm1 Did, Padding,ForActivity, ForThrottle, UpHyst, DownHyst, DownHyst, Throttle */
|
||||
{ 0x3c0fd047, 0x00, 0x03, 0x1e00, 0x00200410, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x30750000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xa00fd047, 0x01, 0x04, 0x1e00, 0x00800510, 0x87020000, 0, 0, 0x16, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x409c0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x0410d047, 0x01, 0x00, 0x1e00, 0x00600410, 0x87020000, 0, 0, 0x0e, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x50c30000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x6810d047, 0x01, 0x00, 0x1e00, 0x00800410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x60ea0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xcc10d047, 0x01, 0x00, 0x1e00, 0x00e00410, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xe8fd0000, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x3011d047, 0x01, 0x00, 0x1e00, 0x00400510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x70110100, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0x9411d047, 0x01, 0x00, 0x1e00, 0x00a00510, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0xf8240100, 0, 0, 0, 0, 0, 0, 0 } },
|
||||
{ 0xf811d047, 0x01, 0x00, 0x1e00, 0x00000610, 0x87020000, 0, 0, 0x0c, 0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, { 0x80380100, 0, 0, 0, 0, 0, 0, 0 } }
|
||||
{ 0x100ea446, 0x00, 0x03, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x30750000, 0x3000, 0, 0x2600, 0, 0, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
|
||||
{ 0x400ea446, 0x01, 0x04, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x409c0000, 0x2000, 0, 0x1e00, 1, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
|
||||
{ 0x740ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x50c30000, 0x2800, 0, 0x2000, 1, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } },
|
||||
{ 0xa40ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x60ea0000, 0x3000, 0, 0x2600, 1, 1, 0x0004, 0x8f02, 0xffff, 0x2f00, 0x300e, 0x2700 } },
|
||||
{ 0xd80ea446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x70110100, 0x3800, 0, 0x2c00, 1, 1, 0x0004, 0x1203, 0xffff, 0x3600, 0xc9e2, 0x2e00 } },
|
||||
{ 0x3c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x80380100, 0x2000, 0, 0x1e00, 2, 1, 0x0004, 0x8300, 0xffff, 0x1f00, 0xcb5e, 0x1a00 } },
|
||||
{ 0x6c0fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0x905f0100, 0x2400, 0, 0x1e00, 2, 1, 0x0004, 0x8901, 0xffff, 0x2300, 0x314c, 0x1d00 } },
|
||||
{ 0xa00fa446, 0x01, 0x00, 0x3200, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x00, { 0xa0860100, 0x2800, 0, 0x2000, 2, 1, 0x0004, 0x0c02, 0xffff, 0x2700, 0x6433, 0x2100 } }
|
||||
};
|
||||
|
||||
static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 =
|
||||
{0x50140000, 0x50140000, 0x00320000, 0x00, 0x00,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0000, 0x00, 0x00};
|
||||
{0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* Set the address for reading/writing the SMC SRAM space.
|
||||
|
@ -219,6 +218,18 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr)
|
|||
&& (0x20100 <= cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMC_PC_C)));
|
||||
}
|
||||
|
||||
static bool polaris10_is_hw_avfs_present(struct pp_smumgr *smumgr)
|
||||
{
|
||||
uint32_t efuse;
|
||||
|
||||
efuse = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC, ixSMU_EFUSE_0 + (49*4));
|
||||
efuse &= 0x00000001;
|
||||
if (efuse)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the SMC, and wait for its response.
|
||||
*
|
||||
|
@ -228,21 +239,27 @@ bool polaris10_is_smc_ram_running(struct pp_smumgr *smumgr)
|
|||
*/
|
||||
int polaris10_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!polaris10_is_smc_ram_running(smumgr))
|
||||
return -1;
|
||||
|
||||
|
||||
SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
|
||||
|
||||
if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP))
|
||||
printk("Failed to send Previous Message.\n");
|
||||
ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP);
|
||||
|
||||
if (ret != 1)
|
||||
printk("\n failed to send pre message %x ret is %d \n", msg, ret);
|
||||
|
||||
cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
|
||||
|
||||
SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
|
||||
|
||||
if (1 != SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP))
|
||||
printk("Failed to send Message.\n");
|
||||
ret = SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP);
|
||||
|
||||
if (ret != 1)
|
||||
printk("\n failed to send message %x ret is %d \n", msg, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -953,6 +970,11 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr)
|
|||
(cgs_handle_t)smu_data->smu_buffer.handle);
|
||||
return -1;);
|
||||
|
||||
if (polaris10_is_hw_avfs_present(smumgr))
|
||||
smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
|
||||
else
|
||||
smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,9 +266,10 @@ int atmel_hlcdc_create_outputs(struct drm_device *dev)
|
|||
if (!ret)
|
||||
ret = atmel_hlcdc_check_endpoint(dev, &ep);
|
||||
|
||||
of_node_put(ep_np);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(ep_np);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_endpoint_of_node(dev->dev->of_node, ep_np) {
|
||||
|
@ -276,9 +277,10 @@ int atmel_hlcdc_create_outputs(struct drm_device *dev)
|
|||
if (!ret)
|
||||
ret = atmel_hlcdc_attach_endpoint(dev, &ep);
|
||||
|
||||
of_node_put(ep_np);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(ep_np);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -339,6 +339,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
|
|||
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
|
||||
factor_reg);
|
||||
} else {
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1296,14 +1296,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_planes);
|
|||
*/
|
||||
void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_device *dev = state->dev;
|
||||
unsigned crtc_mask = 0;
|
||||
struct drm_crtc *crtc;
|
||||
int ret;
|
||||
bool global = false;
|
||||
|
||||
drm_for_each_crtc(crtc, dev) {
|
||||
if (crtc->acquire_ctx != state->acquire_ctx)
|
||||
continue;
|
||||
|
||||
crtc_mask |= drm_crtc_mask(crtc);
|
||||
crtc->acquire_ctx = NULL;
|
||||
}
|
||||
|
||||
if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
|
||||
global = true;
|
||||
|
||||
dev->mode_config.acquire_ctx = NULL;
|
||||
}
|
||||
|
||||
retry:
|
||||
drm_modeset_backoff(state->acquire_ctx);
|
||||
|
||||
ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
|
||||
ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
|
||||
if (ret)
|
||||
goto retry;
|
||||
|
||||
drm_for_each_crtc(crtc, dev)
|
||||
if (drm_crtc_mask(crtc) & crtc_mask)
|
||||
crtc->acquire_ctx = state->acquire_ctx;
|
||||
|
||||
if (global)
|
||||
dev->mode_config.acquire_ctx = state->acquire_ctx;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_legacy_backoff);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "exynos_drm_plane.h"
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_fb.h"
|
||||
#include "exynos_drm_fbdev.h"
|
||||
#include "exynos_drm_iommu.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
struct exynos_dp_device {
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
struct drm_connector *connector;
|
||||
struct drm_bridge *ptn_bridge;
|
||||
struct drm_device *drm_dev;
|
||||
struct device *dev;
|
||||
|
@ -70,7 +70,7 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
|
|||
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data)
|
||||
{
|
||||
struct exynos_dp_device *dp = to_dp(plat_data);
|
||||
struct drm_connector *connector = &dp->connector;
|
||||
struct drm_connector *connector = dp->connector;
|
||||
struct drm_display_mode *mode;
|
||||
int num_modes = 0;
|
||||
|
||||
|
@ -103,6 +103,7 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
|
|||
int ret;
|
||||
|
||||
drm_connector_register(connector);
|
||||
dp->connector = connector;
|
||||
|
||||
/* Pre-empt DP connector creation if there's a bridge */
|
||||
if (dp->ptn_bridge) {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <drm/drmP.h>
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_crtc.h"
|
||||
#include "exynos_drm_fbdev.h"
|
||||
|
||||
static LIST_HEAD(exynos_drm_subdrv_list);
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_fb.h"
|
||||
#include "exynos_drm_fbdev.h"
|
||||
#include "exynos_drm_crtc.h"
|
||||
#include "exynos_drm_plane.h"
|
||||
#include "exynos_drm_iommu.h"
|
||||
|
@ -120,7 +119,6 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
|
|||
.timing_base = 0x0,
|
||||
.has_clksel = 1,
|
||||
.has_limited_fmt = 1,
|
||||
.has_hw_trigger = 1,
|
||||
};
|
||||
|
||||
static struct fimd_driver_data exynos3_fimd_driver_data = {
|
||||
|
@ -171,14 +169,11 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = {
|
|||
.lcdblk_vt_shift = 24,
|
||||
.lcdblk_bypass_shift = 15,
|
||||
.lcdblk_mic_bypass_shift = 11,
|
||||
.trg_type = I80_HW_TRG,
|
||||
.has_shadowcon = 1,
|
||||
.has_vidoutcon = 1,
|
||||
.has_vtsel = 1,
|
||||
.has_mic_bypass = 1,
|
||||
.has_dp_clk = 1,
|
||||
.has_hw_trigger = 1,
|
||||
.has_trigger_per_te = 1,
|
||||
};
|
||||
|
||||
struct fimd_context {
|
||||
|
|
|
@ -48,13 +48,13 @@
|
|||
|
||||
/* registers for base address */
|
||||
#define G2D_SRC_BASE_ADDR 0x0304
|
||||
#define G2D_SRC_STRIDE_REG 0x0308
|
||||
#define G2D_SRC_STRIDE 0x0308
|
||||
#define G2D_SRC_COLOR_MODE 0x030C
|
||||
#define G2D_SRC_LEFT_TOP 0x0310
|
||||
#define G2D_SRC_RIGHT_BOTTOM 0x0314
|
||||
#define G2D_SRC_PLANE2_BASE_ADDR 0x0318
|
||||
#define G2D_DST_BASE_ADDR 0x0404
|
||||
#define G2D_DST_STRIDE_REG 0x0408
|
||||
#define G2D_DST_STRIDE 0x0408
|
||||
#define G2D_DST_COLOR_MODE 0x040C
|
||||
#define G2D_DST_LEFT_TOP 0x0410
|
||||
#define G2D_DST_RIGHT_BOTTOM 0x0414
|
||||
|
@ -563,7 +563,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
|
|||
|
||||
switch (reg_offset) {
|
||||
case G2D_SRC_BASE_ADDR:
|
||||
case G2D_SRC_STRIDE_REG:
|
||||
case G2D_SRC_STRIDE:
|
||||
case G2D_SRC_COLOR_MODE:
|
||||
case G2D_SRC_LEFT_TOP:
|
||||
case G2D_SRC_RIGHT_BOTTOM:
|
||||
|
@ -573,7 +573,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
|
|||
reg_type = REG_TYPE_SRC_PLANE2;
|
||||
break;
|
||||
case G2D_DST_BASE_ADDR:
|
||||
case G2D_DST_STRIDE_REG:
|
||||
case G2D_DST_STRIDE:
|
||||
case G2D_DST_COLOR_MODE:
|
||||
case G2D_DST_LEFT_TOP:
|
||||
case G2D_DST_RIGHT_BOTTOM:
|
||||
|
@ -968,8 +968,8 @@ static int g2d_check_reg_offset(struct device *dev,
|
|||
} else
|
||||
buf_info->types[reg_type] = BUF_TYPE_GEM;
|
||||
break;
|
||||
case G2D_SRC_STRIDE_REG:
|
||||
case G2D_DST_STRIDE_REG:
|
||||
case G2D_SRC_STRIDE:
|
||||
case G2D_DST_STRIDE:
|
||||
if (for_addr)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config,
|
|||
state->v_ratio == (1 << 15))
|
||||
height_ok = true;
|
||||
|
||||
if (width_ok & height_ok)
|
||||
if (width_ok && height_ok)
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG_KMS("scaling mode is not supported");
|
||||
|
|
|
@ -4977,9 +4977,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
|
|||
intel_display_power_get(dev_priv, power_domain);
|
||||
|
||||
if (long_hpd) {
|
||||
/* indicate that we need to restart link training */
|
||||
intel_dp->train_set_valid = false;
|
||||
|
||||
intel_dp_long_pulse(intel_dp->attached_connector);
|
||||
if (intel_dp->is_mst)
|
||||
ret = IRQ_HANDLED;
|
||||
|
|
|
@ -85,8 +85,7 @@ static bool
|
|||
intel_dp_reset_link_train(struct intel_dp *intel_dp,
|
||||
uint8_t dp_train_pat)
|
||||
{
|
||||
if (!intel_dp->train_set_valid)
|
||||
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
|
||||
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
|
||||
intel_dp_set_signal_levels(intel_dp);
|
||||
return intel_dp_set_link_train(intel_dp, dp_train_pat);
|
||||
}
|
||||
|
@ -161,23 +160,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we used previously trained voltage and pre-emphasis values
|
||||
* and we don't get clock recovery, reset link training values
|
||||
*/
|
||||
if (intel_dp->train_set_valid) {
|
||||
DRM_DEBUG_KMS("clock recovery not ok, reset");
|
||||
/* clear the flag as we are not reusing train set */
|
||||
intel_dp->train_set_valid = false;
|
||||
if (!intel_dp_reset_link_train(intel_dp,
|
||||
DP_TRAINING_PATTERN_1 |
|
||||
DP_LINK_SCRAMBLING_DISABLE)) {
|
||||
DRM_ERROR("failed to enable link training\n");
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check to see if we've tried the max voltage */
|
||||
for (i = 0; i < intel_dp->lane_count; i++)
|
||||
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
|
||||
|
@ -284,7 +266,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
/* Make sure clock is still ok */
|
||||
if (!drm_dp_clock_recovery_ok(link_status,
|
||||
intel_dp->lane_count)) {
|
||||
intel_dp->train_set_valid = false;
|
||||
intel_dp_link_training_clock_recovery(intel_dp);
|
||||
intel_dp_set_link_train(intel_dp,
|
||||
training_pattern |
|
||||
|
@ -301,7 +282,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
|
||||
/* Try 5 times, then try clock recovery if that fails */
|
||||
if (tries > 5) {
|
||||
intel_dp->train_set_valid = false;
|
||||
intel_dp_link_training_clock_recovery(intel_dp);
|
||||
intel_dp_set_link_train(intel_dp,
|
||||
training_pattern |
|
||||
|
@ -322,10 +302,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
|
||||
intel_dp_set_idle_link_train(intel_dp);
|
||||
|
||||
if (channel_eq) {
|
||||
intel_dp->train_set_valid = true;
|
||||
if (channel_eq)
|
||||
DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
|
||||
}
|
||||
}
|
||||
|
||||
void intel_dp_stop_link_train(struct intel_dp *intel_dp)
|
||||
|
|
|
@ -863,8 +863,6 @@ struct intel_dp {
|
|||
/* This is called before a link training is starterd */
|
||||
void (*prepare_link_retrain)(struct intel_dp *intel_dp);
|
||||
|
||||
bool train_set_valid;
|
||||
|
||||
/* Displayport compliance testing */
|
||||
unsigned long compliance_test_type;
|
||||
unsigned long compliance_test_data;
|
||||
|
|
|
@ -824,8 +824,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
||||
struct intel_fbc *fbc = &dev_priv->fbc;
|
||||
bool enable_by_default = IS_HASWELL(dev_priv) ||
|
||||
IS_BROADWELL(dev_priv);
|
||||
bool enable_by_default = IS_BROADWELL(dev_priv);
|
||||
|
||||
if (intel_vgpu_active(dev_priv->dev)) {
|
||||
fbc->no_fbc_reason = "VGPU is active";
|
||||
|
|
|
@ -552,7 +552,8 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
if (ret)
|
||||
goto fini;
|
||||
|
||||
fbcon->helper.fbdev->pixmap.buf_align = 4;
|
||||
if (fbcon->helper.fbdev)
|
||||
fbcon->helper.fbdev->pixmap.buf_align = 4;
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
config DRM_SUN4I
|
||||
tristate "DRM Support for Allwinner A10 Display Engine"
|
||||
depends on DRM && ARM
|
||||
depends on DRM && ARM && COMMON_CLK
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
select DRM_GEM_CMA_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
|
|
|
@ -190,7 +190,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
|
|||
/* Get the physical address of the buffer in memory */
|
||||
gem = drm_fb_cma_get_gem_obj(fb, 0);
|
||||
|
||||
DRM_DEBUG_DRIVER("Using GEM @ 0x%x\n", gem->paddr);
|
||||
DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->paddr);
|
||||
|
||||
/* Compute the start of the displayed memory */
|
||||
bpp = drm_format_plane_cpp(fb->pixel_format, 0);
|
||||
|
@ -198,7 +198,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
|
|||
paddr += (state->src_x >> 16) * bpp;
|
||||
paddr += (state->src_y >> 16) * fb->pitches[0];
|
||||
|
||||
DRM_DEBUG_DRIVER("Setting buffer address to 0x%x\n", paddr);
|
||||
DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
|
||||
|
||||
/* Write the 32 lower bits of the address (in bits) */
|
||||
lo_paddr = paddr << 3;
|
||||
|
|
|
@ -72,14 +72,40 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
|
|||
static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
return *parent_rate / DIV_ROUND_CLOSEST(*parent_rate, rate);
|
||||
unsigned long best_parent = 0;
|
||||
u8 best_div = 1;
|
||||
int i;
|
||||
|
||||
for (i = 6; i < 127; i++) {
|
||||
unsigned long ideal = rate * i;
|
||||
unsigned long rounded;
|
||||
|
||||
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
|
||||
ideal);
|
||||
|
||||
if (rounded == ideal) {
|
||||
best_parent = rounded;
|
||||
best_div = i;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((rounded < ideal) && (rounded > best_parent)) {
|
||||
best_parent = rounded;
|
||||
best_div = i;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*parent_rate = best_parent;
|
||||
|
||||
return best_parent / best_div;
|
||||
}
|
||||
|
||||
static int sun4i_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sun4i_dclk *dclk = hw_to_dclk(hw);
|
||||
int div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
u8 div = parent_rate / rate;
|
||||
|
||||
return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
|
||||
GENMASK(6, 0), div);
|
||||
|
@ -127,10 +153,14 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon)
|
|||
const char *clk_name, *parent_name;
|
||||
struct clk_init_data init;
|
||||
struct sun4i_dclk *dclk;
|
||||
int ret;
|
||||
|
||||
parent_name = __clk_get_name(tcon->sclk0);
|
||||
of_property_read_string_index(dev->of_node, "clock-output-names", 0,
|
||||
&clk_name);
|
||||
ret = of_property_read_string_index(dev->of_node,
|
||||
"clock-output-names", 0,
|
||||
&clk_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
|
||||
if (!dclk)
|
||||
|
@ -140,6 +170,7 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon)
|
|||
init.ops = &sun4i_dclk_ops;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
|
||||
dclk->regmap = tcon->regs;
|
||||
dclk->hw.init = &init;
|
||||
|
|
|
@ -24,34 +24,6 @@
|
|||
#include "sun4i_layer.h"
|
||||
#include "sun4i_tcon.h"
|
||||
|
||||
static int sun4i_drv_connector_plug_all(struct drm_device *drm)
|
||||
{
|
||||
struct drm_connector *connector, *failed;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&drm->mode_config.mutex);
|
||||
list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
|
||||
ret = drm_connector_register(connector);
|
||||
if (ret) {
|
||||
failed = connector;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&drm->mode_config.mutex);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
|
||||
if (failed == connector)
|
||||
break;
|
||||
|
||||
drm_connector_unregister(connector);
|
||||
}
|
||||
mutex_unlock(&drm->mode_config.mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe)
|
||||
{
|
||||
struct sun4i_drv *drv = drm->dev_private;
|
||||
|
@ -125,6 +97,22 @@ static struct drm_driver sun4i_drv_driver = {
|
|||
.disable_vblank = sun4i_drv_disable_vblank,
|
||||
};
|
||||
|
||||
static void sun4i_remove_framebuffers(void)
|
||||
{
|
||||
struct apertures_struct *ap;
|
||||
|
||||
ap = alloc_apertures(1);
|
||||
if (!ap)
|
||||
return;
|
||||
|
||||
/* The framebuffer can be located anywhere in RAM */
|
||||
ap->ranges[0].base = 0;
|
||||
ap->ranges[0].size = ~0;
|
||||
|
||||
remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false);
|
||||
kfree(ap);
|
||||
}
|
||||
|
||||
static int sun4i_drv_bind(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm;
|
||||
|
@ -172,6 +160,9 @@ static int sun4i_drv_bind(struct device *dev)
|
|||
}
|
||||
drm->irq_enabled = true;
|
||||
|
||||
/* Remove early framebuffers (ie. simplefb) */
|
||||
sun4i_remove_framebuffers();
|
||||
|
||||
/* Create our framebuffer */
|
||||
drv->fbdev = sun4i_framebuffer_init(drm);
|
||||
if (IS_ERR(drv->fbdev)) {
|
||||
|
@ -187,7 +178,7 @@ static int sun4i_drv_bind(struct device *dev)
|
|||
if (ret)
|
||||
goto free_drm;
|
||||
|
||||
ret = sun4i_drv_connector_plug_all(drm);
|
||||
ret = drm_connector_register_all(drm);
|
||||
if (ret)
|
||||
goto unregister_drm;
|
||||
|
||||
|
@ -204,6 +195,7 @@ static void sun4i_drv_unbind(struct device *dev)
|
|||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
|
||||
drm_connector_unregister_all(drm);
|
||||
drm_dev_unregister(drm);
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
sun4i_framebuffer_free(drm);
|
||||
|
|
|
@ -54,8 +54,13 @@ static int sun4i_rgb_get_modes(struct drm_connector *connector)
|
|||
static int sun4i_rgb_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector);
|
||||
struct sun4i_drv *drv = rgb->drv;
|
||||
struct sun4i_tcon *tcon = drv->tcon;
|
||||
u32 hsync = mode->hsync_end - mode->hsync_start;
|
||||
u32 vsync = mode->vsync_end - mode->vsync_start;
|
||||
unsigned long rate = mode->clock * 1000;
|
||||
long rounded_rate;
|
||||
|
||||
DRM_DEBUG_DRIVER("Validating modes...\n");
|
||||
|
||||
|
@ -87,6 +92,15 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
|
|||
|
||||
DRM_DEBUG_DRIVER("Vertical parameters OK\n");
|
||||
|
||||
rounded_rate = clk_round_rate(tcon->dclk, rate);
|
||||
if (rounded_rate < rate)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
||||
if (rounded_rate > rate)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
DRM_DEBUG_DRIVER("Clock rate OK\n");
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
|
@ -203,7 +217,7 @@ int sun4i_rgb_init(struct drm_device *drm)
|
|||
int ret;
|
||||
|
||||
/* If we don't have a panel, there's no point in going on */
|
||||
if (!tcon->panel)
|
||||
if (IS_ERR(tcon->panel))
|
||||
return -ENODEV;
|
||||
|
||||
rgb = devm_kzalloc(drm->dev, sizeof(*rgb), GFP_KERNEL);
|
||||
|
|
|
@ -425,11 +425,11 @@ static struct drm_panel *sun4i_tcon_find_panel(struct device_node *node)
|
|||
|
||||
remote = of_graph_get_remote_port_parent(end_node);
|
||||
if (!remote) {
|
||||
DRM_DEBUG_DRIVER("Enable to parse remote node\n");
|
||||
DRM_DEBUG_DRIVER("Unable to parse remote node\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return of_drm_find_panel(remote);
|
||||
return of_drm_find_panel(remote) ?: ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
|
||||
static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
||||
|
@ -490,7 +490,11 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return sun4i_rgb_init(drm);
|
||||
ret = sun4i_rgb_init(drm);
|
||||
if (ret < 0)
|
||||
goto err_free_clocks;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_clocks:
|
||||
sun4i_tcon_free_clocks(tcon);
|
||||
|
@ -522,12 +526,13 @@ static int sun4i_tcon_probe(struct platform_device *pdev)
|
|||
* Defer the probe.
|
||||
*/
|
||||
panel = sun4i_tcon_find_panel(node);
|
||||
if (IS_ERR(panel)) {
|
||||
/*
|
||||
* If we don't have a panel endpoint, just go on
|
||||
*/
|
||||
if (PTR_ERR(panel) != -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
/*
|
||||
* If we don't have a panel endpoint, just go on
|
||||
*/
|
||||
if (PTR_ERR(panel) == -EPROBE_DEFER) {
|
||||
DRM_DEBUG_DRIVER("Still waiting for our panel. Deferring...\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
return component_add(&pdev->dev, &sun4i_tcon_ops);
|
||||
|
|
Loading…
Reference in a new issue