drm fixes for 5.9-rc3

core:
 - Take modeset bkl for legacy drivers.
 
 dp_mst:
 - Allow null crtc in dp_mst.
 
 i915:
 - Fix command parser desc matching with masks
 
 amdgpu:
 - Misc display fixes
 - Backlight fixes
 - MPO fix for DCN1
 - Fixes for Sienna Cichlid
 - Fixes for Navy Flounder
 - Vega SW CTF fixes
 - SMU fix for Raven
 - Fix a possible overflow in INFO ioctl
 - Gfx10 clockgating fix
 
 msm:
 - opp/bw scaling patch followup
 - frequency restoring fux
 - vblank in atomic commit fix
 - dpu modesetting fixes
 - fencing fix
 
 etnaviv:
 - scheduler interaction fix
 - gpu init regression fix
 
 exynos:
 - Just drop __iommu annotation to fix sparse warning.
 
 omap:
 - locking state fix.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJfSGXpAAoJEAx081l5xIa+bs4QAJ6dQb0Llv9TyUBZL/FTTbc2
 iv8PDzA55aoBn7qI00mkUN9M9elfAV75dfLcn9h1fJg/EN3UZXkPCxFAcsscN+gm
 0TXTU9SmgqeDDK2RFxyvSGbuJbfuoOiXMbERdd+sYupUh7FowckDFVrOvbRcEe//
 PX3klUuQRSRxsgShrruJjaLdpqA+saZ12fhoE3eagsvlaFFAuVz8GY2zj533yaw9
 zjgDTkOWiO4Lw2/X10dmjEoxa5Nn26ECF4y+iFih7Uw2e+tu+ZVaL+/PcVPlJk5a
 NdlDAgU1gS8U9c0lSbrLNGGwBRXj1899FIRMS55uLwIBSmdZlOkh/wEOmnC+c1uK
 kbrUfYlU6dXLjzUOTd2d8GQx3F9OTFxOXoZjshMYlryf2RsVl4kImBlpdAC3TT7p
 B/Qk4xbU3uOuDzMgF76b1wT5XiFoHKcPrxNcf5L1tkqULdmYioB78hs4uQij5Bh0
 p6ynfR8rb19J4m+ctI84HqfG6ZbloBgGDZLzIe37lHsvG6xKG7/VjcclBV9BHBXs
 mgG0h+CeogY14a9JWeZ2dQFH8wT77QT5G0/ODQo1r9+OXM1i10DGCZyihrNJf2Nl
 //4uIDlgq695Lxd+h7FMuupWLpvAvnooDaUvnnNfVGsQVFsEhagl3R+TCGaFULHJ
 hi1vfCSZEBV+tCeiKSRU
 =ZmIT
 -----END PGP SIGNATURE-----

Merge tag 'drm-fixes-2020-08-28' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "As expected a bit of an rc3 uptick, amdgpu and msm are the main ones,
  one msm patch was from the merge window, but had dependencies and we
  dropped it until the other tree had landed. Otherwise it's a couple of
  fixes for core, and etnaviv, and single i915, exynos, omap fixes.

  I'm still tracking the Sandybridge gpu relocations issue, if we don't
  see much movement I might just queue up the reverts. I'll talk to
  Daniel next week once he's back from holidays.

  core:
   - Take modeset bkl for legacy drivers

  dp_mst:
   - Allow null crtc in dp_mst

  i915:
   - Fix command parser desc matching with masks

  amdgpu:
   - Misc display fixes
   - Backlight fixes
   - MPO fix for DCN1
   - Fixes for Sienna Cichlid
   - Fixes for Navy Flounder
   - Vega SW CTF fixes
   - SMU fix for Raven
   - Fix a possible overflow in INFO ioctl
   - Gfx10 clockgating fix

  msm:
   - opp/bw scaling patch followup
   - frequency restoring fux
   - vblank in atomic commit fix
   - dpu modesetting fixes
   - fencing fix

  etnaviv:
   - scheduler interaction fix
   - gpu init regression fix

  exynos:
   - Just drop __iommu annotation to fix sparse warning

  omap:
   - locking state fix"

