drm fixes for mediatek, amdgpu and i915.

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJbiLmbAAoJEAx081l5xIa+bDwP/0g7rknYVIMDFFw4NQBcyLmT
 yetrdF+/fnIBYRJqDz8kIDMn26ftNvO4qeWSaikN2V5Xt6E8JyVKsMIFKmMP5Amx
 VqZA286vQTvcXAGcMecDQQ4P7LOIC/i2gA3NSp7XGTApbhiYHQM4Xe1O9BBrNCMa
 amA+ZoGKR/eJ3ihs8+VCWeGS+wh+O05LRj41fJXmOMYRL97IsxLX0VTNK3srlrbC
 F8nrfJxwGRqhgB634HXAAnbC8/CsxJZvSIVs5qg2qTVVi13VP+1sCyzvUt5tV9QN
 q2afF3vPtbN4Qvb1WfwZNjsPCDCvWGXBXSTgpvumHsoHaACJUHaf3JOT3HLDNjJ/
 YV9PTZOYLa8R2zQvHsGFjy0eWW5hWJ+FNhOl/bxL3T0+4aoEMCUr+Xf8Bknzicar
 jxpRVU8RU6G2wWBfxgKXSvcPx+1NGaotMNZhFUmiFks2oX9f0luUtYkZ3V9WHN4f
 ke87bHMVqjRHUFlVx8Qrnl01L9b6wlaowuAi9pPOqzOhr9l38ompO9P/MAu7RXUN
 YD5bKCrPVMl6nCjE7viKN13+tBLAbn1khpnRTpMu9ygU+2d4Uxo/+HljN/cXLrYG
 rKtNRq0dI1hBoKxBXtaBsJs3TvdqI8UqwSn2KrDKVZwvLwLasYsXmJVa9UGvBDJB
 8TPc6aupyN/ilDBCBGqJ
 =0BQW
 -----END PGP SIGNATURE-----

Merge tag 'drm-fixes-2018-08-31' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Regular fixes pull:

   - Mediatek has a bunch of fixes to their RDMA and Overlay engines.

   - i915 has some Cannonlake/Geminilake watermark workarounds, LSPCON
     fix, HDCP free fix, audio fix and a ppgtt reference counting fix.

   - amdgpu has some SRIOV, Kasan, memory leaks and other misc fixes"

* tag 'drm-fixes-2018-08-31' of git://anongit.freedesktop.org/drm/drm: (35 commits)
  drm/i915/audio: Hook up component bindings even if displays are disabled
  drm/i915: Increase LSPCON timeout
  drm/i915: Stop holding a ref to the ppgtt from each vma
  drm/i915: Free write_buf that we allocated with kzalloc.
  drm/i915: Fix glk/cnl display w/a #1175
  drm/amdgpu: Need to set moved to true when evict bo
  drm/amdgpu: Remove duplicated power source update
  drm/amd/display: Fix memory leak caused by missed dc_sink_release
  drm/amdgpu: fix holding mn_lock while allocating memory
  drm/amdgpu: Power on uvd block when hw_fini
  drm/amdgpu: Update power state at the end of smu hw_init.
  drm/amdgpu: Fix vce initialize failed on Kaveri/Mullins
  drm/amdgpu: Enable/disable gfx PG feature in rlc safe mode
  drm/amdgpu: Adjust the VM size based on system memory size v2
  drm/mediatek: fix connection from RDMA2 to DSI1
  drm/mediatek: update some variable name from ovl to comp
  drm/mediatek: use layer_nr function to get layer number to init plane
  drm/mediatek: add function to return RDMA layer number
  drm/mediatek: add function to return OVL layer number
  drm/mediatek: add function to get layer number for component
  ...
This commit is contained in:
Linus Torvalds 2018-08-30 21:18:05 -07:00
commit 4658aff6ee
26 changed files with 303 additions and 161 deletions

View File

