diff options
Diffstat (limited to 'drivers/gpu')
26 files changed, 303 insertions, 161 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 502b94fb116a..b6e9df11115d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1012,13 +1012,9 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,  		if (r)  			return r; -		if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE) { -			parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT; -			if (!parser->ctx->preamble_presented) { -				parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST; -				parser->ctx->preamble_presented = true; -			} -		} +		if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE) +			parser->job->preamble_status |= +				AMDGPU_PREAMBLE_IB_PRESENT;  		if (parser->ring && parser->ring != ring)  			return -EINVAL; @@ -1207,26 +1203,24 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,  	int r; +	job = p->job; +	p->job = NULL; + +	r = drm_sched_job_init(&job->base, entity, p->filp); +	if (r) +		goto error_unlock; + +	/* No memory allocation is allowed while holding the mn lock */  	amdgpu_mn_lock(p->mn);  	amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {  		struct amdgpu_bo *bo = e->robj;  		if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { -			amdgpu_mn_unlock(p->mn); -			return -ERESTARTSYS; +			r = -ERESTARTSYS; +			goto error_abort;  		}  	} -	job = p->job; -	p->job = NULL; - -	r = drm_sched_job_init(&job->base, entity, p->filp); -	if (r) { -		amdgpu_job_free(job); -		amdgpu_mn_unlock(p->mn); -		return r; -	} -  	job->owner = p->filp;  	p->fence = dma_fence_get(&job->base.s_fence->finished); @@ -1241,6 +1235,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,  	amdgpu_cs_post_dependencies(p); +	if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) && +	    !p->ctx->preamble_presented) { +		job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST; +		p->ctx->preamble_presented = true; +	} +  	cs->out.handle = seq;  	job->uf_sequence = seq; @@ -1258,6 +1258,15 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,  	amdgpu_mn_unlock(p->mn);  	return 0; + +error_abort: +	dma_fence_put(&job->base.s_fence->finished); +	job->base.s_fence = NULL; + +error_unlock: +	amdgpu_job_free(job); +	amdgpu_mn_unlock(p->mn); +	return r;  }  int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 5518e623fed2..51b5e977ca88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -164,8 +164,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,  		return r;  	} +	need_ctx_switch = ring->current_ctx != fence_ctx;  	if (ring->funcs->emit_pipeline_sync && job &&  	    ((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) || +	     (amdgpu_sriov_vf(adev) && need_ctx_switch) ||  	     amdgpu_vm_need_pipeline_sync(ring, job))) {  		need_pipe_sync = true;  		dma_fence_put(tmp); @@ -196,7 +198,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,  	}  	skip_preamble = ring->current_ctx == fence_ctx; -	need_ctx_switch = ring->current_ctx != fence_ctx;  	if (job && ring->funcs->emit_cntxcntl) {  		if (need_ctx_switch)  			status |= AMDGPU_HAVE_CTX_SWITCH; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 8f98629fbe59..7b4e657a95c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1932,14 +1932,6 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)  			amdgpu_fence_wait_empty(ring);  	} -	mutex_lock(&adev->pm.mutex); -	/* update battery/ac status */ -	if (power_supply_is_system_supplied() > 0) -		adev->pm.ac_power = true; -	else -		adev->pm.ac_power = false; -	mutex_unlock(&adev->pm.mutex); -  	if (adev->powerplay.pp_funcs->dispatch_tasks) {  		if (!amdgpu_device_has_dc_support(adev)) {  			mutex_lock(&adev->pm.mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ece0ac703e27..b17771dd5ce7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -172,6 +172,7 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,  	 * is validated on next vm use to avoid fault.  	 * */  	list_move_tail(&base->vm_status, &vm->evicted); +	base->moved = true;  }  /** @@ -369,7 +370,6 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,  	uint64_t addr;  	int r; -	addr = amdgpu_bo_gpu_offset(bo);  	entries = amdgpu_bo_size(bo) / 8;  	if (pte_support_ats) { @@ -401,6 +401,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,  	if (r)  		goto error; +	addr = amdgpu_bo_gpu_offset(bo);  	if (ats_entries) {  		uint64_t ats_value; @@ -2483,28 +2484,52 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)   * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size   *   * @adev: amdgpu_device pointer - * @vm_size: the default vm size if it's set auto + * @min_vm_size: the minimum vm size in GB if it's set auto   * @fragment_size_default: Default PTE fragment size   * @max_level: max VMPT level   * @max_bits: max address space size in bits   *   */ -void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, +void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,  			   uint32_t fragment_size_default, unsigned max_level,  			   unsigned max_bits)  { +	unsigned int max_size = 1 << (max_bits - 30); +	unsigned int vm_size;  	uint64_t tmp;  	/* adjust vm size first */  	if (amdgpu_vm_size != -1) { -		unsigned max_size = 1 << (max_bits - 30); -  		vm_size = amdgpu_vm_size;  		if (vm_size > max_size) {  			dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",  				 amdgpu_vm_size, max_size);  			vm_size = max_size;  		} +	} else { +		struct sysinfo si; +		unsigned int phys_ram_gb; + +		/* Optimal VM size depends on the amount of physical +		 * RAM available. Underlying requirements and +		 * assumptions: +		 * +		 *  - Need to map system memory and VRAM from all GPUs +		 *     - VRAM from other GPUs not known here +		 *     - Assume VRAM <= system memory +		 *  - On GFX8 and older, VM space can be segmented for +		 *    different MTYPEs +		 *  - Need to allow room for fragmentation, guard pages etc. +		 * +		 * This adds up to a rough guess of system memory x3. +		 * Round up to power of two to maximize the available +		 * VM size with the given page table size. +		 */ +		si_meminfo(&si); +		phys_ram_gb = ((uint64_t)si.totalram * si.mem_unit + +			       (1 << 30) - 1) >> 30; +		vm_size = roundup_pow_of_two( +			min(max(phys_ram_gb * 3, min_vm_size), max_size));  	}  	adev->vm_manager.max_pfn = (uint64_t)vm_size << 18; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 67a15d439ac0..9fa9df0c5e7f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -321,7 +321,7 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,  void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);  void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,  		      struct amdgpu_bo_va *bo_va); -void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, +void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,  			   uint32_t fragment_size_default, unsigned max_level,  			   unsigned max_bits);  int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 5cd45210113f..5a9534a82d40 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -5664,6 +5664,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,  	if (amdgpu_sriov_vf(adev))  		return 0; +	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG | +				AMD_PG_SUPPORT_RLC_SMU_HS | +				AMD_PG_SUPPORT_CP | +				AMD_PG_SUPPORT_GFX_DMG)) +		adev->gfx.rlc.funcs->enter_safe_mode(adev);  	switch (adev->asic_type) {  	case CHIP_CARRIZO:  	case CHIP_STONEY: @@ -5713,7 +5718,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,  	default:  		break;  	} - +	if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG | +				AMD_PG_SUPPORT_RLC_SMU_HS | +				AMD_PG_SUPPORT_CP | +				AMD_PG_SUPPORT_GFX_DMG)) +		adev->gfx.rlc.funcs->exit_safe_mode(adev);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 75317f283c69..ad151fefa41f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -632,12 +632,6 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)  	amdgpu_gart_table_vram_unpin(adev);  } -static void gmc_v6_0_gart_fini(struct amdgpu_device *adev) -{ -	amdgpu_gart_table_vram_free(adev); -	amdgpu_gart_fini(adev); -} -  static void gmc_v6_0_vm_decode_fault(struct amdgpu_device *adev,  				     u32 status, u32 addr, u32 mc_client)  { @@ -935,8 +929,9 @@ static int gmc_v6_0_sw_fini(void *handle)  	amdgpu_gem_force_release(adev);  	amdgpu_vm_manager_fini(adev); -	gmc_v6_0_gart_fini(adev); +	amdgpu_gart_table_vram_free(adev);  	amdgpu_bo_fini(adev); +	amdgpu_gart_fini(adev);  	release_firmware(adev->gmc.fw);  	adev->gmc.fw = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 36dc367c4b45..f8d8a3a73e42 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -747,19 +747,6 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)  }  /** - * gmc_v7_0_gart_fini - vm fini callback - * - * @adev: amdgpu_device pointer - * - * Tears down the driver GART/VM setup (CIK). - */ -static void gmc_v7_0_gart_fini(struct amdgpu_device *adev) -{ -	amdgpu_gart_table_vram_free(adev); -	amdgpu_gart_fini(adev); -} - -/**   * gmc_v7_0_vm_decode_fault - print human readable fault info   *   * @adev: amdgpu_device pointer @@ -1095,8 +1082,9 @@ static int gmc_v7_0_sw_fini(void *handle)  	amdgpu_gem_force_release(adev);  	amdgpu_vm_manager_fini(adev);  	kfree(adev->gmc.vm_fault_info); -	gmc_v7_0_gart_fini(adev); +	amdgpu_gart_table_vram_free(adev);  	amdgpu_bo_fini(adev); +	amdgpu_gart_fini(adev);  	release_firmware(adev->gmc.fw);  	adev->gmc.fw = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 70fc97b59b4f..9333109b210d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -969,19 +969,6 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)  }  /** - * gmc_v8_0_gart_fini - vm fini callback - * - * @adev: amdgpu_device pointer - * - * Tears down the driver GART/VM setup (CIK). - */ -static void gmc_v8_0_gart_fini(struct amdgpu_device *adev) -{ -	amdgpu_gart_table_vram_free(adev); -	amdgpu_gart_fini(adev); -} - -/**   * gmc_v8_0_vm_decode_fault - print human readable fault info   *   * @adev: amdgpu_device pointer @@ -1199,8 +1186,9 @@ static int gmc_v8_0_sw_fini(void *handle)  	amdgpu_gem_force_release(adev);  	amdgpu_vm_manager_fini(adev);  	kfree(adev->gmc.vm_fault_info); -	gmc_v8_0_gart_fini(adev); +	amdgpu_gart_table_vram_free(adev);  	amdgpu_bo_fini(adev); +	amdgpu_gart_fini(adev);  	release_firmware(adev->gmc.fw);  	adev->gmc.fw = NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 399a5db27649..72f8018fa2a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -942,26 +942,12 @@ static int gmc_v9_0_sw_init(void *handle)  	return 0;  } -/** - * gmc_v9_0_gart_fini - vm fini callback - * - * @adev: amdgpu_device pointer - * - * Tears down the driver GART/VM setup (CIK). - */ -static void gmc_v9_0_gart_fini(struct amdgpu_device *adev) -{ -	amdgpu_gart_table_vram_free(adev); -	amdgpu_gart_fini(adev); -} -  static int gmc_v9_0_sw_fini(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	amdgpu_gem_force_release(adev);  	amdgpu_vm_manager_fini(adev); -	gmc_v9_0_gart_fini(adev);  	/*  	* TODO: @@ -974,7 +960,9 @@ static int gmc_v9_0_sw_fini(void *handle)  	*/  	amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL); +	amdgpu_gart_table_vram_free(adev);  	amdgpu_bo_fini(adev); +	amdgpu_gart_fini(adev);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 3f57f6463dc8..cb79a93c2eb7 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -65,8 +65,6 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,  					    int min_temp, int max_temp);  static int kv_init_fps_limits(struct amdgpu_device *adev); -static void kv_dpm_powergate_uvd(void *handle, bool gate); -static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate);  static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate);  static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate); @@ -1354,8 +1352,6 @@ static int kv_dpm_enable(struct amdgpu_device *adev)  		return ret;  	} -	kv_update_current_ps(adev, adev->pm.dpm.boot_ps); -  	if (adev->irq.installed &&  	    amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) {  		ret = kv_set_thermal_temperature_range(adev, KV_TEMP_RANGE_MIN, KV_TEMP_RANGE_MAX); @@ -1374,6 +1370,8 @@ static int kv_dpm_enable(struct amdgpu_device *adev)  static void kv_dpm_disable(struct amdgpu_device *adev)  { +	struct kv_power_info *pi = kv_get_pi(adev); +  	amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,  		       AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);  	amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq, @@ -1387,8 +1385,10 @@ static void kv_dpm_disable(struct amdgpu_device *adev)  	/* powerup blocks */  	kv_dpm_powergate_acp(adev, false);  	kv_dpm_powergate_samu(adev, false); -	kv_dpm_powergate_vce(adev, false); -	kv_dpm_powergate_uvd(adev, false); +	if (pi->caps_vce_pg) /* power on the VCE block */ +		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +	if (pi->caps_uvd_pg) /* power on the UVD block */ +		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerON);  	kv_enable_smc_cac(adev, false);  	kv_enable_didt(adev, false); @@ -1551,7 +1551,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,  	int ret;  	if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) { -		kv_dpm_powergate_vce(adev, false);  		if (pi->caps_stable_p_state)  			pi->vce_boot_level = table->count - 1;  		else @@ -1573,7 +1572,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,  		kv_enable_vce_dpm(adev, true);  	} else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {  		kv_enable_vce_dpm(adev, false); -		kv_dpm_powergate_vce(adev, true);  	}  	return 0; @@ -1702,24 +1700,32 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate)  	}  } -static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate) +static void kv_dpm_powergate_vce(void *handle, bool gate)  { +	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	struct kv_power_info *pi = kv_get_pi(adev); - -	if (pi->vce_power_gated == gate) -		return; +	int ret;  	pi->vce_power_gated = gate; -	if (!pi->caps_vce_pg) -		return; - -	if (gate) -		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); -	else -		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +	if (gate) { +		/* stop the VCE block */ +		ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, +							     AMD_PG_STATE_GATE); +		kv_enable_vce_dpm(adev, false); +		if (pi->caps_vce_pg) /* power off the VCE block */ +			amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); +	} else { +		if (pi->caps_vce_pg) /* power on the VCE block */ +			amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +		kv_enable_vce_dpm(adev, true); +		/* re-init the VCE block */ +		ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, +							     AMD_PG_STATE_UNGATE); +	}  } +  static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)  {  	struct kv_power_info *pi = kv_get_pi(adev); @@ -3061,7 +3067,7 @@ static int kv_dpm_hw_init(void *handle)  	else  		adev->pm.dpm_enabled = true;  	mutex_unlock(&adev->pm.mutex); - +	amdgpu_pm_compute_clocks(adev);  	return ret;  } @@ -3313,6 +3319,9 @@ static int kv_set_powergating_by_smu(void *handle,  	case AMD_IP_BLOCK_TYPE_UVD:  		kv_dpm_powergate_uvd(handle, gate);  		break; +	case AMD_IP_BLOCK_TYPE_VCE: +		kv_dpm_powergate_vce(handle, gate); +		break;  	default:  		break;  	} diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index db327b412562..1de96995e690 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -6887,7 +6887,6 @@ static int si_dpm_enable(struct amdgpu_device *adev)  	si_enable_auto_throttle_source(adev, AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL, true);  	si_thermal_start_thermal_controller(adev); -	ni_update_current_ps(adev, boot_ps);  	return 0;  } @@ -7763,7 +7762,7 @@ static int si_dpm_hw_init(void *handle)  	else  		adev->pm.dpm_enabled = true;  	mutex_unlock(&adev->pm.mutex); - +	amdgpu_pm_compute_clocks(adev);  	return ret;  } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c index fbe878ae1e8c..4ba0003a9d32 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -480,12 +480,20 @@ void pp_rv_set_display_requirement(struct pp_smu *pp,  {  	struct dc_context *ctx = pp->ctx;  	struct amdgpu_device *adev = ctx->driver_context; +	void *pp_handle = adev->powerplay.pp_handle;  	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; +	struct pp_display_clock_request clock = {0}; -	if (!pp_funcs || !pp_funcs->display_configuration_changed) +	if (!pp_funcs || !pp_funcs->display_clock_voltage_request)  		return; -	amdgpu_dpm_display_configuration_changed(adev); +	clock.clock_type = amd_pp_dcf_clock; +	clock.clock_freq_in_khz = req->hard_min_dcefclk_khz; +	pp_funcs->display_clock_voltage_request(pp_handle, &clock); + +	clock.clock_type = amd_pp_f_clock; +	clock.clock_freq_in_khz = req->hard_min_fclk_khz; +	pp_funcs->display_clock_voltage_request(pp_handle, &clock);  }  void pp_rv_set_wm_ranges(struct pp_smu *pp, 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 567867915d32..37eaf72ace54 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -754,8 +754,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)  			 * fail-safe mode  			 */  			if (dc_is_hdmi_signal(link->connector_signal) || -			    dc_is_dvi_signal(link->connector_signal)) +			    dc_is_dvi_signal(link->connector_signal)) { +				if (prev_sink != NULL) +					dc_sink_release(prev_sink); +  				return false; +			}  		default:  			break;  		} diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 11d834f94220..98358b4b36de 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -199,7 +199,6 @@ vma_create(struct drm_i915_gem_object *obj,  		vma->flags |= I915_VMA_GGTT;  		list_add(&vma->obj_link, &obj->vma_list);  	} else { -		i915_ppgtt_get(i915_vm_to_ppgtt(vm));  		list_add_tail(&vma->obj_link, &obj->vma_list);  	} @@ -807,9 +806,6 @@ static void __i915_vma_destroy(struct i915_vma *vma)  	if (vma->obj)  		rb_erase(&vma->obj_node, &vma->obj->vma_tree); -	if (!i915_vma_is_ggtt(vma)) -		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm)); -  	rbtree_postorder_for_each_entry_safe(iter, n, &vma->active, node) {  		GEM_BUG_ON(i915_gem_active_isset(&iter->base));  		kfree(iter); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index b725835b47ef..769f3f586661 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -962,9 +962,6 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv)  {  	int ret; -	if (INTEL_INFO(dev_priv)->num_pipes == 0) -		return; -  	ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops);  	if (ret < 0) {  		DRM_ERROR("failed to add audio component (%d)\n", ret); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ed3fa1c8a983..4a3c8ee9a973 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2988,6 +2988,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,  	int w = drm_rect_width(&plane_state->base.src) >> 16;  	int h = drm_rect_height(&plane_state->base.src) >> 16;  	int dst_x = plane_state->base.dst.x1; +	int dst_w = drm_rect_width(&plane_state->base.dst);  	int pipe_src_w = crtc_state->pipe_src_w;  	int max_width = skl_max_plane_width(fb, 0, rotation);  	int max_height = 4096; @@ -3009,10 +3010,10 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,  	 * screen may cause FIFO underflow and display corruption.  	 */  	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && -	    (dst_x + w < 4 || dst_x > pipe_src_w - 4)) { +	    (dst_x + dst_w < 4 || dst_x > pipe_src_w - 4)) {  		DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n", -			      dst_x + w < 4 ? "end" : "start", -			      dst_x + w < 4 ? dst_x + w : dst_x, +			      dst_x + dst_w < 4 ? "end" : "start", +			      dst_x + dst_w < 4 ? dst_x + dst_w : dst_x,  			      4, pipe_src_w - 4);  		return -ERANGE;  	} diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a9076402dcb0..192972a7d287 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -943,8 +943,12 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *intel_dig_port,  	ret = i2c_transfer(adapter, &msg, 1);  	if (ret == 1) -		return 0; -	return ret >= 0 ? -EIO : ret; +		ret = 0; +	else if (ret >= 0) +		ret = -EIO; + +	kfree(write_buf); +	return ret;  }  static diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 5dae16ccd9f1..3e085c5f2b81 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -74,7 +74,7 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,  	DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",  		      lspcon_mode_name(mode)); -	wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 100); +	wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);  	if (current_mode != mode)  		DRM_ERROR("LSPCON mode hasn't settled\n"); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 978782a77629..28d191192945 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -132,6 +132,11 @@ static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,  	writel(0x0, comp->regs + DISP_REG_OVL_RST);  } +static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp) +{ +	return 4; +} +  static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)  {  	unsigned int reg; @@ -157,6 +162,11 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)  static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)  { +	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" +	 * is defined in mediatek HW data sheet. +	 * The alphabet order in XXX is no relation to data +	 * arrangement in memory. +	 */  	switch (fmt) {  	default:  	case DRM_FORMAT_RGB565: @@ -221,6 +231,7 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {  	.stop = mtk_ovl_stop,  	.enable_vblank = mtk_ovl_enable_vblank,  	.disable_vblank = mtk_ovl_disable_vblank, +	.layer_nr = mtk_ovl_layer_nr,  	.layer_on = mtk_ovl_layer_on,  	.layer_off = mtk_ovl_layer_off,  	.layer_config = mtk_ovl_layer_config, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 585943c81e1f..b0a5cffe345a 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -31,14 +31,31 @@  #define RDMA_REG_UPDATE_INT				BIT(0)  #define DISP_REG_RDMA_GLOBAL_CON		0x0010  #define RDMA_ENGINE_EN					BIT(0) +#define RDMA_MODE_MEMORY				BIT(1)  #define DISP_REG_RDMA_SIZE_CON_0		0x0014 +#define RDMA_MATRIX_ENABLE				BIT(17) +#define RDMA_MATRIX_INT_MTX_SEL				GENMASK(23, 20) +#define RDMA_MATRIX_INT_MTX_BT601_to_RGB		(6 << 20)  #define DISP_REG_RDMA_SIZE_CON_1		0x0018  #define DISP_REG_RDMA_TARGET_LINE		0x001c +#define DISP_RDMA_MEM_CON			0x0024 +#define MEM_MODE_INPUT_FORMAT_RGB565			(0x000 << 4) +#define MEM_MODE_INPUT_FORMAT_RGB888			(0x001 << 4) +#define MEM_MODE_INPUT_FORMAT_RGBA8888			(0x002 << 4) +#define MEM_MODE_INPUT_FORMAT_ARGB8888			(0x003 << 4) +#define MEM_MODE_INPUT_FORMAT_UYVY			(0x004 << 4) +#define MEM_MODE_INPUT_FORMAT_YUYV			(0x005 << 4) +#define MEM_MODE_INPUT_SWAP				BIT(8) +#define DISP_RDMA_MEM_SRC_PITCH			0x002c +#define DISP_RDMA_MEM_GMC_SETTING_0		0x0030  #define DISP_REG_RDMA_FIFO_CON			0x0040  #define RDMA_FIFO_UNDERFLOW_EN				BIT(31)  #define RDMA_FIFO_PSEUDO_SIZE(bytes)			(((bytes) / 16) << 16)  #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes)		((bytes) / 16)  #define RDMA_FIFO_SIZE(rdma)			((rdma)->data->fifo_size) +#define DISP_RDMA_MEM_START_ADDR		0x0f00 + +#define RDMA_MEM_GMC				0x40402020  struct mtk_disp_rdma_data {  	unsigned int fifo_size; @@ -138,12 +155,87 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,  	writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);  } +static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma, +				     unsigned int fmt) +{ +	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" +	 * is defined in mediatek HW data sheet. +	 * The alphabet order in XXX is no relation to data +	 * arrangement in memory. +	 */ +	switch (fmt) { +	default: +	case DRM_FORMAT_RGB565: +		return MEM_MODE_INPUT_FORMAT_RGB565; +	case DRM_FORMAT_BGR565: +		return MEM_MODE_INPUT_FORMAT_RGB565 | MEM_MODE_INPUT_SWAP; +	case DRM_FORMAT_RGB888: +		return MEM_MODE_INPUT_FORMAT_RGB888; +	case DRM_FORMAT_BGR888: +		return MEM_MODE_INPUT_FORMAT_RGB888 | MEM_MODE_INPUT_SWAP; +	case DRM_FORMAT_RGBX8888: +	case DRM_FORMAT_RGBA8888: +		return MEM_MODE_INPUT_FORMAT_ARGB8888; +	case DRM_FORMAT_BGRX8888: +	case DRM_FORMAT_BGRA8888: +		return MEM_MODE_INPUT_FORMAT_ARGB8888 | MEM_MODE_INPUT_SWAP; +	case DRM_FORMAT_XRGB8888: +	case DRM_FORMAT_ARGB8888: +		return MEM_MODE_INPUT_FORMAT_RGBA8888; +	case DRM_FORMAT_XBGR8888: +	case DRM_FORMAT_ABGR8888: +		return MEM_MODE_INPUT_FORMAT_RGBA8888 | MEM_MODE_INPUT_SWAP; +	case DRM_FORMAT_UYVY: +		return MEM_MODE_INPUT_FORMAT_UYVY; +	case DRM_FORMAT_YUYV: +		return MEM_MODE_INPUT_FORMAT_YUYV; +	} +} + +static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp) +{ +	return 1; +} + +static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, +				  struct mtk_plane_state *state) +{ +	struct mtk_disp_rdma *rdma = comp_to_rdma(comp); +	struct mtk_plane_pending_state *pending = &state->pending; +	unsigned int addr = pending->addr; +	unsigned int pitch = pending->pitch & 0xffff; +	unsigned int fmt = pending->format; +	unsigned int con; + +	con = rdma_fmt_convert(rdma, fmt); +	writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON); + +	if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) { +		rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, +				 RDMA_MATRIX_ENABLE, RDMA_MATRIX_ENABLE); +		rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, +				 RDMA_MATRIX_INT_MTX_SEL, +				 RDMA_MATRIX_INT_MTX_BT601_to_RGB); +	} else { +		rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, +				 RDMA_MATRIX_ENABLE, 0); +	} + +	writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR); +	writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH); +	writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0); +	rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON, +			 RDMA_MODE_MEMORY, RDMA_MODE_MEMORY); +} +  static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {  	.config = mtk_rdma_config,  	.start = mtk_rdma_start,  	.stop = mtk_rdma_stop,  	.enable_vblank = mtk_rdma_enable_vblank,  	.disable_vblank = mtk_rdma_disable_vblank, +	.layer_nr = mtk_rdma_layer_nr, +	.layer_config = mtk_rdma_layer_config,  };  static int mtk_disp_rdma_bind(struct device *dev, struct device *master, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 2d6aa150a9ff..0b976dfd04df 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -45,7 +45,8 @@ struct mtk_drm_crtc {  	bool				pending_needs_vblank;  	struct drm_pending_vblank_event	*event; -	struct drm_plane		planes[OVL_LAYER_NR]; +	struct drm_plane		*planes; +	unsigned int			layer_nr;  	bool				pending_planes;  	void __iomem			*config_regs; @@ -171,9 +172,9 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)  static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); -	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; +	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; -	mtk_ddp_comp_enable_vblank(ovl, &mtk_crtc->base); +	mtk_ddp_comp_enable_vblank(comp, &mtk_crtc->base);  	return 0;  } @@ -181,9 +182,9 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)  static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); -	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; +	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; -	mtk_ddp_comp_disable_vblank(ovl); +	mtk_ddp_comp_disable_vblank(comp);  }  static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc) @@ -286,7 +287,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)  	}  	/* Initially configure all planes */ -	for (i = 0; i < OVL_LAYER_NR; i++) { +	for (i = 0; i < mtk_crtc->layer_nr; i++) {  		struct drm_plane *plane = &mtk_crtc->planes[i];  		struct mtk_plane_state *plane_state; @@ -334,7 +335,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);  	struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); -	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; +	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];  	unsigned int i;  	/* @@ -343,7 +344,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)  	 * queue update module registers on vblank.  	 */  	if (state->pending_config) { -		mtk_ddp_comp_config(ovl, state->pending_width, +		mtk_ddp_comp_config(comp, state->pending_width,  				    state->pending_height,  				    state->pending_vrefresh, 0); @@ -351,14 +352,14 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)  	}  	if (mtk_crtc->pending_planes) { -		for (i = 0; i < OVL_LAYER_NR; i++) { +		for (i = 0; i < mtk_crtc->layer_nr; i++) {  			struct drm_plane *plane = &mtk_crtc->planes[i];  			struct mtk_plane_state *plane_state;  			plane_state = to_mtk_plane_state(plane->state);  			if (plane_state->pending.config) { -				mtk_ddp_comp_layer_config(ovl, i, plane_state); +				mtk_ddp_comp_layer_config(comp, i, plane_state);  				plane_state->pending.config = false;  			}  		} @@ -370,12 +371,12 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,  				       struct drm_crtc_state *old_state)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); -	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; +	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];  	int ret;  	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); -	ret = mtk_smi_larb_get(ovl->larb_dev); +	ret = mtk_smi_larb_get(comp->larb_dev);  	if (ret) {  		DRM_ERROR("Failed to get larb: %d\n", ret);  		return; @@ -383,7 +384,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,  	ret = mtk_crtc_ddp_hw_init(mtk_crtc);  	if (ret) { -		mtk_smi_larb_put(ovl->larb_dev); +		mtk_smi_larb_put(comp->larb_dev);  		return;  	} @@ -395,7 +396,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,  					struct drm_crtc_state *old_state)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); -	struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; +	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];  	int i;  	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); @@ -403,7 +404,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,  		return;  	/* Set all pending plane state to disabled */ -	for (i = 0; i < OVL_LAYER_NR; i++) { +	for (i = 0; i < mtk_crtc->layer_nr; i++) {  		struct drm_plane *plane = &mtk_crtc->planes[i];  		struct mtk_plane_state *plane_state; @@ -418,7 +419,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,  	drm_crtc_vblank_off(crtc);  	mtk_crtc_ddp_hw_fini(mtk_crtc); -	mtk_smi_larb_put(ovl->larb_dev); +	mtk_smi_larb_put(comp->larb_dev);  	mtk_crtc->enabled = false;  } @@ -450,7 +451,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,  	if (mtk_crtc->event)  		mtk_crtc->pending_needs_vblank = true; -	for (i = 0; i < OVL_LAYER_NR; i++) { +	for (i = 0; i < mtk_crtc->layer_nr; i++) {  		struct drm_plane *plane = &mtk_crtc->planes[i];  		struct mtk_plane_state *plane_state; @@ -516,7 +517,7 @@ err_cleanup_crtc:  	return ret;  } -void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl) +void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)  {  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);  	struct mtk_drm_private *priv = crtc->dev->dev_private; @@ -598,7 +599,12 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  		mtk_crtc->ddp_comp[i] = comp;  	} -	for (zpos = 0; zpos < OVL_LAYER_NR; zpos++) { +	mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]); +	mtk_crtc->planes = devm_kzalloc(dev, mtk_crtc->layer_nr * +					sizeof(struct drm_plane), +					GFP_KERNEL); + +	for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {  		type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :  				(zpos == 1) ? DRM_PLANE_TYPE_CURSOR :  						DRM_PLANE_TYPE_OVERLAY; @@ -609,7 +615,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  	}  	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0], -				&mtk_crtc->planes[1], pipe); +				mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] : +				NULL, pipe);  	if (ret < 0)  		goto unprepare;  	drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h index 9d9410c67ae9..091adb2087eb 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h @@ -18,13 +18,12 @@  #include "mtk_drm_ddp_comp.h"  #include "mtk_drm_plane.h" -#define OVL_LAYER_NR	4  #define MTK_LUT_SIZE	512  #define MTK_MAX_BPC	10  #define MTK_MIN_BPC	3  void mtk_drm_crtc_commit(struct drm_crtc *crtc); -void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl); +void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);  int mtk_drm_crtc_create(struct drm_device *drm_dev,  			const enum mtk_ddp_comp_id *path,  			unsigned int path_len); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c index 87e4191c250e..546b3e3b300b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c @@ -106,6 +106,8 @@  #define OVL1_MOUT_EN_COLOR1		0x1  #define GAMMA_MOUT_EN_RDMA1		0x1  #define RDMA0_SOUT_DPI0			0x2 +#define RDMA0_SOUT_DPI1			0x3 +#define RDMA0_SOUT_DSI1			0x1  #define RDMA0_SOUT_DSI2			0x4  #define RDMA0_SOUT_DSI3			0x5  #define RDMA1_SOUT_DPI0			0x2 @@ -122,6 +124,8 @@  #define DPI0_SEL_IN_RDMA2		0x3  #define DPI1_SEL_IN_RDMA1		(0x1 << 8)  #define DPI1_SEL_IN_RDMA2		(0x3 << 8) +#define DSI0_SEL_IN_RDMA1		0x1 +#define DSI0_SEL_IN_RDMA2		0x4  #define DSI1_SEL_IN_RDMA1		0x1  #define DSI1_SEL_IN_RDMA2		0x4  #define DSI2_SEL_IN_RDMA1		(0x1 << 16) @@ -224,6 +228,12 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,  	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {  		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;  		value = RDMA0_SOUT_DPI0; +	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) { +		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; +		value = RDMA0_SOUT_DPI1; +	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) { +		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; +		value = RDMA0_SOUT_DSI1;  	} else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {  		*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;  		value = RDMA0_SOUT_DSI2; @@ -282,6 +292,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,  	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {  		*addr = DISP_REG_CONFIG_DPI_SEL_IN;  		value = DPI1_SEL_IN_RDMA1; +	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) { +		*addr = DISP_REG_CONFIG_DSIE_SEL_IN; +		value = DSI0_SEL_IN_RDMA1;  	} else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {  		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;  		value = DSI1_SEL_IN_RDMA1; @@ -297,8 +310,11 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,  	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {  		*addr = DISP_REG_CONFIG_DPI_SEL_IN;  		value = DPI1_SEL_IN_RDMA2; -	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) { +	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {  		*addr = DISP_REG_CONFIG_DSIE_SEL_IN; +		value = DSI0_SEL_IN_RDMA2; +	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) { +		*addr = DISP_REG_CONFIG_DSIO_SEL_IN;  		value = DSI1_SEL_IN_RDMA2;  	} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {  		*addr = DISP_REG_CONFIG_DSIE_SEL_IN; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 7413ffeb3c9d..8399229e6ad2 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -78,6 +78,7 @@ struct mtk_ddp_comp_funcs {  	void (*stop)(struct mtk_ddp_comp *comp);  	void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);  	void (*disable_vblank)(struct mtk_ddp_comp *comp); +	unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);  	void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);  	void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);  	void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx, @@ -128,6 +129,14 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)  		comp->funcs->disable_vblank(comp);  } +static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp) +{ +	if (comp->funcs && comp->funcs->layer_nr) +		return comp->funcs->layer_nr(comp); + +	return 0; +} +  static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,  					 unsigned int idx)  { diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 39721119713b..47ec604289b7 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -381,7 +381,7 @@ static int mtk_drm_bind(struct device *dev)  err_deinit:  	mtk_drm_kms_deinit(drm);  err_free: -	drm_dev_unref(drm); +	drm_dev_put(drm);  	return ret;  } @@ -390,7 +390,7 @@ static void mtk_drm_unbind(struct device *dev)  	struct mtk_drm_private *private = dev_get_drvdata(dev);  	drm_dev_unregister(private->drm); -	drm_dev_unref(private->drm); +	drm_dev_put(private->drm);  	private->drm = NULL;  } @@ -564,7 +564,7 @@ static int mtk_drm_remove(struct platform_device *pdev)  	drm_dev_unregister(drm);  	mtk_drm_kms_deinit(drm); -	drm_dev_unref(drm); +	drm_dev_put(drm);  	component_master_del(&pdev->dev, &mtk_drm_ops);  	pm_runtime_disable(&pdev->dev); @@ -580,29 +580,24 @@ static int mtk_drm_sys_suspend(struct device *dev)  {  	struct mtk_drm_private *private = dev_get_drvdata(dev);  	struct drm_device *drm = private->drm; +	int ret; -	drm_kms_helper_poll_disable(drm); - -	private->suspend_state = drm_atomic_helper_suspend(drm); -	if (IS_ERR(private->suspend_state)) { -		drm_kms_helper_poll_enable(drm); -		return PTR_ERR(private->suspend_state); -	} - +	ret = drm_mode_config_helper_suspend(drm);  	DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n"); -	return 0; + +	return ret;  }  static int mtk_drm_sys_resume(struct device *dev)  {  	struct mtk_drm_private *private = dev_get_drvdata(dev);  	struct drm_device *drm = private->drm; +	int ret; -	drm_atomic_helper_resume(drm, private->suspend_state); -	drm_kms_helper_poll_enable(drm); - +	ret = drm_mode_config_helper_resume(drm);  	DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n"); -	return 0; + +	return ret;  }  #endif | 