* tag 'drm-fixes-2020-08-28' of git://anongit.freedesktop.org/drm/drm: (41 commits)
  drm/amd/display: Fix memleak in amdgpu_dm_mode_config_init
  drm/amdgpu: disable runtime pm for navy_flounder
  drm/amd/display: Retry AUX write when fail occurs
  drm/amdgpu: Fix buffer overflow in INFO ioctl
  drm/amd/powerplay: Fix hardmins not being sent to SMU for RV
  drm/amdgpu: use MODE1 reset for navy_flounder by default
  drm/amd/pm: correct the thermal alert temperature limit settings
  drm/amdgpu: add asd fw check before loading asd
  drm/amd/display: Keep current gain when ABM disable immediately
  drm/amd/display: Fix passive dongle mistaken as active dongle in EDID emulation
  drm/amd/display: Revert HDCP disable sequence change
  drm/amd/display: Send DISPLAY_OFF after power down on boot
  drm/amdgpu/gfx10: refine mgcg setting
  drm/amd/pm: correct Vega20 swctf limit setting
  drm/amd/pm: correct Vega12 swctf limit setting
  drm/amd/pm: correct Vega10 swctf limit setting
  drm/amd/pm: set VCN pg per instances
  drm/amd/pm: enable run_btc callback for sienna_cichlid
  drivers: gpu: amd: Initialize amdgpu_dm_backlight_caps object to 0 in amdgpu_dm_update_backlight_caps
  drm/amd/display: Reject overlay plane configurations in multi-display scenarios
  ...
This commit is contained in:
Linus Torvalds 2020-08-28 09:46:48 -07:00
commit 5ec06b5c0d
43 changed files with 309 additions and 168 deletions

View file

@ -179,6 +179,7 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
case CHIP_VEGA20:
case CHIP_ARCTURUS:
case CHIP_SIENNA_CICHLID:
case CHIP_NAVY_FLOUNDER:
/* enable runpm if runpm=1 */
if (amdgpu_runtime_pm > 0)
adev->runpm = true;
@ -678,8 +679,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
* in the bitfields */
if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
se_num = 0xffffffff;
else if (se_num >= AMDGPU_GFX_MAX_SE)
return -EINVAL;
if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
sh_num = 0xffffffff;
else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
return -EINVAL;
if (info->read_mmr_reg.count > 128)
return -EINVAL;

View file

@ -522,8 +522,7 @@ static int psp_asd_load(struct psp_context *psp)
* add workaround to bypass it for sriov now.
* TODO: add version check to make it common
*/
if (amdgpu_sriov_vf(psp->adev) ||
(psp->adev->asic_type == CHIP_NAVY_FLOUNDER))
if (amdgpu_sriov_vf(psp->adev) || !psp->asd_fw)
return 0;
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);

View file

@ -7263,10 +7263,8 @@ static void gfx_v10_0_update_medium_grain_clock_gating(struct amdgpu_device *ade
def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK |
RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK |
RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK);
/* only for Vega10 & Raven1 */
data |= RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK;
RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK |
RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK);
if (def != data)
WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data);

View file

@ -364,6 +364,7 @@ nv_asic_reset_method(struct amdgpu_device *adev)
switch (adev->asic_type) {
case CHIP_SIENNA_CICHLID:
case CHIP_NAVY_FLOUNDER:
return AMD_RESET_METHOD_MODE1;
default:
if (smu_baco_is_support(smu))

View file

@ -2834,12 +2834,18 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
&dm_atomic_state_funcs);
r = amdgpu_display_modeset_create_props(adev);
if (r)
if (r) {
dc_release_state(state->context);
kfree(state);
return r;
}
r = amdgpu_dm_audio_init(adev);
if (r)
if (r) {
dc_release_state(state->context);
kfree(state);
return r;
}
return 0;
}
@ -2856,6 +2862,8 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
#if defined(CONFIG_ACPI)
struct amdgpu_dm_backlight_caps caps;
memset(&caps, 0, sizeof(caps));
if (dm->backlight_caps.caps_valid)
return;
@ -2894,51 +2902,50 @@ static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness)
return rc ? 0 : 1;
}
static u32 convert_brightness(const struct amdgpu_dm_backlight_caps *caps,
const uint32_t user_brightness)
static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
unsigned *min, unsigned *max)
{
u32 min, max, conversion_pace;
u32 brightness = user_brightness;
if (!caps)
goto out;
return 0;
if (!caps->aux_support) {
max = caps->max_input_signal;
min = caps->min_input_signal;
/*
* The brightness input is in the range 0-255
* It needs to be rescaled to be between the
* requested min and max input signal
* It also needs to be scaled up by 0x101 to
* match the DC interface which has a range of
* 0 to 0xffff
*/
conversion_pace = 0x101;
brightness =
user_brightness
* conversion_pace
* (max - min)
/ AMDGPU_MAX_BL_LEVEL
+ min * conversion_pace;
if (caps->aux_support) {
// Firmware limits are in nits, DC API wants millinits.
*max = 1000 * caps->aux_max_input_signal;
*min = 1000 * caps->aux_min_input_signal;
} else {
/* TODO
* We are doing a linear interpolation here, which is OK but
* does not provide the optimal result. We probably want
* something close to the Perceptual Quantizer (PQ) curve.
*/
max = caps->aux_max_input_signal;
min = caps->aux_min_input_signal;
brightness = (AMDGPU_MAX_BL_LEVEL - user_brightness) * min
+ user_brightness * max;
// Multiple the value by 1000 since we use millinits
brightness *= 1000;
brightness = DIV_ROUND_CLOSEST(brightness, AMDGPU_MAX_BL_LEVEL);
// Firmware limits are 8-bit, PWM control is 16-bit.
*max = 0x101 * caps->max_input_signal;
*min = 0x101 * caps->min_input_signal;
}
return 1;
}
out:
return brightness;
static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
uint32_t brightness)
{
unsigned min, max;
if (!get_brightness_range(caps, &min, &max))
return brightness;
// Rescale 0..255 to min..max
return min + DIV_ROUND_CLOSEST((max - min) * brightness,
AMDGPU_MAX_BL_LEVEL);
}
static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
uint32_t brightness)
{
unsigned min, max;
if (!get_brightness_range(caps, &min, &max))
return brightness;
if (brightness < min)
return 0;
// Rescale min..max to 0..255
return DIV_ROUND_CLOSEST(AMDGPU_MAX_BL_LEVEL * (brightness - min),
max - min);
}
static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
@ -2954,7 +2961,7 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
link = (struct dc_link *)dm->backlight_link;
brightness = convert_brightness(&caps, bd->props.brightness);
brightness = convert_brightness_from_user(&caps, bd->props.brightness);
// Change brightness based on AUX property
if (caps.aux_support)
return set_backlight_via_aux(link, brightness);
@ -2971,7 +2978,7 @@ static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
if (ret == DC_ERROR_UNEXPECTED)
return bd->props.brightness;
return ret;
return convert_brightness_to_user(&dm->backlight_caps, ret);
}
static const struct backlight_ops amdgpu_dm_backlight_ops = {

View file

@ -67,7 +67,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
&operation_result);
if (payload.write)
if (payload.write && result >= 0)
result = msg->size;
if (result < 0)