@ -1012,13 +1012,9 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
if (r) if (r)
return r; return r;
if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE) { if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT; parser->job->preamble_status |=
if (!parser->ctx->preamble_presented) { AMDGPU_PREAMBLE_IB_PRESENT;
parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
parser->ctx->preamble_presented = true;
}
}
if (parser->ring && parser->ring != ring) if (parser->ring && parser->ring != ring)
return -EINVAL; return -EINVAL;
@ -1207,26 +1203,24 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
int r; 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_mn_lock(p->mn);
amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
struct amdgpu_bo *bo = e->robj; struct amdgpu_bo *bo = e->robj;
if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
amdgpu_mn_unlock(p->mn); r = -ERESTARTSYS;
return -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; job->owner = p->filp;
p->fence = dma_fence_get(&job->base.s_fence->finished); 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); 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; cs->out.handle = seq;
job->uf_sequence = seq; job->uf_sequence = seq;
@ -1258,6 +1258,15 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_mn_unlock(p->mn); amdgpu_mn_unlock(p->mn);
return 0; 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) int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

View File

@ -164,8 +164,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
return r; return r;
} }
need_ctx_switch = ring->current_ctx != fence_ctx;
if (ring->funcs->emit_pipeline_sync && job && if (ring->funcs->emit_pipeline_sync && job &&
((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) || ((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) ||
(amdgpu_sriov_vf(adev) && need_ctx_switch) ||
amdgpu_vm_need_pipeline_sync(ring, job))) { amdgpu_vm_need_pipeline_sync(ring, job))) {
need_pipe_sync = true; need_pipe_sync = true;
dma_fence_put(tmp); 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; skip_preamble = ring->current_ctx == fence_ctx;
need_ctx_switch = ring->current_ctx != fence_ctx;
if (job && ring->funcs->emit_cntxcntl) { if (job && ring->funcs->emit_cntxcntl) {
if (need_ctx_switch) if (need_ctx_switch)
status |= AMDGPU_HAVE_CTX_SWITCH; status |= AMDGPU_HAVE_CTX_SWITCH;

View File

@ -1932,14 +1932,6 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
amdgpu_fence_wait_empty(ring); 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 (adev->powerplay.pp_funcs->dispatch_tasks) {
if (!amdgpu_device_has_dc_support(adev)) { if (!amdgpu_device_has_dc_support(adev)) {
mutex_lock(&adev->pm.mutex); mutex_lock(&adev->pm.mutex);

View File

@ -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. * is validated on next vm use to avoid fault.
* */ * */
list_move_tail(&base->vm_status, &vm->evicted); 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; uint64_t addr;
int r; int r;
addr = amdgpu_bo_gpu_offset(bo);
entries = amdgpu_bo_size(bo) / 8; entries = amdgpu_bo_size(bo) / 8;
if (pte_support_ats) { if (pte_support_ats) {
@ -401,6 +401,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
if (r) if (r)
goto error; goto error;
addr = amdgpu_bo_gpu_offset(bo);
if (ats_entries) { if (ats_entries) {
uint64_t ats_value; 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 * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
* *
* @adev: amdgpu_device pointer * @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 * @fragment_size_default: Default PTE fragment size
* @max_level: max VMPT level * @max_level: max VMPT level
* @max_bits: max address space size in bits * @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, uint32_t fragment_size_default, unsigned max_level,
unsigned max_bits) unsigned max_bits)
{ {
unsigned int max_size = 1 << (max_bits - 30);
unsigned int vm_size;
uint64_t tmp; uint64_t tmp;
/* adjust vm size first */ /* adjust vm size first */
if (amdgpu_vm_size != -1) { if (amdgpu_vm_size != -1) {
unsigned max_size = 1 << (max_bits - 30);
vm_size = amdgpu_vm_size; vm_size = amdgpu_vm_size;
if (vm_size > max_size) { if (vm_size > max_size) {
dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n", dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",
amdgpu_vm_size, max_size); amdgpu_vm_size, max_size);
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; adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;

View File

@ -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_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va); 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, uint32_t fragment_size_default, unsigned max_level,
unsigned max_bits); unsigned max_bits);
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);

View File

@ -5664,6 +5664,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
return 0; 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) { switch (adev->asic_type) {
case CHIP_CARRIZO: case CHIP_CARRIZO:
case CHIP_STONEY: case CHIP_STONEY:
@ -5713,7 +5718,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
default: default:
break; 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; return 0;
} }

View File

@ -632,12 +632,6 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)
amdgpu_gart_table_vram_unpin(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, static void gmc_v6_0_vm_decode_fault(struct amdgpu_device *adev,
u32 status, u32 addr, u32 mc_client) 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_gem_force_release(adev);
amdgpu_vm_manager_fini(adev); amdgpu_vm_manager_fini(adev);
gmc_v6_0_gart_fini(adev); amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev); amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw); release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL; adev->gmc.fw = NULL;

View File

@ -746,19 +746,6 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
amdgpu_gart_table_vram_unpin(adev); amdgpu_gart_table_vram_unpin(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 * gmc_v7_0_vm_decode_fault - print human readable fault info
* *
@ -1095,8 +1082,9 @@ static int gmc_v7_0_sw_fini(void *handle)
amdgpu_gem_force_release(adev); amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev); amdgpu_vm_manager_fini(adev);
kfree(adev->gmc.vm_fault_info); kfree(adev->gmc.vm_fault_info);
gmc_v7_0_gart_fini(adev); amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev); amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw); release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL; adev->gmc.fw = NULL;

View File

@ -968,19 +968,6 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
amdgpu_gart_table_vram_unpin(adev); amdgpu_gart_table_vram_unpin(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 * gmc_v8_0_vm_decode_fault - print human readable fault info
* *
@ -1199,8 +1186,9 @@ static int gmc_v8_0_sw_fini(void *handle)
amdgpu_gem_force_release(adev); amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev); amdgpu_vm_manager_fini(adev);
kfree(adev->gmc.vm_fault_info); kfree(adev->gmc.vm_fault_info);
gmc_v8_0_gart_fini(adev); amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev); amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw); release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL; adev->gmc.fw = NULL;

View File

@ -942,26 +942,12 @@ static int gmc_v9_0_sw_init(void *handle)
return 0; 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) static int gmc_v9_0_sw_fini(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_gem_force_release(adev); amdgpu_gem_force_release(adev);
amdgpu_vm_manager_fini(adev); amdgpu_vm_manager_fini(adev);
gmc_v9_0_gart_fini(adev);
/* /*
* TODO: * 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_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev); amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
return 0; return 0;
} }

View File

@ -65,8 +65,6 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,
int min_temp, int max_temp); int min_temp, int max_temp);
static int kv_init_fps_limits(struct amdgpu_device *adev); 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_samu(struct amdgpu_device *adev, bool gate);
static void kv_dpm_powergate_acp(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; return ret;
} }
kv_update_current_ps(adev, adev->pm.dpm.boot_ps);
if (adev->irq.installed && if (adev->irq.installed &&
amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) { 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); 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) 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_irq_put(adev, &adev->pm.dpm.thermal.irq,
AMDGPU_THERMAL_IRQ_LOW_TO_HIGH); AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);
amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq, amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
@ -1387,8 +1385,10 @@ static void kv_dpm_disable(struct amdgpu_device *adev)
/* powerup blocks */ /* powerup blocks */
kv_dpm_powergate_acp(adev, false); kv_dpm_powergate_acp(adev, false);
kv_dpm_powergate_samu(adev, false); kv_dpm_powergate_samu(adev, false);
kv_dpm_powergate_vce(adev, false); if (pi->caps_vce_pg) /* power on the VCE block */
kv_dpm_powergate_uvd(adev, false); 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_smc_cac(adev, false);
kv_enable_didt(adev, false); kv_enable_didt(adev, false);
@ -1551,7 +1551,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
int ret; int ret;
if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) { if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) {
kv_dpm_powergate_vce(adev, false);
if (pi->caps_stable_p_state) if (pi->caps_stable_p_state)
pi->vce_boot_level = table->count - 1; pi->vce_boot_level = table->count - 1;
else else
@ -1573,7 +1572,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
kv_enable_vce_dpm(adev, true); kv_enable_vce_dpm(adev, true);
} else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) { } else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {
kv_enable_vce_dpm(adev, false); kv_enable_vce_dpm(adev, false);
kv_dpm_powergate_vce(adev, true);
} }
return 0; 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); struct kv_power_info *pi = kv_get_pi(adev);
int ret;
if (pi->vce_power_gated == gate)
return;
pi->vce_power_gated = gate; pi->vce_power_gated = gate;
if (!pi->caps_vce_pg) if (gate) {
return; /* stop the VCE block */
ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
if (gate) AMD_PG_STATE_GATE);
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); kv_enable_vce_dpm(adev, false);
else if (pi->caps_vce_pg) /* power off the VCE block */
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); 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) static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)
{ {
struct kv_power_info *pi = kv_get_pi(adev); struct kv_power_info *pi = kv_get_pi(adev);
@ -3061,7 +3067,7 @@ static int kv_dpm_hw_init(void *handle)
else else
adev->pm.dpm_enabled = true; adev->pm.dpm_enabled = true;
mutex_unlock(&adev->pm.mutex); mutex_unlock(&adev->pm.mutex);
amdgpu_pm_compute_clocks(adev);
return ret; return ret;
} }
@ -3313,6 +3319,9 @@ static int kv_set_powergating_by_smu(void *handle,
case AMD_IP_BLOCK_TYPE_UVD: case AMD_IP_BLOCK_TYPE_UVD:
kv_dpm_powergate_uvd(handle, gate); kv_dpm_powergate_uvd(handle, gate);
break; break;
case AMD_IP_BLOCK_TYPE_VCE:
kv_dpm_powergate_vce(handle, gate);
break;
default: default:
break; break;
} }

