diff options
Diffstat (limited to 'drivers/gpu')
129 files changed, 1057 insertions, 468 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c index 7e59e473a190..cdea1338c8dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c @@ -152,7 +152,7 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,  		dev_warn(adev->dev,  			 "Invalid sdma engine id (%d), using engine id 0\n",  			 engine_id); -		/* fall through */ +		fallthrough;  	case 0:  		sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA0, 0,  				mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 0047da06041f..414548064648 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -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; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 7fe564275457..06757681b2ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -178,7 +178,7 @@ static int psp_sw_init(void *handle)  		return ret;  	} -	if (adev->asic_type == CHIP_NAVI10) { +	if (adev->asic_type == CHIP_NAVI10 || adev->asic_type == CHIP_SIENNA_CICHLID) {  		ret= psp_sysfs_init(adev);  		if (ret) {  			return ret; @@ -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); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 65997ffaed45..037a187aa42f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -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); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 33f1c4a46ebe..88f63d7ea371 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -3250,7 +3250,7 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev)  		dev_warn(adev->dev,  			 "Unknown chip type (%d) in function gfx_v8_0_tiling_mode_table_init() falling through to CHIP_CARRIZO\n",  			 adev->asic_type); -		/* fall through */ +		fallthrough;  	case CHIP_CARRIZO:  		modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 6e4f3ff4810f..b67ba38a195f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1297,7 +1297,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)  	case CHIP_VEGA10:  		if (amdgpu_sriov_vf(adev))  			break; -		/* fall through */ +		fallthrough;  	case CHIP_VEGA20:  		soc15_program_register_sequence(adev,  						golden_settings_mmhub_1_0_0, diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index da8024c2826e..ca11253e787c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -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)) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index e16874f30d5d..6c5d9612abcb 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -58,7 +58,7 @@ MODULE_FIRMWARE("amdgpu/arcturus_ta.bin");  MODULE_FIRMWARE("amdgpu/sienna_cichlid_sos.bin");  MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin");  MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin"); -MODULE_FIRMWARE("amdgpu/navy_flounder_asd.bin"); +MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin");  /* address block */  #define smnMP1_FIRMWARE_FLAGS		0x3010024 diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index ea914b256ebd..b5986d19dc08 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -6196,7 +6196,7 @@ static void si_request_link_speed_change_before_state_change(struct amdgpu_devic  			si_pi->force_pcie_gen = AMDGPU_PCIE_GEN2;  			if (current_link_speed == AMDGPU_PCIE_GEN2)  				break; -			/* fall through */ +			fallthrough;  		case AMDGPU_PCIE_GEN2:  			if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)  				break; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index e0e60b0d0669..0f4508b4903e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1216,6 +1216,8 @@ static int stop_cpsch(struct device_queue_manager *dqm)  	dqm->sched_running = false;  	dqm_unlock(dqm); +	pm_release_ib(&dqm->packets); +  	kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);  	pm_uninit(&dqm->packets, hanging); @@ -1326,7 +1328,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,  	if (q->properties.is_active) {  		increment_queue_count(dqm, q->properties.type); -		retval = execute_queues_cpsch(dqm, +		execute_queues_cpsch(dqm,  				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);  	} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index df9338257ae0..4ba8b54a2695 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -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; +} + +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; -out: -	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 = { @@ -5271,19 +5278,6 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc)  {  } -static bool does_crtc_have_active_cursor(struct drm_crtc_state *new_crtc_state) -{ -	struct drm_device *dev = new_crtc_state->crtc->dev; -	struct drm_plane *plane; - -	drm_for_each_plane_mask(plane, dev, new_crtc_state->plane_mask) { -		if (plane->type == DRM_PLANE_TYPE_CURSOR) -			return true; -	} - -	return false; -} -  static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state)  {  	struct drm_atomic_state *state = new_crtc_state->state; @@ -5347,19 +5341,20 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,  		return ret;  	} -	/* In some use cases, like reset, no stream is attached */ -	if (!dm_crtc_state->stream) -		return 0; -  	/* -	 * We want at least one hardware plane enabled to use -	 * the stream with a cursor enabled. +	 * We require the primary plane to be enabled whenever the CRTC is, otherwise +	 * drm_mode_cursor_universal may end up trying to enable the cursor plane while all other +	 * planes are disabled, which is not supported by the hardware. And there is legacy +	 * userspace which stops using the HW cursor altogether in response to the resulting EINVAL.  	 */ -	if (state->enable && state->active && -	    does_crtc_have_active_cursor(state) && -	    dm_crtc_state->active_planes == 0) +	if (state->enable && +	    !(state->plane_mask & drm_plane_mask(crtc->primary)))  		return -EINVAL; +	/* In some use cases, like reset, no stream is attached */ +	if (!dm_crtc_state->stream) +		return 0; +  	if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)  		return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index e85b58f0f416..336aaa09be46 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -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) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index c664404a75d4..543afa34d87a 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -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,  }; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 117d8aaf2a9b..437d1a7a16fe 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -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); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 9bc03f26efda..b2be6ad5101d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -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; diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 633442bc7ef2..d9888f316da6 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -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; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index a643927e272b..fa643ec5a876 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -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 (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; -				} +	if (!dc->config.power_down_display_on_boot) +		return; + +	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( diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 17d5cb422025..8939541ad7af 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -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 diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 9140b3fc767a..f31f48dd0da2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -409,8 +409,8 @@ static struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {  			},  		},  	.num_states = 5, -	.sr_exit_time_us = 8.6, -	.sr_enter_plus_exit_time_us = 10.9, +	.sr_exit_time_us = 11.6, +	.sr_enter_plus_exit_time_us = 13.9,  	.urgent_latency_us = 4.0,  	.urgent_latency_pixel_data_only_us = 4.0,  	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 5994d2a33c40..947d6106f341 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -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); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h index d3192b9d0c3d..47f8ee2832ff 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_log.h @@ -27,7 +27,7 @@  #define MOD_HDCP_LOG_H_  #ifdef CONFIG_DRM_AMD_DC_HDCP -#define HDCP_LOG_ERR(hdcp, ...) DRM_WARN(__VA_ARGS__) +#define HDCP_LOG_ERR(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__)  #define HDCP_LOG_VER(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__)  #define HDCP_LOG_FSM(hdcp, ...) DRM_DEBUG_KMS(__VA_ARGS__)  #define HDCP_LOG_TOP(hdcp, ...) pr_debug("[HDCP_TOP]:"__VA_ARGS__) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index fb1161dd7ea8..3a367a5968ae 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -88,7 +88,7 @@ enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,  	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;  	if (!psp->dtm_context.dtm_initialized) { -		DRM_ERROR("Failed to add display topology, DTM TA is not initialized."); +		DRM_INFO("Failed to add display topology, DTM TA is not initialized.");  		display->state = MOD_HDCP_DISPLAY_INACTIVE;  		return MOD_HDCP_STATUS_FAILURE;  	} diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 0826625573dc..63f945f9f331 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -1126,7 +1126,7 @@ static int smu_disable_dpms(struct smu_context *smu)  	 */  	if (smu->uploading_custom_pp_table &&  	    (adev->asic_type >= CHIP_NAVI10) && -	    (adev->asic_type <= CHIP_NAVI12)) +	    (adev->asic_type <= CHIP_NAVY_FLOUNDER))  		return 0;  	/* @@ -1211,7 +1211,9 @@ static int smu_hw_fini(void *handle)  int smu_reset(struct smu_context *smu)  {  	struct amdgpu_device *adev = smu->adev; -	int ret = 0; +	int ret; + +	amdgpu_gfx_off_ctrl(smu->adev, false);  	ret = smu_hw_fini(adev);  	if (ret) @@ -1222,8 +1224,12 @@ int smu_reset(struct smu_context *smu)  		return ret;  	ret = smu_late_init(adev); +	if (ret) +		return ret; -	return ret; +	amdgpu_gfx_off_ctrl(smu->adev, true); + +	return 0;  }  static int smu_suspend(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c index fb962b9ceffb..9582b38162f0 100644 --- a/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c @@ -1840,10 +1840,14 @@ static bool arcturus_is_dpm_running(struct smu_context *smu)  {  	int ret = 0;  	uint32_t feature_mask[2]; -	unsigned long feature_enabled; +	uint64_t feature_enabled; +  	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); -	feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | -			   ((uint64_t)feature_mask[1] << 32)); +	if (ret) +		return false; + +	feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; +  	return !!(feature_enabled & SMC_DPM_FEATURE);  } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index c9cfe90a2947..9ee8cf8267c8 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -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, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index ffe05b7cc1f0..4a3b64aa21ce 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3581,7 +3581,8 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,  	case AMDGPU_PP_SENSOR_GPU_POWER:  		return smu7_get_gpu_power(hwmgr, (uint32_t *)value);  	case AMDGPU_PP_SENSOR_VDDGFX: -		if ((data->vr_config & 0xff) == 0x2) +		if ((data->vr_config & VRCONF_VDDGFX_MASK) == +		    (VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT))  			val_vid = PHM_READ_INDIRECT_FIELD(hwmgr->device,  					CGS_IND_REG__SMC, PWR_SVI2_STATUS, PLANE2_VID);  		else diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c index 468bdd6f6697..952cd3d7240e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c @@ -363,17 +363,29 @@ 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; + +	/* +	 * As a common sense, usSoftwareShutdownTemp should be bigger +	 * than ThotspotLimit. For any invalid usSoftwareShutdownTemp, +	 * we will just use the max possible setting VEGA10_THERMAL_MAXIMUM_ALERT_TEMP +	 * to avoid false alarms. +	 */ +	if ((tdp_table->usSoftwareShutdownTemp > +	     range->hotspot_crit_max / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)) { +		if (high > tdp_table->usSoftwareShutdownTemp) +			high = tdp_table->usSoftwareShutdownTemp; +	}  	if (low > high)  		return -EINVAL; @@ -382,8 +394,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); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c index c15b9756025d..7ace439dcde7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c @@ -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); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c index 7add2f60f49c..364162ddaa9c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c @@ -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); diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index 9f62af9abd23..3d5eae956a23 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -1331,10 +1331,14 @@ static bool navi10_is_dpm_running(struct smu_context *smu)  {  	int ret = 0;  	uint32_t feature_mask[2]; -	unsigned long feature_enabled; +	uint64_t feature_enabled; +  	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); -	feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | -			   ((uint64_t)feature_mask[1] << 32)); +	if (ret) +		return false; + +	feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; +  	return !!(feature_enabled & SMC_DPM_FEATURE);  } diff --git a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c index 3865dbed5f93..61f4ddae262d 100644 --- a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c @@ -68,7 +68,8 @@  	FEATURE_MASK(FEATURE_DPM_LINK_BIT)       | \  	FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT)     | \  	FEATURE_MASK(FEATURE_DPM_FCLK_BIT)	 | \ -	FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) +	FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)	 | \ +	FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT))  #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15 @@ -95,6 +96,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), @@ -228,6 +230,7 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu,  	*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT)  				| FEATURE_MASK(FEATURE_DPM_FCLK_BIT) +				| FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)  				| FEATURE_MASK(FEATURE_DS_SOCCLK_BIT)  				| FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT)  				| FEATURE_MASK(FEATURE_DS_FCLK_BIT) @@ -775,7 +778,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 +790,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) @@ -1146,10 +1149,14 @@ static bool sienna_cichlid_is_dpm_running(struct smu_context *smu)  {  	int ret = 0;  	uint32_t feature_mask[2]; -	unsigned long feature_enabled; +	uint64_t feature_enabled; +  	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); -	feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | -			   ((uint64_t)feature_mask[1] << 32)); +	if (ret) +		return false; + +	feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; +  	return !!(feature_enabled & SMC_DPM_FEATURE);  } @@ -1732,6 +1739,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 +2731,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,  }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c index c18169aa59ce..e4d1f3d66ef4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c @@ -37,6 +37,7 @@  #include "cgs_common.h"  #include "atombios.h"  #include "pppcielanes.h" +#include "smu7_smumgr.h"  #include "smu/smu_7_0_1_d.h"  #include "smu/smu_7_0_1_sh_mask.h" @@ -2948,6 +2949,7 @@ const struct pp_smumgr_func ci_smu_funcs = {  	.request_smu_load_specific_fw = NULL,  	.send_msg_to_smc = ci_send_msg_to_smc,  	.send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, +	.get_argument = smu7_get_argument,  	.download_pptable_settings = NULL,  	.upload_pptable_settings = NULL,  	.get_offsetof = ci_get_offsetof, diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index ca570b135478..e9de542f9b7c 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -532,7 +532,7 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,  		malidp_hw_write(hwdev, lower_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_LOW);  		malidp_hw_write(hwdev, upper_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_HIGH);  		malidp_hw_write(hwdev, pitches[1], base + MALIDP_MW_P2_STRIDE); -		/* fall through */ +		fallthrough;  	case 1:  		malidp_hw_write(hwdev, lower_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_LOW);  		malidp_hw_write(hwdev, upper_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_HIGH); @@ -869,7 +869,7 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,  		malidp_hw_write(hwdev, lower_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_LOW);  		malidp_hw_write(hwdev, upper_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_HIGH);  		malidp_hw_write(hwdev, pitches[1], base + MALIDP_MW_P2_STRIDE); -		/* fall through */ +		fallthrough;  	case 1:  		malidp_hw_write(hwdev, lower_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_LOW);  		malidp_hw_write(hwdev, upper_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_HIGH); @@ -1324,7 +1324,7 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)  			break;  		case MW_RESTART:  			drm_writeback_signal_completion(&malidp->mw_connector, 0); -			/* fall through - to a new start */ +			fallthrough;	/* to a new start */  		case MW_START:  			/* writeback started, need to emulate one-shot mode */  			hw->disable_memwrite(hwdev); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index dd12b55d57a2..6a9fba051d13 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -238,7 +238,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)  					ast->dp501_fw_addr = NULL;  				}  			} -			/* fallthrough */ +			fallthrough;  		case 0x0c:  			ast->tx_chip_type = AST_TX_DP501;  		} diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index ce94f797d090..66b67402f1ac 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -409,7 +409,6 @@ static bool nwl_dsi_read_packet(struct nwl_dsi *dsi, u32 status)  		switch (data_type) {  		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: -			fallthrough;  		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:  			if (xfer->msg->rx_len > 1) {  				/* read second byte */ @@ -418,7 +417,6 @@ static bool nwl_dsi_read_packet(struct nwl_dsi *dsi, u32 status)  			}  			fallthrough;  		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: -			fallthrough;  		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:  			if (xfer->msg->rx_len > 0) {  				/* read first byte */ diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index d7e65c869415..9fef6413741d 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -61,10 +61,10 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,  	switch (hparms->channels) {  	case 7 ... 8:  		conf0 |= HDMI_AUD_CONF0_I2S_EN3; -		/* Fall-thru */ +		fallthrough;  	case 5 ... 6:  		conf0 |= HDMI_AUD_CONF0_I2S_EN2; -		/* Fall-thru */ +		fallthrough;  	case 3 ... 4:  		conf0 |= HDMI_AUD_CONF0_I2S_EN1;  		/* Fall-thru */ diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 86b9f0f87a14..5b6e19ecbc84 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -604,13 +604,13 @@ static void ti_sn_bridge_read_valid_rates(struct ti_sn_bridge *pdata,  		DRM_DEV_ERROR(pdata->dev,  			      "Unexpected max rate (%#x); assuming 5.4 GHz\n",  			      (int)dpcd_val); -		/* fall through */ +		fallthrough;  	case DP_LINK_BW_5_4:  		rate_valid[7] = 1; -		/* fall through */ +		fallthrough;  	case DP_LINK_BW_2_7:  		rate_valid[4] = 1; -		/* fall through */ +		fallthrough;  	case DP_LINK_BW_1_62:  		rate_valid[1] = 1;  		break; diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index a0735fbc144b..7a01d0918861 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -537,7 +537,7 @@ int drm_legacy_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)  	switch (map->type) {  	case _DRM_REGISTERS:  		iounmap(map->handle); -		/* FALLTHROUGH */ +		fallthrough;  	case _DRM_FRAME_BUFFER:  		arch_phys_wc_del(map->mtrr);  		break; diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index a3c82e726057..092c8c985911 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -492,7 +492,7 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],  		case DP_DS_16BPC:  			return 16;  		} -		/* fall through */ +		fallthrough;  	default:  		return 0;  	} diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 14b6f7638728..501b4fe55a3d 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1930,7 +1930,7 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,  	default:  		WARN(1, "Invalid aspect ratio (0%x) on mode\n",  		     in->picture_aspect_ratio); -		/* fall through */ +		fallthrough;  	case HDMI_PICTURE_ASPECT_NONE:  		out->flags |= DRM_MODE_FLAG_PIC_AR_NONE;  		break; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index d5a4cd85a0f6..c6404b8d067f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -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 !!!! diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index 4e3e95dce6d8..cd46c882269c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -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);  } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 7a6f6df5e954..b38e9b592b8a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -987,10 +987,10 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,  	switch (length) {  	case 3:  		reg |= payload[2] << 16; -		/* Fall through */ +		fallthrough;  	case 2:  		reg |= payload[1] << 8; -		/* Fall through */ +		fallthrough;  	case 1:  		reg |= payload[0];  		exynos_dsi_write(dsi, DSIM_PAYLOAD_REG, reg); @@ -1038,7 +1038,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,  				payload[1] = reg >> 16;  				++xfer->rx_done;  			} -			/* Fall through */ +			fallthrough;  		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:  		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:  			payload[0] = reg >> 8; @@ -1082,10 +1082,10 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,  		switch (length) {  		case 3:  			payload[2] = (reg >> 16) & 0xff; -			/* Fall through */ +			fallthrough;  		case 2:  			payload[1] = (reg >> 8) & 0xff; -			/* Fall through */ +			fallthrough;  		case 1:  			payload[0] = reg & 0xff;  		} diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 56a2b47e1af7..5147f5929be7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -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; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 7445748288da..74e926abeff0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -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; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c index 86fac677fe69..3c6d9f3913d5 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c @@ -101,19 +101,19 @@ static void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane,  		break;  	case DRM_FORMAT_ARGB8888:  		alpha = DCU_LAYER_AB_WHOLE_FRAME; -		/* fall-through */ +		fallthrough;  	case DRM_FORMAT_XRGB8888:  		bpp = FSL_DCU_ARGB8888;  		break;  	case DRM_FORMAT_ARGB4444:  		alpha = DCU_LAYER_AB_WHOLE_FRAME; -		/* fall-through */ +		fallthrough;  	case DRM_FORMAT_XRGB4444:  		bpp = FSL_DCU_ARGB4444;  		break;  	case DRM_FORMAT_ARGB1555:  		alpha = DCU_LAYER_AB_WHOLE_FRAME; -		/* fall-through */ +		fallthrough;  	case DRM_FORMAT_XRGB1555:  		bpp = FSL_DCU_ARGB1555;  		break; diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 8c55f5bee9ab..f4053dd6bde9 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -712,7 +712,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,  			switch (intel_dsi->pixel_format) {  			default:  				MISSING_CASE(intel_dsi->pixel_format); -				/* fallthrough */ +				fallthrough;  			case MIPI_DSI_FMT_RGB565:  				tmp |= PIX_FMT_RGB565;  				break; @@ -739,7 +739,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,  			switch (intel_dsi->video_mode_format) {  			default:  				MISSING_CASE(intel_dsi->video_mode_format); -				/* fallthrough */ +				fallthrough;  			case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS:  				tmp |= VIDEO_MODE_SYNC_EVENT;  				break; @@ -792,7 +792,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,  		switch (pipe) {  		default:  			MISSING_CASE(pipe); -			/* fallthrough */ +			fallthrough;  		case PIPE_A:  			tmp |= TRANS_DDI_EDP_INPUT_A_ON;  			break; diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index c53c85d38fa5..a0a41ec5c341 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -905,7 +905,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)  			drm_dbg_kms(&dev_priv->drm,  				    "VBT tp1 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",  				    psr_table->tp1_wakeup_time); -			/* fallthrough */ +			fallthrough;  		case 2:  			dev_priv->vbt.psr.tp1_wakeup_time_us = 2500;  			break; @@ -925,7 +925,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)  			drm_dbg_kms(&dev_priv->drm,  				    "VBT tp2_tp3 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",  				    psr_table->tp2_tp3_wakeup_time); -			/* fallthrough */ +			fallthrough;  		case 2:  			dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = 2500;  		break; @@ -1775,7 +1775,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv,  		switch (child->hdmi_max_data_rate) {  		default:  			MISSING_CASE(child->hdmi_max_data_rate); -			/* fall through */ +			fallthrough;  		case HDMI_MAX_DATA_RATE_PLATFORM:  			max_tmds_clock = 0;  			break; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index bb91dace304a..91a8161e7c05 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -326,7 +326,7 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv,  	default:  		drm_err(&dev_priv->drm,  			"Unknown pnv display core clock 0x%04x\n", gcfgc); -		/* fall through */ +		fallthrough;  	case GC_DISPLAY_CLOCK_133_MHZ_PNV:  		cdclk_config->cdclk = 133333;  		break; @@ -766,7 +766,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,  	switch (cdclk) {  	default:  		MISSING_CASE(cdclk); -		/* fall through */ +		fallthrough;  	case 337500:  		val |= LCPLL_CLK_FREQ_337_5_BDW;  		break; @@ -1042,7 +1042,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,  		drm_WARN_ON(&dev_priv->drm,  			    cdclk != dev_priv->cdclk.hw.bypass);  		drm_WARN_ON(&dev_priv->drm, vco != 0); -		/* fall through */ +		fallthrough;  	case 308571:  	case 337500:  		freq_select = CDCLK_FREQ_337_308; @@ -1333,7 +1333,7 @@ static void icl_readout_refclk(struct drm_i915_private *dev_priv,  	switch (dssm) {  	default:  		MISSING_CASE(dssm); -		/* fall through */ +		fallthrough;  	case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:  		cdclk_config->ref = 24000;  		break; @@ -1561,7 +1561,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,  		drm_WARN_ON(&dev_priv->drm,  			    cdclk != dev_priv->cdclk.hw.bypass);  		drm_WARN_ON(&dev_priv->drm, vco != 0); -		/* fall through */ +		fallthrough;  	case 2:  		divider = BXT_CDCLK_CD2X_DIV_SEL_1;  		break; diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index eccaa79cb4a9..157d8c8c605a 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -52,7 +52,7 @@ cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)  	switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {  	default:  		MISSING_CASE(val); -		/* fall through */ +		fallthrough;  	case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:  		procmon = &cnl_procmon_values[PROCMON_0_85V_DOT_0];  		break; @@ -258,7 +258,7 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)  static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,  				       enum phy phy)  { -	bool ret; +	bool ret = true;  	u32 expected_val = 0;  	if (!icl_combo_phy_enabled(dev_priv, phy)) @@ -276,7 +276,7 @@ static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,  				     DCC_MODE_SELECT_CONTINUOSLY);  	} -	ret = cnl_verify_procmon_ref_values(dev_priv, phy); +	ret &= cnl_verify_procmon_ref_values(dev_priv, phy);  	if (phy_is_master(dev_priv, phy)) {  		ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy), @@ -320,7 +320,7 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,  			break;  		default:  			MISSING_CASE(lane_count); -			/* fall-through */ +			fallthrough;  		case 4:  			lane_mask = PWR_UP_ALL_LANES;  			break; @@ -337,7 +337,7 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,  			break;  		default:  			MISSING_CASE(lane_count); -			/* fall-through */ +			fallthrough;  		case 4:  			lane_mask = PWR_UP_ALL_LANES;  			break; diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 2c484b55bcdf..a49ff3a1a63c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1888,7 +1888,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,  		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {  		default:  			MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK); -			/* fallthrough */ +			fallthrough;  		case TRANS_DDI_EDP_INPUT_A_ON:  		case TRANS_DDI_EDP_INPUT_A_ONOFF:  			*pipe_mask = BIT(PIPE_A); @@ -4268,7 +4268,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,  			pipe_config->hdmi_scrambling = true;  		if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)  			pipe_config->hdmi_high_tmds_clock_ratio = true; -		/* fall through */ +		fallthrough;  	case TRANS_DDI_MODE_SELECT_DVI:  		pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);  		pipe_config->lane_count = 4; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b2ec3a5141cc..b18c5ac2934d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2029,12 +2029,12 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)  	case I915_FORMAT_MOD_Y_TILED_CCS:  		if (is_ccs_plane(fb, color_plane))  			return 128; -		/* fall through */ +		fallthrough;  	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:  	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:  		if (is_ccs_plane(fb, color_plane))  			return 64; -		/* fall through */ +		fallthrough;  	case I915_FORMAT_MOD_Y_TILED:  		if (IS_GEN(dev_priv, 2) || HAS_128_BYTE_Y_TILING(dev_priv))  			return 128; @@ -2043,7 +2043,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)  	case I915_FORMAT_MOD_Yf_TILED_CCS:  		if (is_ccs_plane(fb, color_plane))  			return 128; -		/* fall through */ +		fallthrough;  	case I915_FORMAT_MOD_Yf_TILED:  		switch (cpp) {  		case 1: @@ -2185,7 +2185,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,  	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:  		if (is_semiplanar_uv_plane(fb, color_plane))  			return intel_tile_row_size(fb, color_plane); -		/* Fall-through */ +		fallthrough;  	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:  		return 16 * 1024;  	case I915_FORMAT_MOD_Y_TILED_CCS: @@ -2194,7 +2194,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,  		if (INTEL_GEN(dev_priv) >= 12 &&  		    is_semiplanar_uv_plane(fb, color_plane))  			return intel_tile_row_size(fb, color_plane); -		/* Fall-through */ +		fallthrough;  	case I915_FORMAT_MOD_Yf_TILED:  		return 1 * 1024 * 1024;  	default: @@ -6211,7 +6211,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,  	case DRM_FORMAT_ARGB16161616F:  		if (INTEL_GEN(dev_priv) >= 11)  			break; -		/* fall through */ +		fallthrough;  	default:  		drm_dbg_kms(&dev_priv->drm,  			    "[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", @@ -10896,7 +10896,7 @@ static void hsw_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,  		break;  	default:  		MISSING_CASE(ddi_pll_sel); -		/* fall through */ +		fallthrough;  	case PORT_CLK_SEL_NONE:  		return;  	} @@ -10956,10 +10956,10 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,  			drm_WARN(dev, 1,  				 "unknown pipe linked to transcoder %s\n",  				 transcoder_name(panel_transcoder)); -			/* fall through */ +			fallthrough;  		case TRANS_DDI_EDP_INPUT_A_ONOFF:  			force_thru = true; -			/* fall through */ +			fallthrough;  		case TRANS_DDI_EDP_INPUT_A_ON:  			trans_pipe = PIPE_A;  			break; @@ -13183,7 +13183,7 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)  		case INTEL_OUTPUT_DDI:  			if (drm_WARN_ON(dev, !HAS_DDI(to_i915(dev))))  				break; -			/* else, fall through */ +			fallthrough;  		case INTEL_OUTPUT_DP:  		case INTEL_OUTPUT_HDMI:  		case INTEL_OUTPUT_EDP: @@ -14956,12 +14956,6 @@ static int intel_atomic_check(struct drm_device *dev,  	if (dev_priv->wm.distrust_bios_wm)  		any_ms = true; -	if (any_ms) { -		ret = intel_modeset_checks(state); -		if (ret) -			goto fail; -	} -  	intel_fbc_choose_crtc(dev_priv, state);  	ret = calc_watermark_data(state);  	if (ret) @@ -14976,6 +14970,10 @@ static int intel_atomic_check(struct drm_device *dev,  		goto fail;  	if (any_ms) { +		ret = intel_modeset_checks(state); +		if (ret) +			goto fail; +  		ret = intel_modeset_calc_cdclk(state);  		if (ret)  			return ret; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index aeb6ee395cce..afa7a378b31d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -892,7 +892,7 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,  			refclk = dev_priv->dpll.ref_clks.nssc;  			break;  		} -		/* fall through */ +		fallthrough;  	case WRPLL_REF_PCH_SSC:  		/*  		 * We could calculate spread here, but our checking @@ -2977,7 +2977,7 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,  		switch (dev_priv->dpll.ref_clks.nssc) {  		default:  			MISSING_CASE(dev_priv->dpll.ref_clks.nssc); -			/* fall-through */ +			fallthrough;  		case 19200:  			*pll_params = tgl_tbt_pll_19_2MHz_values;  			break; @@ -2992,7 +2992,7 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,  		switch (dev_priv->dpll.ref_clks.nssc) {  		default:  			MISSING_CASE(dev_priv->dpll.ref_clks.nssc); -			/* fall-through */ +			fallthrough;  		case 19200:  		case 38400:  			*pll_params = icl_tbt_pll_19_2MHz_values; @@ -3120,7 +3120,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,  			switch (div1) {  			default:  				MISSING_CASE(div1); -				/* fall through */ +				fallthrough;  			case 2:  				hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;  				break; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 89a4d294822d..1a0d49af2a08 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -336,8 +336,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,  		/* Fill up the empty slots in sha_text and write it out */  		sha_empty = sizeof(sha_text) - sha_leftovers; -		for (j = 0; j < sha_empty; j++) -			sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); +		for (j = 0; j < sha_empty; j++) { +			u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8); +			sha_text |= ksv[j] << off; +		}  		ret = intel_write_sha_text(dev_priv, sha_text);  		if (ret < 0) @@ -435,7 +437,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,  		/* Write 32 bits of text */  		intel_de_write(dev_priv, HDCP_REP_CTL,  			       rep_ctl | HDCP_SHA1_TEXT_32); -		sha_text |= bstatus[0] << 24 | bstatus[1] << 16; +		sha_text |= bstatus[0] << 8 | bstatus[1];  		ret = intel_write_sha_text(dev_priv, sha_text);  		if (ret < 0)  			return ret; @@ -450,17 +452,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,  				return ret;  			sha_idx += sizeof(sha_text);  		} + +		/* +		 * Terminate the SHA-1 stream by hand. For the other leftover +		 * cases this is appended by the hardware. +		 */ +		intel_de_write(dev_priv, HDCP_REP_CTL, +			       rep_ctl | HDCP_SHA1_TEXT_32); +		sha_text = DRM_HDCP_SHA1_TERMINATOR << 24; +		ret = intel_write_sha_text(dev_priv, sha_text); +		if (ret < 0) +			return ret; +		sha_idx += sizeof(sha_text);  	} else if (sha_leftovers == 3) { -		/* Write 32 bits of text */ +		/* Write 32 bits of text (filled from LSB) */  		intel_de_write(dev_priv, HDCP_REP_CTL,  			       rep_ctl | HDCP_SHA1_TEXT_32); -		sha_text |= bstatus[0] << 24; +		sha_text |= bstatus[0];  		ret = intel_write_sha_text(dev_priv, sha_text);  		if (ret < 0)  			return ret;  		sha_idx += sizeof(sha_text); -		/* Write 8 bits of text, 24 bits of M0 */ +		/* Write 8 bits of text (filled from LSB), 24 bits of M0 */  		intel_de_write(dev_priv, HDCP_REP_CTL,  			       rep_ctl | HDCP_SHA1_TEXT_8);  		ret = intel_write_sha_text(dev_priv, bstatus[1]); @@ -781,6 +795,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)  	struct intel_hdcp *hdcp = &connector->hdcp;  	enum port port = dig_port->base.port;  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder; +	u32 repeater_ctl;  	int ret;  	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n", @@ -796,6 +811,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector)  		return -ETIMEDOUT;  	} +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, +						   port); +	intel_de_write(dev_priv, HDCP_REP_CTL, +		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl); +  	ret = hdcp->shim->toggle_signalling(dig_port, false);  	if (ret) {  		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n"); diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index bbde3b12c311..4072d7062efd 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -229,7 +229,7 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state,  	case DRM_MODE_SCALE_NONE:  		WARN_ON(adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w);  		WARN_ON(adjusted_mode->crtc_vdisplay != crtc_state->pipe_src_h); -		/* fall through */ +		fallthrough;  	case DRM_MODE_SCALE_FULLSCREEN:  		x = y = 0;  		width = adjusted_mode->crtc_hdisplay; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 2da4388e1540..5e9fb349c829 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1531,7 +1531,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,  	default:  		drm_WARN(&dev_priv->drm, 1,  			 "unknown pixel multiplier specified\n"); -		/* fall through */ +		fallthrough;  	case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;  	case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;  	case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; @@ -2549,19 +2549,19 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)  	switch (sdvo->controlled_output) {  	case SDVO_OUTPUT_LVDS1:  		mask |= SDVO_OUTPUT_LVDS1; -		/* fall through */ +		fallthrough;  	case SDVO_OUTPUT_LVDS0:  		mask |= SDVO_OUTPUT_LVDS0; -		/* fall through */ +		fallthrough;  	case SDVO_OUTPUT_TMDS1:  		mask |= SDVO_OUTPUT_TMDS1; -		/* fall through */ +		fallthrough;  	case SDVO_OUTPUT_TMDS0:  		mask |= SDVO_OUTPUT_TMDS0; -		/* fall through */ +		fallthrough;  	case SDVO_OUTPUT_RGB1:  		mask |= SDVO_OUTPUT_RGB1; -		/* fall through */ +		fallthrough;  	case SDVO_OUTPUT_RGB0:  		mask |= SDVO_OUTPUT_RGB0;  		break; diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index d03860fef2d7..c89f5f7ccb06 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -2147,7 +2147,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,  		case DRM_FORMAT_RGB565:  			if (INTEL_GEN(dev_priv) >= 11)  				break; -			/* fall through */ +			fallthrough;  		case DRM_FORMAT_C8:  		case DRM_FORMAT_XRGB16161616F:  		case DRM_FORMAT_XBGR16161616F: @@ -2702,7 +2702,7 @@ static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,  		if (modifier == DRM_FORMAT_MOD_LINEAR ||  		    modifier == I915_FORMAT_MOD_X_TILED)  			return true; -		/* fall through */ +		fallthrough;  	default:  		return false;  	} @@ -2733,7 +2733,7 @@ static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,  		if (modifier == DRM_FORMAT_MOD_LINEAR ||  		    modifier == I915_FORMAT_MOD_X_TILED)  			return true; -		/* fall through */ +		fallthrough;  	default:  		return false;  	} @@ -2768,7 +2768,7 @@ static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,  		if (modifier == DRM_FORMAT_MOD_LINEAR ||  		    modifier == I915_FORMAT_MOD_X_TILED)  			return true; -		/* fall through */ +		fallthrough;  	default:  		return false;  	} @@ -2801,7 +2801,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,  	case DRM_FORMAT_ABGR8888:  		if (is_ccs_modifier(modifier))  			return true; -		/* fall through */ +		fallthrough;  	case DRM_FORMAT_RGB565:  	case DRM_FORMAT_XRGB2101010:  	case DRM_FORMAT_XBGR2101010: @@ -2819,7 +2819,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,  	case DRM_FORMAT_XVYU2101010:  		if (modifier == I915_FORMAT_MOD_Yf_TILED)  			return true; -		/* fall through */ +		fallthrough;  	case DRM_FORMAT_C8:  	case DRM_FORMAT_XBGR16161616F:  	case DRM_FORMAT_ABGR16161616F: @@ -2834,7 +2834,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,  		    modifier == I915_FORMAT_MOD_X_TILED ||  		    modifier == I915_FORMAT_MOD_Y_TILED)  			return true; -		/* fall through */ +		fallthrough;  	default:  		return false;  	} @@ -2860,7 +2860,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,  	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:  		if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))  			return false; -		/* fall through */ +		fallthrough;  	case DRM_FORMAT_MOD_LINEAR:  	case I915_FORMAT_MOD_X_TILED:  	case I915_FORMAT_MOD_Y_TILED: @@ -2877,7 +2877,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,  	case DRM_FORMAT_ABGR8888:  		if (is_ccs_modifier(modifier))  			return true; -		/* fall through */ +		fallthrough;  	case DRM_FORMAT_YUYV:  	case DRM_FORMAT_YVYU:  	case DRM_FORMAT_UYVY: @@ -2889,7 +2889,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,  	case DRM_FORMAT_P016:  		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)  			return true; -		/* fall through */ +		fallthrough;  	case DRM_FORMAT_RGB565:  	case DRM_FORMAT_XRGB2101010:  	case DRM_FORMAT_XBGR2101010: @@ -2910,7 +2910,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,  		    modifier == I915_FORMAT_MOD_X_TILED ||  		    modifier == I915_FORMAT_MOD_Y_TILED)  			return true; -		/* fall through */ +		fallthrough;  	default:  		return false;  	} diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 5b5dc86a5737..8f67aef18b2d 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -159,7 +159,7 @@ int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port)  	switch (lane_mask) {  	default:  		MISSING_CASE(lane_mask); -		/* fall-through */ +		fallthrough;  	case 0x1:  	case 0x2:  	case 0x4: diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index d0bdb6d447ed..ef755dd5e68f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -439,29 +439,36 @@ static bool __cancel_engine(struct intel_engine_cs *engine)  	return __reset_engine(engine);  } -static struct intel_engine_cs *__active_engine(struct i915_request *rq) +static bool +__active_engine(struct i915_request *rq, struct intel_engine_cs **active)  {  	struct intel_engine_cs *engine, *locked; +	bool ret = false;  	/*  	 * Serialise with __i915_request_submit() so that it sees  	 * is-banned?, or we know the request is already inflight. +	 * +	 * Note that rq->engine is unstable, and so we double +	 * check that we have acquired the lock on the final engine.  	 */  	locked = READ_ONCE(rq->engine);  	spin_lock_irq(&locked->active.lock);  	while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {  		spin_unlock(&locked->active.lock); -		spin_lock(&engine->active.lock);  		locked = engine; +		spin_lock(&locked->active.lock);  	} -	engine = NULL; -	if (i915_request_is_active(rq) && rq->fence.error != -EIO) -		engine = rq->engine; +	if (!i915_request_completed(rq)) { +		if (i915_request_is_active(rq) && rq->fence.error != -EIO) +			*active = locked; +		ret = true; +	}  	spin_unlock_irq(&locked->active.lock); -	return engine; +	return ret;  }  static struct intel_engine_cs *active_engine(struct intel_context *ce) @@ -472,17 +479,16 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)  	if (!ce->timeline)  		return NULL; -	mutex_lock(&ce->timeline->mutex); -	list_for_each_entry_reverse(rq, &ce->timeline->requests, link) { -		if (i915_request_completed(rq)) -			break; +	rcu_read_lock(); +	list_for_each_entry_rcu(rq, &ce->timeline->requests, link) { +		if (i915_request_is_active(rq) && i915_request_completed(rq)) +			continue;  		/* Check with the backend if the request is inflight */ -		engine = __active_engine(rq); -		if (engine) +		if (__active_engine(rq, &engine))  			break;  	} -	mutex_unlock(&ce->timeline->mutex); +	rcu_read_unlock();  	return engine;  } @@ -713,6 +719,7 @@ __create_context(struct drm_i915_private *i915)  	ctx->i915 = i915;  	ctx->sched.priority = I915_USER_PRIORITY(I915_PRIORITY_NORMAL);  	mutex_init(&ctx->mutex); +	INIT_LIST_HEAD(&ctx->link);  	spin_lock_init(&ctx->stale.lock);  	INIT_LIST_HEAD(&ctx->stale.engines); @@ -740,10 +747,6 @@ __create_context(struct drm_i915_private *i915)  	for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)  		ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES; -	spin_lock(&i915->gem.contexts.lock); -	list_add_tail(&ctx->link, &i915->gem.contexts.list); -	spin_unlock(&i915->gem.contexts.lock); -  	return ctx;  err_free: @@ -931,6 +934,7 @@ static int gem_context_register(struct i915_gem_context *ctx,  				struct drm_i915_file_private *fpriv,  				u32 *id)  { +	struct drm_i915_private *i915 = ctx->i915;  	struct i915_address_space *vm;  	int ret; @@ -949,8 +953,16 @@ static int gem_context_register(struct i915_gem_context *ctx,  	/* And finally expose ourselves to userspace via the idr */  	ret = xa_alloc(&fpriv->context_xa, id, ctx, xa_limit_32b, GFP_KERNEL);  	if (ret) -		put_pid(fetch_and_zero(&ctx->pid)); +		goto err_pid; + +	spin_lock(&i915->gem.contexts.lock); +	list_add_tail(&ctx->link, &i915->gem.contexts.list); +	spin_unlock(&i915->gem.contexts.lock); + +	return 0; +err_pid: +	put_pid(fetch_and_zero(&ctx->pid));  	return ret;  } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 6b4ec66cb558..446e76e95c38 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -45,6 +45,13 @@ struct eb_vma_array {  	struct eb_vma vma[];  }; +enum { +	FORCE_CPU_RELOC = 1, +	FORCE_GTT_RELOC, +	FORCE_GPU_RELOC, +#define DBG_FORCE_RELOC 0 /* choose one of the above! */ +}; +  #define __EXEC_OBJECT_HAS_PIN		BIT(31)  #define __EXEC_OBJECT_HAS_FENCE		BIT(30)  #define __EXEC_OBJECT_NEEDS_MAP		BIT(29) @@ -253,6 +260,8 @@ struct i915_execbuffer {  	 */  	struct reloc_cache {  		struct drm_mm_node node; /** temporary GTT binding */ +		unsigned long vaddr; /** Current kmap address */ +		unsigned long page; /** Currently mapped page index */  		unsigned int gen; /** Cached value of INTEL_GEN */  		bool use_64bit_reloc : 1;  		bool has_llc : 1; @@ -596,6 +605,23 @@ eb_add_vma(struct i915_execbuffer *eb,  	}  } +static inline int use_cpu_reloc(const struct reloc_cache *cache, +				const struct drm_i915_gem_object *obj) +{ +	if (!i915_gem_object_has_struct_page(obj)) +		return false; + +	if (DBG_FORCE_RELOC == FORCE_CPU_RELOC) +		return true; + +	if (DBG_FORCE_RELOC == FORCE_GTT_RELOC) +		return false; + +	return (cache->has_llc || +		obj->cache_dirty || +		obj->cache_level != I915_CACHE_NONE); +} +  static int eb_reserve_vma(const struct i915_execbuffer *eb,  			  struct eb_vma *ev,  			  u64 pin_flags) @@ -926,6 +952,8 @@ relocation_target(const struct drm_i915_gem_relocation_entry *reloc,  static void reloc_cache_init(struct reloc_cache *cache,  			     struct drm_i915_private *i915)  { +	cache->page = -1; +	cache->vaddr = 0;  	/* Must be a variable in the struct to allow GCC to unroll. */  	cache->gen = INTEL_GEN(i915);  	cache->has_llc = HAS_LLC(i915); @@ -937,6 +965,25 @@ static void reloc_cache_init(struct reloc_cache *cache,  	cache->target = NULL;  } +static inline void *unmask_page(unsigned long p) +{ +	return (void *)(uintptr_t)(p & PAGE_MASK); +} + +static inline unsigned int unmask_flags(unsigned long p) +{ +	return p & ~PAGE_MASK; +} + +#define KMAP 0x4 /* after CLFLUSH_FLAGS */ + +static inline struct i915_ggtt *cache_to_ggtt(struct reloc_cache *cache) +{ +	struct drm_i915_private *i915 = +		container_of(cache, struct i915_execbuffer, reloc_cache)->i915; +	return &i915->ggtt; +} +  #define RELOC_TAIL 4  static int reloc_gpu_chain(struct reloc_cache *cache) @@ -1049,6 +1096,181 @@ static int reloc_gpu_flush(struct reloc_cache *cache)  	return err;  } +static void reloc_cache_reset(struct reloc_cache *cache) +{ +	void *vaddr; + +	if (!cache->vaddr) +		return; + +	vaddr = unmask_page(cache->vaddr); +	if (cache->vaddr & KMAP) { +		if (cache->vaddr & CLFLUSH_AFTER) +			mb(); + +		kunmap_atomic(vaddr); +		i915_gem_object_finish_access((struct drm_i915_gem_object *)cache->node.mm); +	} else { +		struct i915_ggtt *ggtt = cache_to_ggtt(cache); + +		intel_gt_flush_ggtt_writes(ggtt->vm.gt); +		io_mapping_unmap_atomic((void __iomem *)vaddr); + +		if (drm_mm_node_allocated(&cache->node)) { +			ggtt->vm.clear_range(&ggtt->vm, +					     cache->node.start, +					     cache->node.size); +			mutex_lock(&ggtt->vm.mutex); +			drm_mm_remove_node(&cache->node); +			mutex_unlock(&ggtt->vm.mutex); +		} else { +			i915_vma_unpin((struct i915_vma *)cache->node.mm); +		} +	} + +	cache->vaddr = 0; +	cache->page = -1; +} + +static void *reloc_kmap(struct drm_i915_gem_object *obj, +			struct reloc_cache *cache, +			unsigned long page) +{ +	void *vaddr; + +	if (cache->vaddr) { +		kunmap_atomic(unmask_page(cache->vaddr)); +	} else { +		unsigned int flushes; +		int err; + +		err = i915_gem_object_prepare_write(obj, &flushes); +		if (err) +			return ERR_PTR(err); + +		BUILD_BUG_ON(KMAP & CLFLUSH_FLAGS); +		BUILD_BUG_ON((KMAP | CLFLUSH_FLAGS) & PAGE_MASK); + +		cache->vaddr = flushes | KMAP; +		cache->node.mm = (void *)obj; +		if (flushes) +			mb(); +	} + +	vaddr = kmap_atomic(i915_gem_object_get_dirty_page(obj, page)); +	cache->vaddr = unmask_flags(cache->vaddr) | (unsigned long)vaddr; +	cache->page = page; + +	return vaddr; +} + +static void *reloc_iomap(struct drm_i915_gem_object *obj, +			 struct reloc_cache *cache, +			 unsigned long page) +{ +	struct i915_ggtt *ggtt = cache_to_ggtt(cache); +	unsigned long offset; +	void *vaddr; + +	if (cache->vaddr) { +		intel_gt_flush_ggtt_writes(ggtt->vm.gt); +		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr)); +	} else { +		struct i915_vma *vma; +		int err; + +		if (i915_gem_object_is_tiled(obj)) +			return ERR_PTR(-EINVAL); + +		if (use_cpu_reloc(cache, obj)) +			return NULL; + +		i915_gem_object_lock(obj); +		err = i915_gem_object_set_to_gtt_domain(obj, true); +		i915_gem_object_unlock(obj); +		if (err) +			return ERR_PTR(err); + +		vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, +					       PIN_MAPPABLE | +					       PIN_NONBLOCK /* NOWARN */ | +					       PIN_NOEVICT); +		if (IS_ERR(vma)) { +			memset(&cache->node, 0, sizeof(cache->node)); +			mutex_lock(&ggtt->vm.mutex); +			err = drm_mm_insert_node_in_range +				(&ggtt->vm.mm, &cache->node, +				 PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE, +				 0, ggtt->mappable_end, +				 DRM_MM_INSERT_LOW); +			mutex_unlock(&ggtt->vm.mutex); +			if (err) /* no inactive aperture space, use cpu reloc */ +				return NULL; +		} else { +			cache->node.start = vma->node.start; +			cache->node.mm = (void *)vma; +		} +	} + +	offset = cache->node.start; +	if (drm_mm_node_allocated(&cache->node)) { +		ggtt->vm.insert_page(&ggtt->vm, +				     i915_gem_object_get_dma_address(obj, page), +				     offset, I915_CACHE_NONE, 0); +	} else { +		offset += page << PAGE_SHIFT; +	} + +	vaddr = (void __force *)io_mapping_map_atomic_wc(&ggtt->iomap, +							 offset); +	cache->page = page; +	cache->vaddr = (unsigned long)vaddr; + +	return vaddr; +} + +static void *reloc_vaddr(struct drm_i915_gem_object *obj, +			 struct reloc_cache *cache, +			 unsigned long page) +{ +	void *vaddr; + +	if (cache->page == page) { +		vaddr = unmask_page(cache->vaddr); +	} else { +		vaddr = NULL; +		if ((cache->vaddr & KMAP) == 0) +			vaddr = reloc_iomap(obj, cache, page); +		if (!vaddr) +			vaddr = reloc_kmap(obj, cache, page); +	} + +	return vaddr; +} + +static void clflush_write32(u32 *addr, u32 value, unsigned int flushes) +{ +	if (unlikely(flushes & (CLFLUSH_BEFORE | CLFLUSH_AFTER))) { +		if (flushes & CLFLUSH_BEFORE) { +			clflushopt(addr); +			mb(); +		} + +		*addr = value; + +		/* +		 * Writes to the same cacheline are serialised by the CPU +		 * (including clflush). On the write path, we only require +		 * that it hits memory in an orderly fashion and place +		 * mb barriers at the start and end of the relocation phase +		 * to ensure ordering of clflush wrt to the system. +		 */ +		if (flushes & CLFLUSH_AFTER) +			clflushopt(addr); +	} else +		*addr = value; +} +  static int reloc_move_to_gpu(struct i915_request *rq, struct i915_vma *vma)  {  	struct drm_i915_gem_object *obj = vma->obj; @@ -1214,6 +1436,17 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb,  	return cmd;  } +static inline bool use_reloc_gpu(struct i915_vma *vma) +{ +	if (DBG_FORCE_RELOC == FORCE_GPU_RELOC) +		return true; + +	if (DBG_FORCE_RELOC) +		return false; + +	return !dma_resv_test_signaled_rcu(vma->resv, true); +} +  static unsigned long vma_phys_addr(struct i915_vma *vma, u32 offset)  {  	struct page *page; @@ -1228,10 +1461,10 @@ static unsigned long vma_phys_addr(struct i915_vma *vma, u32 offset)  	return addr + offset_in_page(offset);  } -static int __reloc_entry_gpu(struct i915_execbuffer *eb, -			     struct i915_vma *vma, -			     u64 offset, -			     u64 target_addr) +static bool __reloc_entry_gpu(struct i915_execbuffer *eb, +			      struct i915_vma *vma, +			      u64 offset, +			      u64 target_addr)  {  	const unsigned int gen = eb->reloc_cache.gen;  	unsigned int len; @@ -1247,7 +1480,7 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,  	batch = reloc_gpu(eb, vma, len);  	if (IS_ERR(batch)) -		return PTR_ERR(batch); +		return false;  	addr = gen8_canonical_addr(vma->node.start + offset);  	if (gen >= 8) { @@ -1296,21 +1529,55 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,  		*batch++ = target_addr;  	} -	return 0; +	return true; +} + +static bool reloc_entry_gpu(struct i915_execbuffer *eb, +			    struct i915_vma *vma, +			    u64 offset, +			    u64 target_addr) +{ +	if (eb->reloc_cache.vaddr) +		return false; + +	if (!use_reloc_gpu(vma)) +		return false; + +	return __reloc_entry_gpu(eb, vma, offset, target_addr);  }  static u64 -relocate_entry(struct i915_execbuffer *eb, -	       struct i915_vma *vma, +relocate_entry(struct i915_vma *vma,  	       const struct drm_i915_gem_relocation_entry *reloc, +	       struct i915_execbuffer *eb,  	       const struct i915_vma *target)  {  	u64 target_addr = relocation_target(reloc, target); -	int err; - -	err = __reloc_entry_gpu(eb, vma, reloc->offset, target_addr); -	if (err) -		return err; +	u64 offset = reloc->offset; + +	if (!reloc_entry_gpu(eb, vma, offset, target_addr)) { +		bool wide = eb->reloc_cache.use_64bit_reloc; +		void *vaddr; + +repeat: +		vaddr = reloc_vaddr(vma->obj, +				    &eb->reloc_cache, +				    offset >> PAGE_SHIFT); +		if (IS_ERR(vaddr)) +			return PTR_ERR(vaddr); + +		GEM_BUG_ON(!IS_ALIGNED(offset, sizeof(u32))); +		clflush_write32(vaddr + offset_in_page(offset), +				lower_32_bits(target_addr), +				eb->reloc_cache.vaddr); + +		if (wide) { +			offset += sizeof(u32); +			target_addr >>= 32; +			wide = false; +			goto repeat; +		} +	}  	return target->node.start | UPDATE;  } @@ -1375,7 +1642,8 @@ eb_relocate_entry(struct i915_execbuffer *eb,  	 * If the relocation already has the right value in it, no  	 * more work needs to be done.  	 */ -	if (gen8_canonical_addr(target->vma->node.start) == reloc->presumed_offset) +	if (!DBG_FORCE_RELOC && +	    gen8_canonical_addr(target->vma->node.start) == reloc->presumed_offset)  		return 0;  	/* Check that the relocation address is valid... */ @@ -1407,7 +1675,7 @@ eb_relocate_entry(struct i915_execbuffer *eb,  	ev->flags &= ~EXEC_OBJECT_ASYNC;  	/* and update the user's relocation entry */ -	return relocate_entry(eb, ev->vma, reloc, target->vma); +	return relocate_entry(ev->vma, reloc, eb, target->vma);  }  static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev) @@ -1445,8 +1713,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)  		 * this is bad and so lockdep complains vehemently.  		 */  		copied = __copy_from_user(r, urelocs, count * sizeof(r[0])); -		if (unlikely(copied)) -			return -EFAULT; +		if (unlikely(copied)) { +			remain = -EFAULT; +			goto out; +		}  		remain -= count;  		do { @@ -1454,7 +1724,8 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)  			if (likely(offset == 0)) {  			} else if ((s64)offset < 0) { -				return (int)offset; +				remain = (int)offset; +				goto out;  			} else {  				/*  				 * Note that reporting an error now @@ -1484,8 +1755,9 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)  		} while (r++, --count);  		urelocs += ARRAY_SIZE(stack);  	} while (remain); - -	return 0; +out: +	reloc_cache_reset(&eb->reloc_cache); +	return remain;  }  static int eb_relocate(struct i915_execbuffer *eb) @@ -2392,7 +2664,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,  	eb.i915 = i915;  	eb.file = file;  	eb.args = args; -	if (!(args->flags & I915_EXEC_NO_RELOC)) +	if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))  		args->flags |= __EXEC_HAS_RELOC;  	eb.exec = exec; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index b23368529a40..753f82d87a31 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -209,7 +209,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)  	switch (err) {  	default:  		WARN_ONCE(err, "unhandled error in %s: %i\n", __func__, err); -		/* fallthrough */ +		fallthrough;  	case -EIO: /* shmemfs failure from swap device */  	case -EFAULT: /* purged object */  	case -ENODEV: /* bad object, how did you get here! */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index e5b9276d254c..9cf4ad78ece6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -258,6 +258,10 @@ struct page *  i915_gem_object_get_page(struct drm_i915_gem_object *obj,  			 unsigned int n); +struct page * +i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, +			       unsigned int n); +  dma_addr_t  i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj,  				    unsigned long n, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 7050519c87a4..e8a083743e09 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -276,7 +276,7 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,  	switch (type) {  	default:  		MISSING_CASE(type); -		/* fallthrough - to use PAGE_KERNEL anyway */ +		fallthrough;	/* to use PAGE_KERNEL anyway */  	case I915_MAP_WB:  		pgprot = PAGE_KERNEL;  		break; @@ -548,6 +548,20 @@ i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n)  	return nth_page(sg_page(sg), offset);  } +/* Like i915_gem_object_get_page(), but mark the returned page dirty */ +struct page * +i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, +			       unsigned int n) +{ +	struct page *page; + +	page = i915_gem_object_get_page(obj, n); +	if (!obj->mm.dirty) +		set_page_dirty(page); + +	return page; +} +  dma_addr_t  i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj,  				    unsigned long n, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index e0f21f12d3ce..0be5e8683337 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -249,7 +249,7 @@ static void vlv_get_stolen_reserved(struct drm_i915_private *i915,  	switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {  	default:  		MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK); -		/* fall through */ +		fallthrough;  	case GEN7_STOLEN_RESERVED_1M:  		*size = 1024 * 1024;  		break; @@ -416,7 +416,7 @@ static int i915_gem_init_stolen(struct drm_i915_private *i915)  	case 4:  		if (!IS_G4X(i915))  			break; -		/* fall through */ +		fallthrough;  	case 5:  		g4x_get_stolen_reserved(i915, uncore,  					&reserved_base, &reserved_size); @@ -445,7 +445,7 @@ static int i915_gem_init_stolen(struct drm_i915_private *i915)  		break;  	default:  		MISSING_CASE(INTEL_GEN(i915)); -		/* fall-through */ +		fallthrough;  	case 11:  	case 12:  		icl_get_stolen_reserved(i915, uncore, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 2c2bf24140c9..12b30075134a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -596,14 +596,6 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)  				      GFP_KERNEL |  				      __GFP_NORETRY |  				      __GFP_NOWARN); -		/* -		 * Using __get_user_pages_fast() with a read-only -		 * access is questionable. A read-only page may be -		 * COW-broken, and then this might end up giving -		 * the wrong side of the COW.. -		 * -		 * We may or may not care. -		 */  		if (pvec) {  			/* defer to worker if malloc fails */  			if (!i915_gem_object_is_readonly(obj)) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c index 57c14d3340cd..a49016f8ee0d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c @@ -37,14 +37,20 @@ static int __igt_gpu_reloc(struct i915_execbuffer *eb,  		return err;  	/* 8-Byte aligned */ -	err = __reloc_entry_gpu(eb, vma, offsets[0] * sizeof(u32), 0); -	if (err) +	if (!__reloc_entry_gpu(eb, vma, +			       offsets[0] * sizeof(u32), +			       0)) { +		err = -EIO;  		goto unpin_vma; +	}  	/* !8-Byte aligned */ -	err = __reloc_entry_gpu(eb, vma, offsets[1] * sizeof(u32), 1); -	if (err) +	if (!__reloc_entry_gpu(eb, vma, +			       offsets[1] * sizeof(u32), +			       1)) { +		err = -EIO;  		goto unpin_vma; +	}  	/* Skip to the end of the cmd page */  	i = PAGE_SIZE / sizeof(u32) - RELOC_TAIL - 1; @@ -54,9 +60,12 @@ static int __igt_gpu_reloc(struct i915_execbuffer *eb,  	eb->reloc_cache.rq_size += i;  	/* Force batch chaining */ -	err = __reloc_entry_gpu(eb, vma, offsets[2] * sizeof(u32), 2); -	if (err) +	if (!__reloc_entry_gpu(eb, vma, +			       offsets[2] * sizeof(u32), +			       2)) { +		err = -EIO;  		goto unpin_vma; +	}  	GEM_BUG_ON(!eb->reloc_cache.rq);  	rq = i915_request_get(eb->reloc_cache.rq); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index dd1a42c4d344..26087dd79782 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -213,7 +213,7 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class)  		break;  	default:  		MISSING_CASE(class); -		/* fall through */ +		fallthrough;  	case VIDEO_DECODE_CLASS:  	case VIDEO_ENHANCEMENT_CLASS:  	case COPY_ENGINE_CLASS: diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 62979ea591f0..99e28d9021e8 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -1437,7 +1437,7 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)  	switch (vma->ggtt_view.type) {  	default:  		GEM_BUG_ON(vma->ggtt_view.type); -		/* fall through */ +		fallthrough;  	case I915_GGTT_VIEW_NORMAL:  		vma->pages = vma->obj->mm.pages;  		return 0; diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 24322ef08aa4..9eeaca957a7e 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2060,6 +2060,14 @@ static inline void clear_ports(struct i915_request **ports, int count)  	memset_p((void **)ports, NULL, count);  } +static inline void +copy_ports(struct i915_request **dst, struct i915_request **src, int count) +{ +	/* A memcpy_p() would be very useful here! */ +	while (count--) +		WRITE_ONCE(*dst++, *src++); /* avoid write tearing */ +} +  static void execlists_dequeue(struct intel_engine_cs *engine)  {  	struct intel_engine_execlists * const execlists = &engine->execlists; @@ -2648,10 +2656,9 @@ static void process_csb(struct intel_engine_cs *engine)  			/* switch pending to inflight */  			GEM_BUG_ON(!assert_pending_valid(execlists, "promote")); -			memcpy(execlists->inflight, -			       execlists->pending, -			       execlists_num_ports(execlists) * -			       sizeof(*execlists->pending)); +			copy_ports(execlists->inflight, +				   execlists->pending, +				   execlists_num_ports(execlists));  			smp_wmb(); /* complete the seqlock */  			WRITE_ONCE(execlists->active, execlists->inflight); diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 94915f668715..898593ca4889 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -100,7 +100,7 @@ static void set_hwsp(struct intel_engine_cs *engine, u32 offset)  		 */  		default:  			GEM_BUG_ON(engine->id); -			/* fallthrough */ +			fallthrough;  		case RCS0:  			hwsp = RENDER_HWS_PGA_GEN7;  			break; diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 63bba7b4bb2f..05f3bc98d242 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1226,7 +1226,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)  	switch (notification) {  	case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE:  		root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY; -		/* fall through */ +		fallthrough;  	case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE:  		mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps);  		return PTR_ERR_OR_ZERO(mm); diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 372354d33f55..5ac4a999f05a 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -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); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 6a3a2ce0b394..3e6cbb0d1150 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1159,7 +1159,7 @@ static void engine_record_registers(struct intel_engine_coredump *ee)  			switch (engine->id) {  			default:  				MISSING_CASE(engine->id); -				/* fall through */ +				fallthrough;  			case RCS0:  				mmio = RENDER_HWS_PGA_GEN7;  				break; diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 056994224c6b..69c0fa20eba1 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -474,7 +474,7 @@ config_status(struct drm_i915_private *i915, u64 config)  		if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))  			/* Requires a mutex for sampling! */  			return -ENODEV; -		/* Fall-through. */ +		fallthrough;  	case I915_PMU_REQUESTED_FREQUENCY:  		if (INTEL_GEN(i915) < 6)  			return -ENODEV; diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 0b2fe55e6194..781a6783affe 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -388,17 +388,38 @@ static bool __request_in_flight(const struct i915_request *signal)  	 * As we know that there are always preemption points between  	 * requests, we know that only the currently executing request  	 * may be still active even though we have cleared the flag. -	 * However, we can't rely on our tracking of ELSP[0] to known +	 * However, we can't rely on our tracking of ELSP[0] to know  	 * which request is currently active and so maybe stuck, as  	 * the tracking maybe an event behind. Instead assume that  	 * if the context is still inflight, then it is still active  	 * even if the active flag has been cleared. +	 * +	 * To further complicate matters, if there a pending promotion, the HW +	 * may either perform a context switch to the second inflight execlists, +	 * or it may switch to the pending set of execlists. In the case of the +	 * latter, it may send the ACK and we process the event copying the +	 * pending[] over top of inflight[], _overwriting_ our *active. Since +	 * this implies the HW is arbitrating and not struck in *active, we do +	 * not worry about complete accuracy, but we do require no read/write +	 * tearing of the pointer [the read of the pointer must be valid, even +	 * as the array is being overwritten, for which we require the writes +	 * to avoid tearing.] +	 * +	 * Note that the read of *execlists->active may race with the promotion +	 * of execlists->pending[] to execlists->inflight[], overwritting +	 * the value at *execlists->active. This is fine. The promotion implies +	 * that we received an ACK from the HW, and so the context is not +	 * stuck -- if we do not see ourselves in *active, the inflight status +	 * is valid. If instead we see ourselves being copied into *active, +	 * we are inflight and may signal the callback.  	 */  	if (!intel_context_inflight(signal->context))  		return false;  	rcu_read_lock(); -	for (port = __engine_active(signal->engine); (rq = *port); port++) { +	for (port = __engine_active(signal->engine); +	     (rq = READ_ONCE(*port)); /* may race with promotion of pending[] */ +	     port++) {  		if (rq->context == signal->context) {  			inflight = i915_seqno_passed(rq->fence.seqno,  						     signal->fence.seqno); diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 295b9829e2da..4cd2038cbe35 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -164,9 +164,13 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence,  		do {  			list_for_each_entry_safe(pos, next, &x->head, entry) { -				pos->func(pos, -					  TASK_NORMAL, fence->error, -					  &extra); +				int wake_flags; + +				wake_flags = fence->error; +				if (pos->func == autoremove_wake_function) +					wake_flags = 0; + +				pos->func(pos, TASK_NORMAL, wake_flags, &extra);  			}  			if (list_empty(&extra)) diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 6776ebb3246d..8a4235d9d9f1 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -447,7 +447,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,  		if (fb->pitches[1] != fb->pitches[2])  			return -EINVAL; -		/* fall-through */ +		fallthrough;  	case DRM_FORMAT_NV12:  	case DRM_FORMAT_NV16:  		ubo = drm_plane_state_to_ubo(state); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 3fc5511330b9..4d29568be3f5 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -831,13 +831,19 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  			drm_crtc_index(&mtk_crtc->base));  		mtk_crtc->cmdq_client = NULL;  	} -	ret = of_property_read_u32_index(priv->mutex_node, -					 "mediatek,gce-events", -					 drm_crtc_index(&mtk_crtc->base), -					 &mtk_crtc->cmdq_event); -	if (ret) -		dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n", -			drm_crtc_index(&mtk_crtc->base)); + +	if (mtk_crtc->cmdq_client) { +		ret = of_property_read_u32_index(priv->mutex_node, +						 "mediatek,gce-events", +						 drm_crtc_index(&mtk_crtc->base), +						 &mtk_crtc->cmdq_event); +		if (ret) { +			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n", +				drm_crtc_index(&mtk_crtc->base)); +			cmdq_mbox_destroy(mtk_crtc->cmdq_client); +			mtk_crtc->cmdq_client = NULL; +		} +	}  #endif  	return 0;  } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 57c88de9a329..526648885b97 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -496,6 +496,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,  #if IS_REACHABLE(CONFIG_MTK_CMDQ)  	if (of_address_to_resource(node, 0, &res) != 0) {  		dev_err(dev, "Missing reg in %s node\n", node->full_name); +		put_device(&larb_pdev->dev);  		return -EINVAL;  	}  	comp->regs_pa = res.start; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 040a8f393fe2..2d982740b1a4 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -27,7 +27,6 @@  #include "mtk_drm_crtc.h"  #include "mtk_drm_ddp.h" -#include "mtk_drm_ddp.h"  #include "mtk_drm_ddp_comp.h"  #include "mtk_drm_drv.h"  #include "mtk_drm_gem.h" @@ -165,7 +164,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)  	ret = drmm_mode_config_init(drm);  	if (ret) -		return ret; +		goto put_mutex_dev;  	drm->mode_config.min_width = 64;  	drm->mode_config.min_height = 64; @@ -182,7 +181,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)  	ret = component_bind_all(drm->dev, drm);  	if (ret) -		return ret; +		goto put_mutex_dev;  	/*  	 * We currently support two fixed data streams, each optional, @@ -229,7 +228,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)  	}  	if (!dma_dev->dma_parms) {  		ret = -ENOMEM; -		goto err_component_unbind; +		goto put_dma_dev;  	}  	ret = dma_set_max_seg_size(dma_dev, (unsigned int)DMA_BIT_MASK(32)); @@ -256,9 +255,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)  err_unset_dma_parms:  	if (private->dma_parms_allocated)  		dma_dev->dma_parms = NULL; +put_dma_dev: +	put_device(private->dma_dev);  err_component_unbind:  	component_unbind_all(drm->dev, drm); - +put_mutex_dev: +	put_device(private->mutex_dev);  	return ret;  } @@ -544,8 +546,13 @@ err_pm:  	pm_runtime_disable(dev);  err_node:  	of_node_put(private->mutex_node); -	for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) +	for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) {  		of_node_put(private->comp_node[i]); +		if (private->ddp_comp[i]) { +			put_device(private->ddp_comp[i]->larb_dev); +			private->ddp_comp[i] = NULL; +		} +	}  	return ret;  } diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 16fd99dcdacf..80b7a082e874 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -466,14 +466,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)  	horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10);  	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) -		horizontal_backporch_byte = -			(vm->hback_porch * dsi_tmp_buf_bpp - 10); +		horizontal_backporch_byte = vm->hback_porch * dsi_tmp_buf_bpp;  	else -		horizontal_backporch_byte = ((vm->hback_porch + vm->hsync_len) * -			dsi_tmp_buf_bpp - 10); +		horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) * +					    dsi_tmp_buf_bpp;  	data_phy_cycles = timing->lpx + timing->da_hs_prepare + -			  timing->da_hs_zero + timing->da_hs_exit + 3; +			  timing->da_hs_zero + timing->da_hs_exit;  	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {  		if ((vm->hfront_porch + vm->hback_porch) * dsi_tmp_buf_bpp > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index f2e9b429960b..a97725680d4e 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1507,25 +1507,30 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,  		dev_err(dev,  			"Failed to get system configuration registers: %d\n",  			ret); -		return ret; +		goto put_device;  	}  	hdmi->sys_regmap = regmap;  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	hdmi->regs = devm_ioremap_resource(dev, mem); -	if (IS_ERR(hdmi->regs)) -		return PTR_ERR(hdmi->regs); +	if (IS_ERR(hdmi->regs)) { +		ret = PTR_ERR(hdmi->regs); +		goto put_device; +	}  	remote = of_graph_get_remote_node(np, 1, 0); -	if (!remote) -		return -EINVAL; +	if (!remote) { +		ret = -EINVAL; +		goto put_device; +	}  	if (!of_device_is_compatible(remote, "hdmi-connector")) {  		hdmi->next_bridge = of_drm_find_bridge(remote);  		if (!hdmi->next_bridge) {  			dev_err(dev, "Waiting for external bridge\n");  			of_node_put(remote); -			return -EPROBE_DEFER; +			ret = -EPROBE_DEFER; +			goto put_device;  		}  	} @@ -1534,7 +1539,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,  		dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",  			remote);  		of_node_put(remote); -		return -EINVAL; +		ret = -EINVAL; +		goto put_device;  	}  	of_node_put(remote); @@ -1542,10 +1548,14 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,  	of_node_put(i2c_np);  	if (!hdmi->ddc_adpt) {  		dev_err(dev, "Failed to get ddc i2c adapter by node\n"); -		return -EINVAL; +		ret = -EINVAL; +		goto put_device;  	}  	return 0; +put_device: +	put_device(hdmi->cec_dev); +	return ret;  }  /* diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.c b/drivers/gpu/drm/meson/meson_osd_afbcd.c index f12e0271f166..ffc6b584dbf8 100644 --- a/drivers/gpu/drm/meson/meson_osd_afbcd.c +++ b/drivers/gpu/drm/meson/meson_osd_afbcd.c @@ -205,7 +205,7 @@ static int meson_g12a_afbcd_pixel_fmt(u64 modifier, uint32_t format)  		/* YTR is forbidden for non XBGR formats */  		if (modifier & AFBC_FORMAT_MOD_YTR)  			return -EINVAL; -	/* fall through */ +		fallthrough;  	case DRM_FORMAT_XBGR8888:  	case DRM_FORMAT_ABGR8888:  		return MAFBC_FMT_RGBA8888; diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c index a8bcc70644df..1ffbbecafa22 100644 --- a/drivers/gpu/drm/meson/meson_overlay.c +++ b/drivers/gpu/drm/meson/meson_overlay.c @@ -654,7 +654,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,  			 priv->viu.vd1_addr2,  			 priv->viu.vd1_stride2,  			 priv->viu.vd1_height2); -	/* fallthrough */ +		fallthrough;  	case 2:  		gem = drm_fb_cma_get_gem_obj(fb, 1);  		priv->viu.vd1_addr1 = gem->paddr + fb->offsets[1]; @@ -666,7 +666,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,  			 priv->viu.vd1_addr1,  			 priv->viu.vd1_stride1,  			 priv->viu.vd1_height1); -	/* fallthrough */ +		fallthrough;  	case 1:  		gem = drm_fb_cma_get_gem_obj(fb, 0);  		priv->viu.vd1_addr0 = gem->paddr + fb->offsets[0]; diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 6021f8d9efd1..48fa49f69d6d 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -164,6 +164,11 @@ static int a2xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		return ret; +	gpu_write(gpu, REG_AXXX_CP_RB_CNTL, +		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + +	gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); +  	/* NOTE: PM4/micro-engine firmware registers look to be the same  	 * for a2xx and a3xx.. we could possibly push that part down to  	 * adreno_gpu base class.  Or push both PM4 and PFP but diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 0a5ea9f56cb8..f6471145a7a6 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -211,6 +211,16 @@ static int a3xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		return ret; +	/* +	 * Use the default ringbuffer size and block size but disable the RPTR +	 * shadow +	 */ +	gpu_write(gpu, REG_AXXX_CP_RB_CNTL, +		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + +	/* Set the ringbuffer address */ +	gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); +  	/* setup access protection: */  	gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007); diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index b9b26b2bf9c5..954753600625 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -267,6 +267,16 @@ static int a4xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		return ret; +	/* +	 * Use the default ringbuffer size and block size but disable the RPTR +	 * shadow +	 */ +	gpu_write(gpu, REG_A4XX_CP_RB_CNTL, +		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + +	/* Set the ringbuffer address */ +	gpu_write(gpu, REG_A4XX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); +  	/* Load PM4: */  	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);  	len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 9e63a190642c..91726da82ed6 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -59,7 +59,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit  		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:  			if (priv->lastctx == ctx)  				break; -			/* fall-thru */ +			fallthrough;  		case MSM_SUBMIT_CMD_BUF:  			/* copy commands into RB: */  			obj = submit->bos[submit->cmd[i].idx].obj; @@ -150,7 +150,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,  		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:  			if (priv->lastctx == ctx)  				break; -			/* fall-thru */ +			fallthrough;  		case MSM_SUBMIT_CMD_BUF:  			OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);  			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); @@ -703,8 +703,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		return ret; -	a5xx_preempt_hw_init(gpu); -  	if (!adreno_is_a510(adreno_gpu))  		a5xx_gpmu_ucode_init(gpu); @@ -712,6 +710,15 @@ static int a5xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		return ret; +	/* Set the ringbuffer address */ +	gpu_write64(gpu, REG_A5XX_CP_RB_BASE, REG_A5XX_CP_RB_BASE_HI, +		gpu->rb[0]->iova); + +	gpu_write(gpu, REG_A5XX_CP_RB_CNTL, +		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + +	a5xx_preempt_hw_init(gpu); +  	/* Disable the interrupts through the initial bringup stage */  	gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK); @@ -1511,7 +1518,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)  	check_speed_bin(&pdev->dev); -	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); +	/* Restricting nr_rings to 1 to temporarily disable preemption */ +	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);  	if (ret) {  		a5xx_destroy(&(a5xx_gpu->base.base));  		return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h index 54868d4e3958..1e5b1a15a70f 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -31,6 +31,7 @@ struct a5xx_gpu {  	struct msm_ringbuffer *next_ring;  	struct drm_gem_object *preempt_bo[MSM_GPU_MAX_RINGS]; +	struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];  	struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS];  	uint64_t preempt_iova[MSM_GPU_MAX_RINGS]; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 9cf9353a7ff1..9f3fe177b00e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -226,19 +226,31 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,  	struct adreno_gpu *adreno_gpu = &a5xx_gpu->base;  	struct msm_gpu *gpu = &adreno_gpu->base;  	struct a5xx_preempt_record *ptr; -	struct drm_gem_object *bo = NULL; -	u64 iova = 0; +	void *counters; +	struct drm_gem_object *bo = NULL, *counters_bo = NULL; +	u64 iova = 0, counters_iova = 0;  	ptr = msm_gem_kernel_new(gpu->dev,  		A5XX_PREEMPT_RECORD_SIZE + A5XX_PREEMPT_COUNTER_SIZE, -		MSM_BO_UNCACHED, gpu->aspace, &bo, &iova); +		MSM_BO_UNCACHED | MSM_BO_MAP_PRIV, gpu->aspace, &bo, &iova);  	if (IS_ERR(ptr))  		return PTR_ERR(ptr); +	/* The buffer to store counters needs to be unprivileged */ +	counters = msm_gem_kernel_new(gpu->dev, +		A5XX_PREEMPT_COUNTER_SIZE, +		MSM_BO_UNCACHED, gpu->aspace, &counters_bo, &counters_iova); +	if (IS_ERR(counters)) { +		msm_gem_kernel_put(bo, gpu->aspace, true); +		return PTR_ERR(counters); +	} +  	msm_gem_object_set_name(bo, "preempt"); +	msm_gem_object_set_name(counters_bo, "preempt_counters");  	a5xx_gpu->preempt_bo[ring->id] = bo; +	a5xx_gpu->preempt_counters_bo[ring->id] = counters_bo;  	a5xx_gpu->preempt_iova[ring->id] = iova;  	a5xx_gpu->preempt[ring->id] = ptr; @@ -249,7 +261,7 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,  	ptr->data = 0;  	ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT;  	ptr->rptr_addr = rbmemptr(ring, rptr); -	ptr->counter = iova + A5XX_PREEMPT_RECORD_SIZE; +	ptr->counter = counters_iova;  	return 0;  } @@ -260,8 +272,11 @@ void a5xx_preempt_fini(struct msm_gpu *gpu)  	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);  	int i; -	for (i = 0; i < gpu->nr_rings; i++) +	for (i = 0; i < gpu->nr_rings; i++) {  		msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace, true); +		msm_gem_kernel_put(a5xx_gpu->preempt_counters_bo[i], +			gpu->aspace, true); +	}  }  void a5xx_preempt_init(struct msm_gpu *gpu) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b67b38c8fadf..e1c7bcd1b1eb 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -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"); @@ -602,7 +608,7 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)  		gmu_rmw(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0,  			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_IFPC_ENABLE |  			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_HM_POWER_COLLAPSE_ENABLE); -		/* Fall through */ +		fallthrough;  	case GMU_IDLE_STATE_SPTP:  		gmu_write(gmu, REG_A6XX_GMU_PWR_COL_SPTPRAC_HYST,  			GMU_PWR_COL_HYST); @@ -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) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index c5a3e4d4c007..66a95e22b7b3 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -117,7 +117,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,  		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:  			if (priv->lastctx == ctx)  				break; -			/* fall-thru */ +			fallthrough;  		case MSM_SUBMIT_CMD_BUF:  			OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);  			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); @@ -678,7 +678,8 @@ static int a6xx_hw_init(struct msm_gpu *gpu)  			A6XX_PROTECT_RDONLY(0x980, 0x4));  	gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0)); -	if (adreno_is_a650(adreno_gpu)) { +	/* Enable expanded apriv for targets that support it */ +	if (gpu->hw_apriv) {  		gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,  			(1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1));  	} @@ -694,6 +695,13 @@ static int a6xx_hw_init(struct msm_gpu *gpu)  	if (ret)  		goto out; +	/* Set the ringbuffer address */ +	gpu_write64(gpu, REG_A6XX_CP_RB_BASE, REG_A6XX_CP_RB_BASE_HI, +		gpu->rb[0]->iova); + +	gpu_write(gpu, REG_A6XX_CP_RB_CNTL, +		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); +  	/* Always come up on rb 0 */  	a6xx_gpu->cur_ring = gpu->rb[0]; @@ -1056,6 +1064,9 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)  	adreno_gpu->registers = NULL;  	adreno_gpu->reg_offsets = a6xx_register_offsets; +	if (adreno_is_a650(adreno_gpu)) +		adreno_gpu->base.hw_apriv = true; +  	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);  	if (ret) {  		a6xx_destroy(&(a6xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 959656ad6987..b12f5b4a1bea 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -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;  } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h index 846fd5b54c23..2fb58b7098e4 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h @@ -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 }, diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 4e84f3c76f4f..9eeb46bf2a5d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -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), diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index e23641a5ec84..862dd35b27d3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -396,30 +396,10 @@ 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;  	} -	/* -	 * Setup REG_CP_RB_CNTL.  The same value is used across targets (with -	 * the excpetion of A430 that disables the RPTR shadow) - the cacluation -	 * for the ringbuffer size and block size is moved to msm_gpu.h for the -	 * pre-processor to deal with and the A430 variant is ORed in here -	 */ -	adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, -		MSM_GPU_RB_CNTL_DEFAULT | -		(adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); - -	/* Setup ringbuffer address - use ringbuffer[0] for GPU init */ -	adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE, -		REG_ADRENO_CP_RB_BASE_HI, gpu->rb[0]->iova); - -	if (!adreno_is_a430(adreno_gpu)) { -		adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, -			REG_ADRENO_CP_RB_RPTR_ADDR_HI, -			rbmemptr(gpu->rb[0], rptr)); -	} -  	return 0;  } @@ -427,11 +407,8 @@ int adreno_hw_init(struct msm_gpu *gpu)  static uint32_t get_rptr(struct adreno_gpu *adreno_gpu,  		struct msm_ringbuffer *ring)  { -	if (adreno_is_a430(adreno_gpu)) -		return ring->memptrs->rptr = adreno_gpu_read( -			adreno_gpu, REG_ADRENO_CP_RB_RPTR); -	else -		return ring->memptrs->rptr; +	return ring->memptrs->rptr = adreno_gpu_read( +		adreno_gpu, REG_ADRENO_CP_RB_RPTR);  }  struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu) @@ -474,7 +451,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,  			/* ignore if there has not been a ctx switch: */  			if (priv->lastctx == ctx)  				break; -			/* fall-thru */ +			fallthrough;  		case MSM_SUBMIT_CMD_BUF:  			OUT_PKT3(ring, adreno_is_a4xx(adreno_gpu) ?  				CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 99bb468f5f24..e55abae365b5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -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 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index f272a8d0f95b..c2729f71e2fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -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"); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index a97f6d2e5a08..bd6def436c65 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -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);  } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 33f6c56f01ed..29e373d2e7b5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -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); diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 5ccfad794c6a..561bfa48841c 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -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); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7d641c7e3514..79333842f70a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -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, diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index d5645472b25d..57ddc9438351 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -908,7 +908,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,  	memptrs = msm_gem_kernel_new(drm,  		sizeof(struct msm_rbmemptrs) * nr_rings, -		MSM_BO_UNCACHED, gpu->aspace, &gpu->memptrs_bo, +		check_apriv(gpu, MSM_BO_UNCACHED), gpu->aspace, &gpu->memptrs_bo,  		&memptrs_iova);  	if (IS_ERR(memptrs)) { diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 0db117a7339b..37cffac4cbe3 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -15,6 +15,7 @@  #include "msm_drv.h"  #include "msm_fence.h"  #include "msm_ringbuffer.h" +#include "msm_gem.h"  struct msm_gem_submit;  struct msm_gpu_perfcntr; @@ -139,6 +140,8 @@ struct msm_gpu {  	} devfreq;  	struct msm_gpu_state *crashstate; +	/* True if the hardware supports expanded apriv (a650 and newer) */ +	bool hw_apriv;  };  /* It turns out that all targets use the same ringbuffer size */ @@ -327,4 +330,12 @@ static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)  	mutex_unlock(&gpu->dev->struct_mutex);  } +/* + * Simple macro to semi-cleanly add the MAP_PRIV flag for targets that can + * support expanded privileges + */ +#define check_apriv(gpu, flags) \ +	(((gpu)->hw_apriv ? MSM_BO_MAP_PRIV : 0) | (flags)) + +  #endif /* __MSM_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index e397c44cc011..935bf9b1d941 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -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); +		check_apriv(gpu, MSM_BO_WC | MSM_BO_GPU_READONLY), +		gpu->aspace, &ring->bo, &ring->iova);  	if (IS_ERR(ring->start)) {  		ret = PTR_ERR(ring->start); diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index ad1f09a143aa..248edf69e168 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -50,7 +50,10 @@ core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy)  					interlock[NV50_DISP_INTERLOCK_OVLY] |  		  NVDEF(NV507D, UPDATE, NOT_DRIVER_FRIENDLY, FALSE) |  		  NVDEF(NV507D, UPDATE, NOT_DRIVER_UNFRIENDLY, FALSE) | -		  NVDEF(NV507D, UPDATE, INHIBIT_INTERRUPTS, FALSE)); +		  NVDEF(NV507D, UPDATE, INHIBIT_INTERRUPTS, FALSE), + +				SET_NOTIFIER_CONTROL, +		  NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE));  	return PUSH_KICK(push);  } diff --git a/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c b/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c index 9afe9a87bde0..814e5bd97446 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crcc37d.c @@ -6,7 +6,7 @@  #include "disp.h"  #include "head.h" -#include <nvif/push507c.h> +#include <nvif/pushc37b.h>  #include <nvhw/class/clc37d.h> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index e7874877da85..1ed242070001 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -257,6 +257,12 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,  	dmac->push->end = dmac->push->bgn;  	dmac->max = 0x1000/4 - 1; +	/* EVO channels are affected by a HW bug where the last 12 DWORDs +	 * of the push buffer aren't able to be used safely. +	 */ +	if (disp->oclass < GV100_DISP) +		dmac->max -= 12; +  	args->pushbuf = nvif_handle(&dmac->_push.mem.object);  	ret = nv50_chan_create(device, disp, oclass, head, data, size, diff --git a/drivers/gpu/drm/nouveau/include/nvif/push507c.h b/drivers/gpu/drm/nouveau/include/nvif/push507c.h index 889467f13fd9..7917bead4845 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push507c.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push507c.h @@ -20,6 +20,6 @@          PUSH_ASSERT(!((o) & ~DRF_SMASK(NV507C_DMA_JUMP_OFFSET)), "offset"); \  	PUSH_DATA__((p), NVDEF(NV507C, DMA, OPCODE, JUMP) |                 \  			 NVVAL(NV507C, DMA, JUMP_OFFSET, (o) >> 2),         \ -		    "jump 0x%08x - %s", (u32)(o), __func__);                \ +		    " jump 0x%08x - %s", (u32)(o), __func__);               \  } while(0)  #endif diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index e0817934ee16..bd12eae0cb31 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -597,7 +597,7 @@ static void venc_bridge_mode_set(struct drm_bridge *bridge,  	switch (venc_mode) {  	default:  		WARN_ON_ONCE(1); -		/* Fall-through */ +		fallthrough;  	case VENC_MODE_PAL:  		venc->config = &venc_config_pal_trm;  		break; diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index ba20c6f03719..886e9959496f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -4856,7 +4856,7 @@ static void ci_request_link_speed_change_before_state_change(struct radeon_devic  			pi->force_pcie_gen = RADEON_PCIE_GEN2;  			if (current_link_speed == RADEON_PCIE_GEN2)  				break; -			/* fall through */ +			fallthrough;  		case RADEON_PCIE_GEN2:  			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)  				break; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 3b7ead5be5bf..73f67bf222e1 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -820,7 +820,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  					  ((idx_value >> 21) & 0xF));  				return -EINVAL;  			} -			/* Fall through. */ +			fallthrough;  		case 6:  			track->cb[i].cpp = 4;  			break; @@ -971,7 +971,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  				return -EINVAL;  			}  			/* The same rules apply as for DXT3/5. */ -			/* Fall through. */ +			fallthrough;  		case R300_TX_FORMAT_DXT3:  		case R300_TX_FORMAT_DXT5:  			track->textures[i].cpp = 1; diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 1d4c04e0a449..50b89b6d9a6c 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -115,7 +115,7 @@ void r420_pipes_init(struct radeon_device *rdev)  	default:  		/* force to 1 pipe */  		num_pipes = 1; -		/* fall through */ +		fallthrough;  	case 1:  		tmp = (0 << 1);  		break; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 49e8266461f8..390a9621604a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -487,7 +487,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  				return -EINVAL;  			}  		} -		/* fall through */ +		fallthrough;  	case V_0280A0_CLEAR_ENABLE:  	{  		uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); @@ -1535,7 +1535,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,  		break;  	case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA:  		is_array = true; -		/* fall through */ +		fallthrough;  	case V_038000_SQ_TEX_DIM_2D_MSAA:  		array_check.nsamples = 1 << llevel;  		llevel = 0; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 1ad5c3b86b64..57fb3eb3a4b4 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -454,7 +454,7 @@ static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,  		if (p->rdev->family >= CHIP_PALM)  			return 0; -		/* fall through */ +		fallthrough;  	default:  		DRM_ERROR("UVD codec not supported by hardware %d!\n",  			  stream_type); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index a167e1c36d24..d1c73e9db889 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -5744,7 +5744,7 @@ static void si_request_link_speed_change_before_state_change(struct radeon_devic  			si_pi->force_pcie_gen = RADEON_PCIE_GEN2;  			if (current_link_speed == RADEON_PCIE_GEN2)  				break; -			/* fall through */ +			fallthrough;  		case RADEON_PCIE_GEN2:  			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)  				break; diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index f858d8d06347..800721153d51 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -219,7 +219,7 @@ done:  			WREG32(RS_DQ_RD_RET_CONF, 0x3f);  			WREG32(MC_CONFIG, 0x1f); -			/* fall through */ +			fallthrough;  		case CHIP_RV670:  		case CHIP_RV635: diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c index a2ac25c11c90..e0d40ae67d54 100644 --- a/drivers/gpu/drm/savage/savage_state.c +++ b/drivers/gpu/drm/savage/savage_state.c @@ -306,7 +306,7 @@ static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,  	case SAVAGE_PRIM_TRILIST_201:  		reorder = 1;  		prim = SAVAGE_PRIM_TRILIST; -		/* fall through */ +		fallthrough;  	case SAVAGE_PRIM_TRILIST:  		if (n % 3 != 0) {  			DRM_ERROR("wrong number of vertices %u in TRILIST\n", @@ -444,7 +444,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,  	case SAVAGE_PRIM_TRILIST_201:  		reorder = 1;  		prim = SAVAGE_PRIM_TRILIST; -		/* fall through */ +		fallthrough;  	case SAVAGE_PRIM_TRILIST:  		if (n % 3 != 0) {  			DRM_ERROR("wrong number of vertices %u in TRILIST\n", @@ -566,7 +566,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,  	case SAVAGE_PRIM_TRILIST_201:  		reorder = 1;  		prim = SAVAGE_PRIM_TRILIST; -		/* fall through */ +		fallthrough;  	case SAVAGE_PRIM_TRILIST:  		if (n % 3 != 0) {  			DRM_ERROR("wrong number of indices %u in TRILIST\n", n); @@ -705,7 +705,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,  	case SAVAGE_PRIM_TRILIST_201:  		reorder = 1;  		prim = SAVAGE_PRIM_TRILIST; -		/* fall through */ +		fallthrough;  	case SAVAGE_PRIM_TRILIST:  		if (n % 3 != 0) {  			DRM_ERROR("wrong number of indices %u in TRILIST\n", n); @@ -1066,7 +1066,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_  				ret = -EINVAL;  				goto done;  			} -			/* fall through */ +			fallthrough;  		case SAVAGE_CMD_DMA_PRIM:  		case SAVAGE_CMD_VB_PRIM:  			if (!first_draw_cmd) diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 008f07923bbc..38a558768e53 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -850,13 +850,13 @@ static int hdmi_audio_configure(struct sti_hdmi *hdmi)  	switch (info->channels) {  	case 8:  		audio_cfg |= HDMI_AUD_CFG_CH78_VALID; -		/* fall through */ +		fallthrough;  	case 6:  		audio_cfg |= HDMI_AUD_CFG_CH56_VALID; -		/* fall through */ +		fallthrough;  	case 4:  		audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH; -		/* fall through */ +		fallthrough;  	case 2:  		audio_cfg |= HDMI_AUD_CFG_CH12_VALID;  		break; diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 24d95f058918..e40c542254f6 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -195,7 +195,7 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,  	switch (encoder->encoder_type) {  	case DRM_MODE_ENCODER_LVDS:  		is_lvds = true; -		/* Fallthrough */ +		fallthrough;  	case DRM_MODE_ENCODER_DSI:  	case DRM_MODE_ENCODER_NONE:  		channel = 0; @@ -342,7 +342,7 @@ static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon,  		/* R and B components are only 5 bits deep */  		val |= SUN4I_TCON0_FRM_CTL_MODE_R;  		val |= SUN4I_TCON0_FRM_CTL_MODE_B; -		/* Fall through */ +		fallthrough;  	case MEDIA_BUS_FMT_RGB666_1X18:  	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:  		/* Fall through: enable dithering */ diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index 32d4c3f7fc4e..de8a11abd66a 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -1027,7 +1027,7 @@ static ssize_t sun6i_dsi_transfer(struct mipi_dsi_host *host,  			ret = sun6i_dsi_dcs_read(dsi, msg);  			break;  		} -		/* Else, fall through */ +		fallthrough;  	default:  		ret = -EINVAL; diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 9a0b3240bc58..424ad60b4f38 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -135,7 +135,7 @@ static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,  		default:  			WARN_ON_ONCE(1); -			/* fallthrough */ +			fallthrough;  		case 4:  			max = 4;  			break; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 1856962411c7..518220bd092a 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -386,7 +386,7 @@ static void tilcdc_crtc_set_mode(struct drm_crtc *crtc)  		case DRM_FORMAT_XBGR8888:  		case DRM_FORMAT_XRGB8888:  			reg |= LCDC_V2_TFT_24BPP_UNPACK; -			/* fallthrough */ +			fallthrough;  		case DRM_FORMAT_BGR888:  		case DRM_FORMAT_RGB888:  			reg |= LCDC_V2_TFT_24BPP_MODE; diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 33526c5df0e8..4732dcc80e11 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -525,7 +525,7 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,  			if (unlikely(ret != 0))  				return ret;  		} -		/* fall through */ +		fallthrough;  	case TTM_PL_TT:  		ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);  		break; diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 551fa31629af..5771bb53ce6a 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -179,21 +179,21 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)  	switch (vsg->state) {  	case dr_via_device_mapped:  		via_unmap_blit_from_device(pdev, vsg); -		/* fall through */ +		fallthrough;  	case dr_via_desc_pages_alloc:  		for (i = 0; i < vsg->num_desc_pages; ++i) {  			if (vsg->desc_pages[i] != NULL)  				free_page((unsigned long)vsg->desc_pages[i]);  		}  		kfree(vsg->desc_pages); -		/* fall through */ +		fallthrough;  	case dr_via_pages_locked:  		unpin_user_pages_dirty_lock(vsg->pages, vsg->num_pages,  					   (vsg->direction == DMA_FROM_DEVICE)); -		/* fall through */ +		fallthrough;  	case dr_via_pages_alloc:  		vfree(vsg->pages); -		/* fall through */ +		fallthrough;  	default:  		vsg->state = dr_via_sg_init;  	} diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c index 013c9e0e412c..cc93a8c9547b 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.c +++ b/drivers/gpu/drm/xen/xen_drm_front.c @@ -649,9 +649,7 @@ static void displback_changed(struct xenbus_device *xb_dev,  	switch (backend_state) {  	case XenbusStateReconfiguring: -		/* fall through */  	case XenbusStateReconfigured: -		/* fall through */  	case XenbusStateInitialised:  		break; @@ -701,7 +699,6 @@ static void displback_changed(struct xenbus_device *xb_dev,  		break;  	case XenbusStateUnknown: -		/* fall through */  	case XenbusStateClosed:  		if (xb_dev->state == XenbusStateClosed)  			break; diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index 39ff95b75357..534daf37c97e 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -18,6 +18,7 @@  #include <drm/drm_probe_helper.h>  #include <xen/balloon.h> +#include <xen/xen.h>  #include "xen_drm_front.h"  #include "xen_drm_front_gem.h" @@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size)  		 * allocate ballooned pages which will be used to map  		 * grant references provided by the backend  		 */ -		ret = alloc_xenballooned_pages(xen_obj->num_pages, -					       xen_obj->pages); +		ret = xen_alloc_unpopulated_pages(xen_obj->num_pages, +					          xen_obj->pages);  		if (ret < 0) {  			DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",  				  xen_obj->num_pages, ret); @@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct drm_gem_object *gem_obj)  	} else {  		if (xen_obj->pages) {  			if (xen_obj->be_alloc) { -				free_xenballooned_pages(xen_obj->num_pages, -							xen_obj->pages); +				xen_free_unpopulated_pages(xen_obj->num_pages, +							   xen_obj->pages);  				gem_free_pages_array(xen_obj);  			} else {  				drm_gem_put_pages(&xen_obj->base, diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig index aa6cd889bd11..b52c6cdfc0b8 100644 --- a/drivers/gpu/drm/xlnx/Kconfig +++ b/drivers/gpu/drm/xlnx/Kconfig @@ -2,6 +2,7 @@ config DRM_ZYNQMP_DPSUB  	tristate "ZynqMP DisplayPort Controller Driver"  	depends on ARCH_ZYNQMP || COMPILE_TEST  	depends on COMMON_CLK && DRM && OF +	depends on DMADEVICES  	select DMA_ENGINE  	select DRM_GEM_CMA_HELPER  	select DRM_KMS_CMA_HELPER diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c index dbcc16721931..34b4075a6a8e 100644 --- a/drivers/gpu/ipu-v3/ipu-dc.c +++ b/drivers/gpu/ipu-v3/ipu-dc.c @@ -141,7 +141,7 @@ static int ipu_bus_format_to_map(u32 fmt)  	switch (fmt) {  	default:  		WARN_ON(1); -		/* fall-through */ +		fallthrough;  	case MEDIA_BUS_FMT_RGB888_1X24:  		return IPU_DC_MAP_RGB24;  	case MEDIA_BUS_FMT_RGB565_1X16:  |