View file

@ -94,6 +94,15 @@ int rn_get_active_display_cnt_wa(
return display_count;
}
void rn_set_low_power_state(struct clk_mgr *clk_mgr_base)
{
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER);
/* update power state */
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
}
void rn_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
@ -516,6 +525,7 @@ static struct clk_mgr_funcs dcn21_funcs = {
.init_clocks = rn_init_clocks,
.enable_pme_wa = rn_enable_pme_wa,
.are_clock_states_equal = rn_are_clock_states_equal,
.set_low_power_state = rn_set_low_power_state,
.notify_wm_ranges = rn_notify_wm_ranges,
.notify_link_rate_change = rn_notify_link_rate_change,
};

View file

@ -763,6 +763,7 @@ static bool detect_dp(struct dc_link *link,
sink_caps->signal = dp_passive_dongle_detection(link->ddc,
sink_caps,
audio_support);
link->dpcd_caps.dongle_type = sink_caps->dongle_type;
}
return true;
@ -3286,10 +3287,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
core_link_set_avmute(pipe_ctx, true);
}
dc->hwss.blank_stream(pipe_ctx);
#if defined(CONFIG_DRM_AMD_DC_HDCP)
update_psp_stream_config(pipe_ctx, true);
#endif
dc->hwss.blank_stream(pipe_ctx);
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);

View file

@ -4409,9 +4409,9 @@ bool dc_link_get_backlight_level_nits(struct dc_link *link,
link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
return false;
if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
dpcd_backlight_get.raw,
sizeof(union dpcd_source_backlight_get)))
sizeof(union dpcd_source_backlight_get)) != DC_OK)
return false;
*backlight_millinits_avg =
@ -4450,9 +4450,9 @@ bool dc_link_read_default_bl_aux(struct dc_link *link, uint32_t *backlight_milli
link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
return false;
if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
(uint8_t *) backlight_millinits,
sizeof(uint32_t)))
sizeof(uint32_t)) != DC_OK)
return false;
return true;

View file