View File

@ -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_enable_auto_throttle_source(adev, AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
si_thermal_start_thermal_controller(adev); si_thermal_start_thermal_controller(adev);
ni_update_current_ps(adev, boot_ps);
return 0; return 0;
} }
@ -7763,7 +7762,7 @@ static int si_dpm_hw_init(void *handle)
else else
adev->pm.dpm_enabled = true; adev->pm.dpm_enabled = true;
mutex_unlock(&adev->pm.mutex); mutex_unlock(&adev->pm.mutex);
amdgpu_pm_compute_clocks(adev);
return ret; return ret;
} }

View File

@ -480,12 +480,20 @@ void pp_rv_set_display_requirement(struct pp_smu *pp,
{ {
struct dc_context *ctx = pp->ctx; struct dc_context *ctx = pp->ctx;
struct amdgpu_device *adev = ctx->driver_context; 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; 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; 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, void pp_rv_set_wm_ranges(struct pp_smu *pp,

View File

@ -754,8 +754,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
* fail-safe mode * fail-safe mode
*/ */
if (dc_is_hdmi_signal(link->connector_signal) || 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; return false;
}
default: default:
break; break;
} }

View File

@ -199,7 +199,6 @@ vma_create(struct drm_i915_gem_object *obj,
vma->flags |= I915_VMA_GGTT; vma->flags |= I915_VMA_GGTT;
list_add(&vma->obj_link, &obj->vma_list); list_add(&vma->obj_link, &obj->vma_list);
} else { } else {
i915_ppgtt_get(i915_vm_to_ppgtt(vm));
list_add_tail(&vma->obj_link, &obj->vma_list); 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) if (vma->obj)
rb_erase(&vma->obj_node, &vma->obj->vma_tree); 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) { rbtree_postorder_for_each_entry_safe(iter, n, &vma->active, node) {
GEM_BUG_ON(i915_gem_active_isset(&iter->base)); GEM_BUG_ON(i915_gem_active_isset(&iter->base));
kfree(iter); kfree(iter);

View File

@ -962,9 +962,6 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv)
{ {
int ret; int ret;
if (INTEL_INFO(dev_priv)->num_pipes == 0)
return;
ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops); ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to add audio component (%d)\n", ret); DRM_ERROR("failed to add audio component (%d)\n", ret);

View File

@ -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 w = drm_rect_width(&plane_state->base.src) >> 16;
int h = drm_rect_height(&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_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 pipe_src_w = crtc_state->pipe_src_w;
int max_width = skl_max_plane_width(fb, 0, rotation); int max_width = skl_max_plane_width(fb, 0, rotation);
int max_height = 4096; 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. * screen may cause FIFO underflow and display corruption.
*/ */
if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && 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", DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
dst_x + w < 4 ? "end" : "start", dst_x + dst_w < 4 ? "end" : "start",
dst_x + w < 4 ? dst_x + w : dst_x, dst_x + dst_w < 4 ? dst_x + dst_w : dst_x,
4, pipe_src_w - 4); 4, pipe_src_w - 4);
return -ERANGE; return -ERANGE;
} }