@ -233,7 +233,7 @@ struct dc_stream_state {
union stream_update_flags update_flags;
};
#define ABM_LEVEL_IMMEDIATE_DISABLE 0xFFFFFFFF
#define ABM_LEVEL_IMMEDIATE_DISABLE 255
struct dc_stream_update {
struct dc_stream_state *stream;

View file

@ -1450,33 +1450,42 @@ void dcn10_init_hw(struct dc *dc)
void dcn10_power_down_on_boot(struct dc *dc)
{
int i = 0;
struct dc_link *edp_link;
if (dc->config.power_down_display_on_boot) {
struct dc_link *edp_link = get_edp_link(dc);
if (!dc->config.power_down_display_on_boot)
return;
if (edp_link &&
edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwseq->funcs.edp_backlight_control &&
dc->hwss.power_down &&
dc->hwss.edp_power_control) {
dc->hwseq->funcs.edp_backlight_control(edp_link, false);
dc->hwss.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
} else {
for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i];
if (link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
dc->hwss.power_down) {
dc->hwss.power_down(dc);
break;
}
edp_link = get_edp_link(dc);
if (edp_link &&
edp_link->link_enc->funcs->is_dig_enabled &&
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
dc->hwseq->funcs.edp_backlight_control &&
dc->hwss.power_down &&
dc->hwss.edp_power_control) {
dc->hwseq->funcs.edp_backlight_control(edp_link, false);
dc->hwss.power_down(dc);
dc->hwss.edp_power_control(edp_link, false);
} else {
for (i = 0; i < dc->link_count; i++) {
struct dc_link *link = dc->links[i];
if (link->link_enc->funcs->is_dig_enabled &&
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
dc->hwss.power_down) {
dc->hwss.power_down(dc);
break;
}
}
}
/*
* Call update_clocks with empty context
* to send DISPLAY_OFF
* Otherwise DISPLAY_OFF may not be asserted
*/
if (dc->clk_mgr->funcs->set_low_power_state)
dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
}
void dcn10_reset_hw_ctx_wrap(

View file

@ -1213,6 +1213,7 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
bool video_large = false;
bool desktop_large = false;
bool dcc_disabled = false;
bool mpo_enabled = false;
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
@ -1221,6 +1222,9 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
if (context->stream_status[i].plane_count > 2)
return DC_FAIL_UNSUPPORTED_1;
if (context->stream_status[i].plane_count > 1)
mpo_enabled = true;
for (j = 0; j < context->stream_status[i].plane_count; j++) {
struct dc_plane_state *plane =
context->stream_status[i].plane_states[j];
@ -1244,6 +1248,10 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
}
}
/* Disable MPO in multi-display configurations. */
if (context->stream_count > 1 && mpo_enabled)
return DC_FAIL_UNSUPPORTED_1;
/*
* Workaround: On DCN10 there is UMC issue that causes underflow when
* playing 4k video on 4k desktop with video downscaled and single channel

View file

@ -230,6 +230,8 @@ struct clk_mgr_funcs {
int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);
void (*set_low_power_state)(struct clk_mgr *clk_mgr);
void (*init_clocks)(struct clk_mgr *clk_mgr);
void (*enable_pme_wa) (struct clk_mgr *clk_mgr);

View file

@ -204,8 +204,7 @@ static int smu10_set_min_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clo
{
struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
if (smu10_data->need_min_deep_sleep_dcefclk &&
smu10_data->deep_sleep_dcefclk != clock) {
if (clock && smu10_data->deep_sleep_dcefclk != clock) {
smu10_data->deep_sleep_dcefclk = clock;
smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetMinDeepSleepDcefclk,
@ -219,8 +218,7 @@ static int smu10_set_hard_min_dcefclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t c
{
struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
if (smu10_data->dcf_actual_hard_min_freq &&
smu10_data->dcf_actual_hard_min_freq != clock) {
if (clock && smu10_data->dcf_actual_hard_min_freq != clock) {
smu10_data->dcf_actual_hard_min_freq = clock;
smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetHardMinDcefclkByFreq,
@ -234,8 +232,7 @@ static int smu10_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cloc
{
struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
if (smu10_data->f_actual_hard_min_freq &&
smu10_data->f_actual_hard_min_freq != clock) {
if (clock && smu10_data->f_actual_hard_min_freq != clock) {
smu10_data->f_actual_hard_min_freq = clock;
smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetHardMinFclkByFreq,

View file

@ -363,17 +363,19 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range)
{
struct phm_ppt_v2_information *pp_table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_tdp_table *tdp_table = pp_table_info->tdp_table;
struct amdgpu_device *adev = hwmgr->adev;
int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP;
int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP;
uint32_t val;
if (low < range->min)
low = range->min;
if (high > range->max)
high = range->max;
/* compare them in unit celsius degree */
if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
if (high > tdp_table->usSoftwareShutdownTemp)
high = tdp_table->usSoftwareShutdownTemp;
if (low > high)
return -EINVAL;
@ -382,8 +384,8 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) &
(~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) &
(~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK);

View file

@ -170,17 +170,18 @@ int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr)
static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range)
{
struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable;
struct amdgpu_device *adev = hwmgr->adev;
int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP;
int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP;
uint32_t val;
if (low < range->min)
low = range->min;
if (high > range->max)
high = range->max;
/* compare them in unit celsius degree */
if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
if (high > pptable_information->us_software_shutdown_temp)
high = pptable_information->us_software_shutdown_temp;
if (low > high)
return -EINVAL;
@ -189,8 +190,8 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);

View file

@ -240,17 +240,18 @@ int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr)
static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range)
{
struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable;
struct amdgpu_device *adev = hwmgr->adev;
int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP;
int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP;
uint32_t val;
if (low < range->min)
low = range->min;
if (high > range->max)
high = range->max;
/* compare them in unit celsius degree */
if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
if (high > pptable_information->us_software_shutdown_temp)
high = pptable_information->us_software_shutdown_temp;
if (low > high)
return -EINVAL;
@ -259,8 +260,8 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);

View file

@ -95,6 +95,7 @@ static struct cmn2asic_msg_mapping sienna_cichlid_message_map[SMU_MSG_MAX_COUNT]
MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0),
MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0),
MSG_MAP(RunDcBtc, PPSMC_MSG_RunDcBtc, 0),
MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0),
MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0),
MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0),
@ -775,7 +776,7 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
if (ret)
return ret;
if (adev->asic_type == CHIP_SIENNA_CICHLID) {
if (adev->vcn.num_vcn_inst > 1) {
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn,
0x10000, NULL);
if (ret)
@ -787,7 +788,7 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
if (ret)
return ret;
if (adev->asic_type == CHIP_SIENNA_CICHLID) {
if (adev->vcn.num_vcn_inst > 1) {
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn,
0x10000, NULL);
if (ret)
@ -1732,6 +1733,11 @@ static int sienna_cichlid_get_dpm_ultimate_freq(struct smu_context *smu,
return ret;
}
static int sienna_cichlid_run_btc(struct smu_context *smu)
{
return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
}
static bool sienna_cichlid_is_baco_supported(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@ -2719,6 +2725,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
.mode1_reset = smu_v11_0_mode1_reset,
.get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq,
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
.run_btc = sienna_cichlid_run_btc,
.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
.set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
};

View file

@ -34,6 +34,7 @@
#include <drm/drm_bridge.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_self_refresh_helper.h>
@ -3106,7 +3107,7 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
if (ret)
DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
DRM_MODESET_LOCK_ALL_END(ctx, ret);
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
}
EXPORT_SYMBOL(drm_atomic_helper_shutdown);
@ -3246,7 +3247,7 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
}
unlock:
DRM_MODESET_LOCK_ALL_END(ctx, err);
DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
if (err)
return ERR_PTR(err);
@ -3327,7 +3328,7 @@ int drm_atomic_helper_resume(struct drm_device *dev,
err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
DRM_MODESET_LOCK_ALL_END(ctx, err);
DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
drm_atomic_state_put(state);
return err;

View file

@ -294,7 +294,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
crtc->gamma_size, &ctx);
out:
DRM_MODESET_LOCK_ALL_END(ctx, ret);
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
return ret;
}

View file

@ -588,7 +588,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
return -EACCES;
mutex_lock(&crtc->dev->mode_config.mutex);
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
@ -756,8 +755,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
fb = NULL;
mode = NULL;
DRM_MODESET_LOCK_ALL_END(ctx, ret);
mutex_unlock(&crtc->dev->mode_config.mutex);
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
return ret;
}

View file

@ -5040,8 +5040,8 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
crtc = conn_state->crtc;
if (WARN_ON(!crtc))
return -EINVAL;
if (!crtc)
continue;
if (!drm_dp_mst_dsc_aux_for_port(pos->port))
continue;

View file

@ -428,7 +428,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
out_unref:
drm_mode_object_put(obj);
out:
DRM_MODESET_LOCK_ALL_END(ctx, ret);
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
return ret;
}
@ -470,7 +470,7 @@ static int set_property_legacy(struct drm_mode_object *obj,
break;
}
drm_property_change_valid_put(prop, ref);
DRM_MODESET_LOCK_ALL_END(ctx, ret);
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
return ret;
}

View file

@ -792,7 +792,7 @@ static int setplane_internal(struct drm_plane *plane,
crtc_x, crtc_y, crtc_w, crtc_h,
src_x, src_y, src_w, src_h, &ctx);
DRM_MODESET_LOCK_ALL_END(ctx, ret);
DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret);
return ret;
}

View file