View File

@ -943,8 +943,12 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *intel_dig_port,
ret = i2c_transfer(adapter, &msg, 1); ret = i2c_transfer(adapter, &msg, 1);
if (ret == 1) if (ret == 1)
return 0; ret = 0;
return ret >= 0 ? -EIO : ret; else if (ret >= 0)
ret = -EIO;
kfree(write_buf);
return ret;
} }
static static

View File

@ -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", DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode)); 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) if (current_mode != mode)
DRM_ERROR("LSPCON mode hasn't settled\n"); DRM_ERROR("LSPCON mode hasn't settled\n");

View File

@ -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); 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) static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
{ {
unsigned int reg; 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) 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) { switch (fmt) {
default: default:
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
@ -221,6 +231,7 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
.stop = mtk_ovl_stop, .stop = mtk_ovl_stop,
.enable_vblank = mtk_ovl_enable_vblank, .enable_vblank = mtk_ovl_enable_vblank,
.disable_vblank = mtk_ovl_disable_vblank, .disable_vblank = mtk_ovl_disable_vblank,
.layer_nr = mtk_ovl_layer_nr,
.layer_on = mtk_ovl_layer_on, .layer_on = mtk_ovl_layer_on,
.layer_off = mtk_ovl_layer_off, .layer_off = mtk_ovl_layer_off,
.layer_config = mtk_ovl_layer_config, .layer_config = mtk_ovl_layer_config,

View File

@ -31,14 +31,31 @@
#define RDMA_REG_UPDATE_INT BIT(0) #define RDMA_REG_UPDATE_INT BIT(0)
#define DISP_REG_RDMA_GLOBAL_CON 0x0010 #define DISP_REG_RDMA_GLOBAL_CON 0x0010
#define RDMA_ENGINE_EN BIT(0) #define RDMA_ENGINE_EN BIT(0)
#define RDMA_MODE_MEMORY BIT(1)
#define DISP_REG_RDMA_SIZE_CON_0 0x0014 #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_SIZE_CON_1 0x0018
#define DISP_REG_RDMA_TARGET_LINE 0x001c #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 DISP_REG_RDMA_FIFO_CON 0x0040
#define RDMA_FIFO_UNDERFLOW_EN BIT(31) #define RDMA_FIFO_UNDERFLOW_EN BIT(31)
#define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
#define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16)
#define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size) #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 { struct mtk_disp_rdma_data {
unsigned int fifo_size; 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); 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 = { static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
.config = mtk_rdma_config, .config = mtk_rdma_config,
.start = mtk_rdma_start, .start = mtk_rdma_start,
.stop = mtk_rdma_stop, .stop = mtk_rdma_stop,
.enable_vblank = mtk_rdma_enable_vblank, .enable_vblank = mtk_rdma_enable_vblank,
.disable_vblank = mtk_rdma_disable_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, static int mtk_disp_rdma_bind(struct device *dev, struct device *master,

View File

@ -45,7 +45,8 @@ struct mtk_drm_crtc {
bool pending_needs_vblank; bool pending_needs_vblank;
struct drm_pending_vblank_event *event; struct drm_pending_vblank_event *event;
struct drm_plane planes[OVL_LAYER_NR]; struct drm_plane *planes;
unsigned int layer_nr;
bool pending_planes; bool pending_planes;
void __iomem *config_regs; 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) static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_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; 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) static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_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) 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 */ /* 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 drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state; 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_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); 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; unsigned int i;
/* /*
@ -343,7 +344,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
* queue update module registers on vblank. * queue update module registers on vblank.
*/ */
if (state->pending_config) { 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_height,
state->pending_vrefresh, 0); state->pending_vrefresh, 0);
@ -351,14 +352,14 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
} }
if (mtk_crtc->pending_planes) { 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 drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state; struct mtk_plane_state *plane_state;
plane_state = to_mtk_plane_state(plane->state); plane_state = to_mtk_plane_state(plane->state);
if (plane_state->pending.config) { 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; 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 drm_crtc_state *old_state)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_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];
int ret; int ret;
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); 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) { if (ret) {
DRM_ERROR("Failed to get larb: %d\n", ret); DRM_ERROR("Failed to get larb: %d\n", ret);
return; return;
@ -383,7 +384,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
ret = mtk_crtc_ddp_hw_init(mtk_crtc); ret = mtk_crtc_ddp_hw_init(mtk_crtc);
if (ret) { if (ret) {
mtk_smi_larb_put(ovl->larb_dev); mtk_smi_larb_put(comp->larb_dev);
return; return;
} }
@ -395,7 +396,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state) struct drm_crtc_state *old_state)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_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];
int i; int i;
DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); 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; return;
/* Set all pending plane state to disabled */ /* 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 drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state; 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); drm_crtc_vblank_off(crtc);
mtk_crtc_ddp_hw_fini(mtk_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; mtk_crtc->enabled = false;
} }
@ -450,7 +451,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
if (mtk_crtc->event) if (mtk_crtc->event)
mtk_crtc->pending_needs_vblank = true; 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 drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state; struct mtk_plane_state *plane_state;
@ -516,7 +517,7 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
return ret; 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_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private; 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; 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 : type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
(zpos == 1) ? DRM_PLANE_TYPE_CURSOR : (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
DRM_PLANE_TYPE_OVERLAY; 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], 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) if (ret < 0)
goto unprepare; goto unprepare;
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);

View File

@ -18,13 +18,12 @@
#include "mtk_drm_ddp_comp.h" #include "mtk_drm_ddp_comp.h"
#include "mtk_drm_plane.h" #include "mtk_drm_plane.h"
#define OVL_LAYER_NR 4
#define MTK_LUT_SIZE 512 #define MTK_LUT_SIZE 512
#define MTK_MAX_BPC 10 #define MTK_MAX_BPC 10
#define MTK_MIN_BPC 3 #define MTK_MIN_BPC 3
void mtk_drm_crtc_commit(struct drm_crtc *crtc); 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, int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path, const enum mtk_ddp_comp_id *path,
unsigned int path_len); unsigned int path_len);

View File

@ -106,6 +106,8 @@
#define OVL1_MOUT_EN_COLOR1 0x1 #define OVL1_MOUT_EN_COLOR1 0x1
#define GAMMA_MOUT_EN_RDMA1 0x1 #define GAMMA_MOUT_EN_RDMA1 0x1
#define RDMA0_SOUT_DPI0 0x2 #define RDMA0_SOUT_DPI0 0x2
#define RDMA0_SOUT_DPI1 0x3
#define RDMA0_SOUT_DSI1 0x1
#define RDMA0_SOUT_DSI2 0x4 #define RDMA0_SOUT_DSI2 0x4
#define RDMA0_SOUT_DSI3 0x5 #define RDMA0_SOUT_DSI3 0x5
#define RDMA1_SOUT_DPI0 0x2 #define RDMA1_SOUT_DPI0 0x2
@ -122,6 +124,8 @@
#define DPI0_SEL_IN_RDMA2 0x3 #define DPI0_SEL_IN_RDMA2 0x3
#define DPI1_SEL_IN_RDMA1 (0x1 << 8) #define DPI1_SEL_IN_RDMA1 (0x1 << 8)
#define DPI1_SEL_IN_RDMA2 (0x3 << 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_RDMA1 0x1
#define DSI1_SEL_IN_RDMA2 0x4 #define DSI1_SEL_IN_RDMA2 0x4
#define DSI2_SEL_IN_RDMA1 (0x1 << 16) #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) { } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
value = RDMA0_SOUT_DPI0; 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) { } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
*addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN; *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
value = RDMA0_SOUT_DSI2; 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) { } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
*addr = DISP_REG_CONFIG_DPI_SEL_IN; *addr = DISP_REG_CONFIG_DPI_SEL_IN;
value = DPI1_SEL_IN_RDMA1; 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) { } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
*addr = DISP_REG_CONFIG_DSIO_SEL_IN; *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
value = DSI1_SEL_IN_RDMA1; 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) { } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
*addr = DISP_REG_CONFIG_DPI_SEL_IN; *addr = DISP_REG_CONFIG_DPI_SEL_IN;
value = DPI1_SEL_IN_RDMA2; 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; *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; value = DSI1_SEL_IN_RDMA2;
} else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) { } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
*addr = DISP_REG_CONFIG_DSIE_SEL_IN; *addr = DISP_REG_CONFIG_DSIE_SEL_IN;

View File

@ -78,6 +78,7 @@ struct mtk_ddp_comp_funcs {
void (*stop)(struct mtk_ddp_comp *comp); void (*stop)(struct mtk_ddp_comp *comp);
void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc); void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
void (*disable_vblank)(struct mtk_ddp_comp *comp); 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_on)(struct mtk_ddp_comp *comp, unsigned int idx);
void (*layer_off)(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, 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); 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, static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,
unsigned int idx) unsigned int idx)
{ {

View File

@ -381,7 +381,7 @@ static int mtk_drm_bind(struct device *dev)
err_deinit: err_deinit:
mtk_drm_kms_deinit(drm); mtk_drm_kms_deinit(drm);
err_free: err_free:
drm_dev_unref(drm); drm_dev_put(drm);
return ret; return ret;
} }
@ -390,7 +390,7 @@ static void mtk_drm_unbind(struct device *dev)
struct mtk_drm_private *private = dev_get_drvdata(dev); struct mtk_drm_private *private = dev_get_drvdata(dev);
drm_dev_unregister(private->drm); drm_dev_unregister(private->drm);
drm_dev_unref(private->drm); drm_dev_put(private->drm);
private->drm = NULL; private->drm = NULL;
} }
@ -564,7 +564,7 @@ static int mtk_drm_remove(struct platform_device *pdev)
drm_dev_unregister(drm); drm_dev_unregister(drm);
mtk_drm_kms_deinit(drm); mtk_drm_kms_deinit(drm);
drm_dev_unref(drm); drm_dev_put(drm);
component_master_del(&pdev->dev, &mtk_drm_ops); component_master_del(&pdev->dev, &mtk_drm_ops);
pm_runtime_disable(&pdev->dev); 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 mtk_drm_private *private = dev_get_drvdata(dev);
struct drm_device *drm = private->drm; struct drm_device *drm = private->drm;
int ret;
drm_kms_helper_poll_disable(drm); ret = drm_mode_config_helper_suspend(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);
}
DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n"); DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n");
return 0;
return ret;
} }
static int mtk_drm_sys_resume(struct device *dev) static int mtk_drm_sys_resume(struct device *dev)
{ {
struct mtk_drm_private *private = dev_get_drvdata(dev); struct mtk_drm_private *private = dev_get_drvdata(dev);
struct drm_device *drm = private->drm; struct drm_device *drm = private->drm;
int ret;
drm_atomic_helper_resume(drm, private->suspend_state); ret = drm_mode_config_helper_resume(drm);
drm_kms_helper_poll_enable(drm);
DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n"); DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n");
return 0;
return ret;
} }
#endif #endif