@ -337,9 +337,16 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL);
gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV);
gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
gpu->identity.customer_id = gpu_read(gpu, VIVS_HI_CHIP_CUSTOMER_ID);
gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
/*
* Reading these two registers on GC600 rev 0x19 result in a
* unhandled fault: external abort on non-linefetch
*/
if (!etnaviv_is_model_rev(gpu, GC600, 0x19)) {
gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
}
/*
* !!!! HACK ALERT !!!!

View file

@ -89,12 +89,15 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
u32 dma_addr;
int change;
/* block scheduler */
drm_sched_stop(&gpu->sched, sched_job);
/*
* If the GPU managed to complete this jobs fence, the timout is
* spurious. Bail out.
*/
if (dma_fence_is_signaled(submit->out_fence))
return;
goto out_no_timeout;
/*
* If the GPU is still making forward progress on the front-end (which
@ -105,12 +108,9 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
change = dma_addr - gpu->hangcheck_dma_addr;
if (change < 0 || change > 16) {
gpu->hangcheck_dma_addr = dma_addr;
return;
goto out_no_timeout;
}
/* block scheduler */
drm_sched_stop(&gpu->sched, sched_job);
if(sched_job)
drm_sched_increase_karma(sched_job);
@ -120,6 +120,7 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
drm_sched_resubmit_jobs(&gpu->sched);
out_no_timeout:
/* restart scheduler after GPU is usable again */
drm_sched_start(&gpu->sched, true);
}

View file

@ -92,7 +92,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
offset = fbi->var.xoffset * fb->format->cpp[0];
offset += fbi->var.yoffset * fb->pitches[0];
fbi->screen_base = exynos_gem->kvaddr + offset;
fbi->screen_buffer = exynos_gem->kvaddr + offset;
fbi->screen_size = size;
fbi->fix.smem_len = size;

View file

@ -40,7 +40,7 @@ struct exynos_drm_gem {
unsigned int flags;
unsigned long size;
void *cookie;
void __iomem *kvaddr;
void *kvaddr;
dma_addr_t dma_addr;
unsigned long dma_attrs;
struct sg_table *sgt;

View file

@ -1204,6 +1204,12 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
return dst;
}
static inline bool cmd_desc_is(const struct drm_i915_cmd_descriptor * const desc,
const u32 cmd)
{
return desc->cmd.value == (cmd & desc->cmd.mask);
}
static bool check_cmd(const struct intel_engine_cs *engine,
const struct drm_i915_cmd_descriptor *desc,
const u32 *cmd, u32 length)
@ -1242,19 +1248,19 @@ static bool check_cmd(const struct intel_engine_cs *engine,
* allowed mask/value pair given in the whitelist entry.
*/
if (reg->mask) {
if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
if (cmd_desc_is(desc, MI_LOAD_REGISTER_MEM)) {
DRM_DEBUG("CMD: Rejected LRM to masked register 0x%08X\n",
reg_addr);
return false;
}
if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
if (cmd_desc_is(desc, MI_LOAD_REGISTER_REG)) {
DRM_DEBUG("CMD: Rejected LRR to masked register 0x%08X\n",
reg_addr);
return false;
}
if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
if (cmd_desc_is(desc, MI_LOAD_REGISTER_IMM(1)) &&
(offset + 2 > length ||
(cmd[offset + 1] & reg->mask) != reg->value)) {
DRM_DEBUG("CMD: Rejected LRI to masked register 0x%08X\n",
@ -1478,7 +1484,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
break;
}
if (desc->cmd.value == MI_BATCH_BUFFER_START) {
if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) {
ret = check_bbstart(cmd, offset, length, batch_length,
batch_addr, shadow_addr,
jump_whitelist);

View file

@ -133,7 +133,7 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
if (!gmu->legacy) {
a6xx_hfi_set_freq(gmu, perf_index);
icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
dev_pm_opp_set_bw(&gpu->pdev->dev, opp);
pm_runtime_put(gmu->dev);
return;
}
@ -157,11 +157,7 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
if (ret)
dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
/*
* Eventually we will want to scale the path vote with the frequency but
* for now leave it at max so that the performance is nominal.
*/
icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
dev_pm_opp_set_bw(&gpu->pdev->dev, opp);
pm_runtime_put(gmu->dev);
}
@ -204,6 +200,16 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
{
int ret;
u32 val;
u32 mask, reset_val;
val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8);
if (val <= 0x20010004) {
mask = 0xffffffff;
reset_val = 0xbabeface;
} else {
mask = 0x1ff;
reset_val = 0x100;
}
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
@ -215,7 +221,7 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
val == 0xbabeface, 100, 10000);
(val & mask) == reset_val, 100, 10000);
if (ret)
DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
@ -845,10 +851,24 @@ static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
if (IS_ERR_OR_NULL(gpu_opp))
return;
gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */
a6xx_gmu_set_freq(gpu, gpu_opp);
dev_pm_opp_put(gpu_opp);
}
static void a6xx_gmu_set_initial_bw(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
{
struct dev_pm_opp *gpu_opp;
unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index];
gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);
if (IS_ERR_OR_NULL(gpu_opp))
return;
dev_pm_opp_set_bw(&gpu->pdev->dev, gpu_opp);
dev_pm_opp_put(gpu_opp);
}
int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
{
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
@ -882,7 +902,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
}
/* Set the bus quota to a reasonable value for boot */
icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072));
a6xx_gmu_set_initial_bw(gpu, gmu);
/* Enable the GMU interrupt */
gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0);
@ -1051,7 +1071,7 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
a6xx_gmu_shutdown(gmu);
/* Remove the bus vote */
icc_set_bw(gpu->icc_path, 0, 0);
dev_pm_opp_set_bw(&gpu->pdev->dev, NULL);
/*
* Make sure the GX domain is off before turning off the GMU (CX)

View file

@ -938,7 +938,8 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
}
a6xx_get_debugbus(gpu, a6xx_state);
if (snapshot_debugbus)
a6xx_get_debugbus(gpu, a6xx_state);
return &a6xx_state->base;
}

View file

@ -372,7 +372,7 @@ static const struct a6xx_indexed_registers {
u32 data;
u32 count;
} a6xx_indexed_reglist[] = {
{ "CP_SEQ_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
{ "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
REG_A6XX_CP_SQE_STAT_DATA, 0x33 },
{ "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
REG_A6XX_CP_DRAW_STATE_DATA, 0x100 },

View file

@ -14,6 +14,10 @@ bool hang_debug = false;
MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)");
module_param_named(hang_debug, hang_debug, bool, 0600);
bool snapshot_debugbus = false;
MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)");
module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
static const struct adreno_info gpulist[] = {
{
.rev = ADRENO_REV(2, 0, 0, 0),

View file

@ -396,7 +396,7 @@ int adreno_hw_init(struct msm_gpu *gpu)
ring->next = ring->start;
/* reset completed fence seqno: */
ring->memptrs->fence = ring->seqno;
ring->memptrs->fence = ring->fctx->completed_fence;
ring->memptrs->rptr = 0;
}

View file

@ -21,6 +21,8 @@
#define REG_SKIP ~0
#define REG_ADRENO_SKIP(_offset) [_offset] = REG_SKIP
extern bool snapshot_debugbus;
/**
* adreno_regs: List of registers that are used in across all
* 3D devices. Each device type has different offset value for the same

View file

@ -827,7 +827,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
{
struct dpu_crtc *dpu_crtc;
struct drm_encoder *encoder;
bool request_bandwidth;
bool request_bandwidth = false;
if (!crtc) {
DPU_ERROR("invalid crtc\n");

View file

@ -599,7 +599,10 @@ static int dpu_encoder_virt_atomic_check(
dpu_kms = to_dpu_kms(priv->kms);
mode = &crtc_state->mode;
adj_mode = &crtc_state->adjusted_mode;
global_state = dpu_kms_get_existing_global_state(dpu_kms);
global_state = dpu_kms_get_global_state(crtc_state->state);
if (IS_ERR(global_state))
return PTR_ERR(global_state);
trace_dpu_enc_atomic_check(DRMID(drm_enc));
/* perform atomic check on the first physical encoder (master) */
@ -625,12 +628,15 @@ static int dpu_encoder_virt_atomic_check(
/* Reserve dynamic resources now. */
if (!ret) {
/*
* Avoid reserving resources when mode set is pending. Topology
* info may not be available to complete reservation.
* Release and Allocate resources on every modeset
* Dont allocate when active is false.
*/
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
drm_enc, crtc_state, topology);
dpu_rm_release(global_state, drm_enc);
if (!crtc_state->active_changed || crtc_state->active)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
drm_enc, crtc_state, topology);
}
}
@ -1181,7 +1187,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
struct dpu_encoder_virt *dpu_enc = NULL;
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms;
struct dpu_global_state *global_state;
int i = 0;
if (!drm_enc) {
@ -1200,7 +1205,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
priv = drm_enc->dev->dev_private;
dpu_kms = to_dpu_kms(priv->kms);
global_state = dpu_kms_get_existing_global_state(dpu_kms);
trace_dpu_enc_disable(DRMID(drm_enc));
@ -1230,8 +1234,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
dpu_rm_release(global_state, drm_enc);
mutex_unlock(&dpu_enc->enc_lock);
}

View file

@ -866,9 +866,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
crtc_state = drm_atomic_get_new_crtc_state(state->state,
state->crtc);
min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxdwnscale);
min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
ret = drm_atomic_helper_check_plane_state(state, crtc_state, min_scale,
pdpu->pipe_sblk->maxupscale << 16,
pdpu->pipe_sblk->maxdwnscale << 16,
true, true);
if (ret) {
DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);

View file

@ -27,6 +27,34 @@ int msm_atomic_prepare_fb(struct drm_plane *plane,
return msm_framebuffer_prepare(new_state->fb, kms->aspace);
}
/*
* Helpers to control vblanks while we flush.. basically just to ensure
* that vblank accounting is switched on, so we get valid seqn/timestamp
* on pageflip events (if requested)
*/
static void vblank_get(struct msm_kms *kms, unsigned crtc_mask)
{
struct drm_crtc *crtc;
for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
if (!crtc->state->active)
continue;
drm_crtc_vblank_get(crtc);
}
}
static void vblank_put(struct msm_kms *kms, unsigned crtc_mask)
{
struct drm_crtc *crtc;
for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
if (!crtc->state->active)
continue;
drm_crtc_vblank_put(crtc);
}
}
static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
{
unsigned crtc_mask = BIT(crtc_idx);
@ -44,6 +72,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
kms->funcs->enable_commit(kms);
vblank_get(kms, crtc_mask);
/*
* Flush hardware updates:
*/
@ -58,6 +88,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
kms->funcs->wait_flush(kms, crtc_mask);
trace_msm_atomic_wait_flush_finish(crtc_mask);
vblank_put(kms, crtc_mask);
mutex_lock(&kms->commit_lock);
kms->funcs->complete_commit(kms, crtc_mask);
mutex_unlock(&kms->commit_lock);
@ -221,6 +253,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
*/
kms->pending_crtc_mask &= ~crtc_mask;
vblank_get(kms, crtc_mask);
/*
* Flush hardware updates:
*/
@ -235,6 +269,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->funcs->wait_flush(kms, crtc_mask);
trace_msm_atomic_wait_flush_finish(crtc_mask);
vblank_put(kms, crtc_mask);
mutex_lock(&kms->commit_lock);
kms->funcs->complete_commit(kms, crtc_mask);
mutex_unlock(&kms->commit_lock);

View file

@ -1320,6 +1320,13 @@ static int msm_pdev_remove(struct platform_device *pdev)
return 0;
}
static void msm_pdev_shutdown(struct platform_device *pdev)
{
struct drm_device *drm = platform_get_drvdata(pdev);
drm_atomic_helper_shutdown(drm);
}
static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
@ -1332,6 +1339,7 @@ MODULE_DEVICE_TABLE(of, dt_match);
static struct platform_driver msm_platform_driver = {
.probe = msm_pdev_probe,
.remove = msm_pdev_remove,
.shutdown = msm_pdev_shutdown,
.driver = {
.name = "msm",
.of_match_table = dt_match,

View file

@ -27,7 +27,8 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
ring->id = id;
ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ,
MSM_BO_WC, gpu->aspace, &ring->bo, &ring->iova);
MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace, &ring->bo,
&ring->iova);
if (IS_ERR(ring->start)) {
ret = PTR_ERR(ring->start);

View file

@ -451,11 +451,12 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
if (omap_state->manually_updated)
return;
spin_lock_irq(&crtc->dev->event_lock);
drm_crtc_vblank_on(crtc);
ret = drm_crtc_vblank_get(crtc);
WARN_ON(ret != 0);
spin_lock_irq(&crtc->dev->event_lock);
omap_crtc_arm_event(crtc);
spin_unlock_irq(&crtc->dev->event_lock);
}

View file

@ -164,6 +164,8 @@ int drm_modeset_lock_all_ctx(struct drm_device *dev,
* is 0, so no error checking is necessary
*/
#define DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, flags, ret) \
if (!drm_drv_uses_atomic_modeset(dev)) \
mutex_lock(&dev->mode_config.mutex); \
drm_modeset_acquire_init(&ctx, flags); \
modeset_lock_retry: \
ret = drm_modeset_lock_all_ctx(dev, &ctx); \
@ -172,6 +174,7 @@ modeset_lock_retry: \
/**
* DRM_MODESET_LOCK_ALL_END - Helper to release and cleanup modeset locks
* @dev: drm device
* @ctx: local modeset acquire context, will be dereferenced
* @ret: local ret/err/etc variable to track error status
*
@ -188,7 +191,7 @@ modeset_lock_retry: \
* to that failure. In both of these cases the code between BEGIN/END will not
* be run, so the failure will reflect the inability to grab the locks.
*/
#define DRM_MODESET_LOCK_ALL_END(ctx, ret) \
#define DRM_MODESET_LOCK_ALL_END(dev, ctx, ret) \
modeset_lock_fail: \
if (ret == -EDEADLK) { \
ret = drm_modeset_backoff(&ctx); \
@ -196,6 +199,8 @@ modeset_lock_fail: \
goto modeset_lock_retry; \
} \
drm_modeset_drop_locks(&ctx); \
drm_modeset_acquire_fini(&ctx);
drm_modeset_acquire_fini(&ctx); \
if (!drm_drv_uses_atomic_modeset(dev)) \
mutex_unlock(&dev->mode_config.mutex);
#endif /* DRM_MODESET_LOCK_H_ */