Merge origin/master into drm-misc-fixes

Backmerge 4.13-rc5 into drm-misc-fixes, it was getting a
little stale.

Signed-off-by: Sean Paul <[email protected]>
This commit is contained in:
Sean Paul 2017-08-14 13:14:36 -04:00
commit 1724c7c0c9
9803 changed files with 463084 additions and 201803 deletions

View file

@ -1028,12 +1028,15 @@ struct amdgpu_gfx_config {
};
struct amdgpu_cu_info {
uint32_t number; /* total active CU number */
uint32_t ao_cu_mask;
uint32_t max_waves_per_simd;
uint32_t wave_front_size;
uint32_t max_scratch_slots_per_cu;
uint32_t lds_size;
/* total active CU number */
uint32_t number;
uint32_t ao_cu_mask;
uint32_t ao_cu_bitmap[4][4];
uint32_t bitmap[4][4];
};
@ -1924,7 +1927,6 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev);
bool amdgpu_need_post(struct amdgpu_device *adev);
void amdgpu_update_display_priority(struct amdgpu_device *adev);
int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data);
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes);
void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);

View file

@ -101,7 +101,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
if (adev->kfd) {
struct kgd2kfd_shared_resources gpu_resources = {
.compute_vmid_bitmap = 0xFF00,
.num_mec = adev->gfx.mec.num_mec,
.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe
};
@ -122,7 +121,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
/* According to linux/bitmap.h we shouldn't use bitmap_clear if
* nbits is not compile time constant */
last_valid_bit = adev->gfx.mec.num_mec
last_valid_bit = 1 /* only first MEC can have compute queues */
* adev->gfx.mec.num_pipe_per_mec
* adev->gfx.mec.num_queue_per_pipe;
for (i = last_valid_bit; i < KGD_MAX_QUEUES; ++i)

View file

@ -198,12 +198,16 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
result = idr_find(&fpriv->bo_list_handles, id);
if (result) {
if (kref_get_unless_zero(&result->refcount))
if (kref_get_unless_zero(&result->refcount)) {
rcu_read_unlock();
mutex_lock(&result->lock);
else
} else {
rcu_read_unlock();
result = NULL;
}
} else {
rcu_read_unlock();
}
rcu_read_unlock();
return result;
}

View file

@ -838,6 +838,12 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
return -EINVAL;
mode_info = info->mode_info;
if (mode_info) {
/* if the displays are off, vblank time is max */
mode_info->vblank_time_us = 0xffffffff;
/* always set the reference clock */
mode_info->ref_clock = adev->clock.spll.reference_freq;
}
if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc,

View file

@ -64,7 +64,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
return 0;
}
int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
@ -497,7 +497,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
&e->user_invalidated) && e->user_pages) {
/* We acquired a page array, but somebody
* invalidated it. Free it an try again
* invalidated it. Free it and try again
*/
release_pages(e->user_pages,
e->robj->tbo.ttm->num_pages,
@ -1069,10 +1069,8 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
{
int i;
for (i = 0; i < p->num_post_dep_syncobjs; ++i) {
drm_syncobj_replace_fence(p->filp, p->post_dep_syncobjs[i],
p->fence);
}
for (i = 0; i < p->num_post_dep_syncobjs; ++i)
drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
}
static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,

View file

@ -1162,16 +1162,12 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
return;
if (state == VGA_SWITCHEROO_ON) {
unsigned d3_delay = dev->pdev->d3_delay;
pr_info("amdgpu: switched on\n");
/* don't suspend or resume card normally */
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
amdgpu_device_resume(dev, true, true);
dev->pdev->d3_delay = d3_delay;
dev->switch_power_state = DRM_SWITCH_POWER_ON;
drm_kms_helper_poll_enable(dev);
} else {
@ -3804,7 +3800,7 @@ int amdgpu_debugfs_init(struct drm_minor *minor)
return 0;
}
#else
static int amdgpu_debugfs_test_ib_init(struct amdgpu_device *adev)
static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev)
{
return 0;
}

View file

@ -67,9 +67,10 @@
* - 3.15.0 - Export more gpu info for gfx9
* - 3.16.0 - Add reserved vmid support
* - 3.17.0 - Add AMDGPU_NUM_VRAM_CPU_PAGE_FAULTS.
* - 3.18.0 - Export gpu always on cu bitmap
*/
#define KMS_DRIVER_MAJOR 3
#define KMS_DRIVER_MINOR 17
#define KMS_DRIVER_MINOR 18
#define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit = 0;
@ -247,14 +248,28 @@ MODULE_PARM_DESC(lbpw, "Load Balancing Per Watt (LBPW) support (1 = enable, 0 =
module_param_named(lbpw, amdgpu_lbpw, int, 0444);
#ifdef CONFIG_DRM_AMDGPU_SI
#if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
int amdgpu_si_support = 0;
MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))");
#else
int amdgpu_si_support = 1;
MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)");
#endif
module_param_named(si_support, amdgpu_si_support, int, 0444);
#endif
#ifdef CONFIG_DRM_AMDGPU_CIK
#if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
int amdgpu_cik_support = 0;
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))");
#else
int amdgpu_cik_support = 1;
MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)");
#endif
module_param_named(cik_support, amdgpu_cik_support, int, 0444);
#endif

View file

@ -594,6 +594,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.cu_active_number = adev->gfx.cu_info.number;
dev_info.cu_ao_mask = adev->gfx.cu_info.ao_cu_mask;
dev_info.ce_ram_size = adev->gfx.ce_ram_size;
memcpy(&dev_info.cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0],
sizeof(adev->gfx.cu_info.ao_cu_bitmap));
memcpy(&dev_info.cu_bitmap[0], &adev->gfx.cu_info.bitmap[0],
sizeof(adev->gfx.cu_info.bitmap));
dev_info.vram_type = adev->mc.vram_type;

View file

@ -359,7 +359,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo)
head = bo->mn_list.next;
bo->mn = NULL;
list_del(&bo->mn_list);
list_del_init(&bo->mn_list);
if (list_empty(head)) {
struct amdgpu_mn_node *node;

View file

@ -188,6 +188,9 @@ static int amdgpu_pp_hw_fini(void *handle)
int ret = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->pp_enabled && adev->pm.dpm_enabled)
amdgpu_pm_sysfs_fini(adev);
if (adev->powerplay.ip_funcs->hw_fini)
ret = adev->powerplay.ip_funcs->hw_fini(
adev->powerplay.pp_handle);
@ -206,10 +209,9 @@ static void amdgpu_pp_late_fini(void *handle)
adev->powerplay.ip_funcs->late_fini(
adev->powerplay.pp_handle);
if (adev->pp_enabled && adev->pm.dpm_enabled)
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_destroy(adev->powerplay.pp_handle);
if (adev->pp_enabled)
amd_powerplay_destroy(adev->powerplay.pp_handle);
}
static int amdgpu_pp_suspend(void *handle)

View file

@ -152,8 +152,8 @@ static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd,
uint64_t tmr_mc, uint32_t size)
{
cmd->cmd_id = GFX_CMD_ID_SETUP_TMR;
cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = (uint32_t)tmr_mc;
cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = (uint32_t)(tmr_mc >> 32);
cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = lower_32_bits(tmr_mc);
cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = upper_32_bits(tmr_mc);
cmd->cmd.cmd_setup_tmr.buf_size = size;
}
@ -333,14 +333,11 @@ static int psp_load_fw(struct amdgpu_device *adev)
{
int ret;
struct psp_context *psp = &adev->psp;
struct psp_gfx_cmd_resp *cmd;
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
if (!cmd)
psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
if (!psp->cmd)
return -ENOMEM;
psp->cmd = cmd;
ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
AMDGPU_GEM_DOMAIN_GTT,
&psp->fw_pri_bo,
@ -379,8 +376,6 @@ static int psp_load_fw(struct amdgpu_device *adev)
if (ret)
goto failed_mem;
kfree(cmd);
return 0;
failed_mem:
@ -390,7 +385,8 @@ failed_mem1:
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
failed:
kfree(cmd);
kfree(psp->cmd);
psp->cmd = NULL;
return ret;
}
@ -450,6 +446,9 @@ static int psp_hw_fini(void *handle)
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
&psp->fence_buf_mc_addr, &psp->fence_buf);
kfree(psp->cmd);
psp->cmd = NULL;
return 0;
}

View file

@ -1,24 +1,25 @@
/*
***************************************************************************************************
*
* Trade secret of Advanced Micro Devices, Inc.
* Copyright (c) 2010 Advanced Micro Devices, Inc. (unpublished)
*
* All rights reserved. This notice is intended as a precaution against inadvertent publication and
* does not imply publication or any waiver of confidentiality. The year included in the foregoing
* notice is the year of creation of the work.
*
***************************************************************************************************
*/
/**
***************************************************************************************************
* @brief gfx9 Clearstate Definitions
***************************************************************************************************
*
* Do not edit! This is a machine-generated file!
*
*/
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
static const unsigned int gfx9_SECT_CONTEXT_def_1[] =
{

View file

@ -3535,7 +3535,9 @@ static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev)
mask <<= 1;
}
active_cu_number += counter;
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
if (i < 2 && j < 2)
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
cu_info->ao_cu_bitmap[i][j] = ao_bitmap;
}
}

View file

@ -5427,7 +5427,9 @@ static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev)
mask <<= 1;
}
active_cu_number += counter;
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
if (i < 2 && j < 2)
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
cu_info->ao_cu_bitmap[i][j] = ao_bitmap;
}
}
gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);

View file

@ -40,7 +40,6 @@
#include "bif/bif_5_0_d.h"
#include "bif/bif_5_0_sh_mask.h"
#include "gca/gfx_8_0_d.h"
#include "gca/gfx_8_0_enum.h"
#include "gca/gfx_8_0_sh_mask.h"
@ -2100,7 +2099,7 @@ static int gfx_v8_0_sw_init(void *handle)
return r;
/* create MQD for all compute queues as well as KIQ for SRIOV case */
r = amdgpu_gfx_compute_mqd_sw_init(adev, sizeof(struct vi_mqd));
r = amdgpu_gfx_compute_mqd_sw_init(adev, sizeof(struct vi_mqd_allocation));
if (r)
return r;
@ -4637,56 +4636,6 @@ static int gfx_v8_0_kiq_kcq_enable(struct amdgpu_device *adev)
return r;
}
static int gfx_v8_0_kiq_kcq_disable(struct amdgpu_device *adev)
{
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
uint32_t scratch, tmp = 0;
int r, i;
r = amdgpu_gfx_scratch_get(adev, &scratch);
if (r) {
DRM_ERROR("Failed to get scratch reg (%d).\n", r);
return r;
}
WREG32(scratch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(kiq_ring, 6 + 3);
if (r) {
DRM_ERROR("Failed to lock KIQ (%d).\n", r);
amdgpu_gfx_scratch_free(adev, scratch);
return r;
}
/* unmap queues */
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4));
amdgpu_ring_write(kiq_ring,
PACKET3_UNMAP_QUEUES_ACTION(1)| /* RESET_QUEUES */
PACKET3_UNMAP_QUEUES_QUEUE_SEL(2)); /* select all queues */
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
/* write to scratch for completion */
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
amdgpu_ring_write(kiq_ring, (scratch - PACKET3_SET_UCONFIG_REG_START));
amdgpu_ring_write(kiq_ring, 0xDEADBEEF);
amdgpu_ring_commit(kiq_ring);
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(scratch);
if (tmp == 0xDEADBEEF)
break;
DRM_UDELAY(1);
}
if (i >= adev->usec_timeout) {
DRM_ERROR("KCQ disabled failed (scratch(0x%04X)=0x%08X)\n",
scratch, tmp);
r = -EINVAL;
}
amdgpu_gfx_scratch_free(adev, scratch);
return r;
}
static int gfx_v8_0_deactivate_hqd(struct amdgpu_device *adev, u32 req)
{
int i, r = 0;
@ -4715,9 +4664,6 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
uint64_t hqd_gpu_addr, wb_gpu_addr, eop_base_addr;
uint32_t tmp;
/* init the mqd struct */
memset(mqd, 0, sizeof(struct vi_mqd));
mqd->header = 0xC0310800;
mqd->compute_pipelinestat_enable = 0x00000001;
mqd->compute_static_thread_mgmt_se0 = 0xffffffff;
@ -4725,7 +4671,12 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
mqd->compute_static_thread_mgmt_se2 = 0xffffffff;
mqd->compute_static_thread_mgmt_se3 = 0xffffffff;
mqd->compute_misc_reserved = 0x00000003;
if (!(adev->flags & AMD_IS_APU)) {
mqd->dynamic_cu_mask_addr_lo = lower_32_bits(ring->mqd_gpu_addr
+ offsetof(struct vi_mqd_allocation, dyamic_cu_mask));
mqd->dynamic_cu_mask_addr_hi = upper_32_bits(ring->mqd_gpu_addr
+ offsetof(struct vi_mqd_allocation, dyamic_cu_mask));
}
eop_base_addr = ring->eop_gpu_addr >> 8;
mqd->cp_hqd_eop_base_addr_lo = eop_base_addr;
mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr);
@ -4890,7 +4841,6 @@ int gfx_v8_0_mqd_commit(struct amdgpu_device *adev,
static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring)
{
int r = 0;
struct amdgpu_device *adev = ring->adev;
struct vi_mqd *mqd = ring->mqd_ptr;
int mqd_idx = AMDGPU_MAX_COMPUTE_RINGS;
@ -4900,44 +4850,32 @@ static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring)
if (adev->gfx.in_reset) { /* for GPU_RESET case */
/* reset MQD to a clean status */
if (adev->gfx.mec.mqd_backup[mqd_idx])
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation));
/* reset ring buffer */
ring->wptr = 0;
amdgpu_ring_clear_ring(ring);
mutex_lock(&adev->srbm_mutex);
vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
r = gfx_v8_0_deactivate_hqd(adev, 1);
if (r) {
dev_err(adev->dev, "failed to deactivate ring %s\n", ring->name);
goto out_unlock;
}
gfx_v8_0_mqd_commit(adev, mqd);
vi_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
} else {
memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation));
((struct vi_mqd_allocation *)mqd)->dyamic_cu_mask = 0xFFFFFFFF;
((struct vi_mqd_allocation *)mqd)->dyamic_rb_mask = 0xFFFFFFFF;
mutex_lock(&adev->srbm_mutex);
vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
gfx_v8_0_mqd_init(ring);
r = gfx_v8_0_deactivate_hqd(adev, 1);
if (r) {
dev_err(adev->dev, "failed to deactivate ring %s\n", ring->name);
goto out_unlock;
}
gfx_v8_0_mqd_commit(adev, mqd);
vi_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.mec.mqd_backup[mqd_idx])
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct vi_mqd_allocation));
}
return r;
out_unlock:
vi_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
return r;
return 0;
}
static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
@ -4947,6 +4885,9 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
int mqd_idx = ring - &adev->gfx.compute_ring[0];
if (!adev->gfx.in_reset && !adev->gfx.in_suspend) {
memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation));
((struct vi_mqd_allocation *)mqd)->dyamic_cu_mask = 0xFFFFFFFF;
((struct vi_mqd_allocation *)mqd)->dyamic_rb_mask = 0xFFFFFFFF;
mutex_lock(&adev->srbm_mutex);
vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
gfx_v8_0_mqd_init(ring);
@ -4954,11 +4895,11 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.mec.mqd_backup[mqd_idx])
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct vi_mqd_allocation));
} else if (adev->gfx.in_reset) { /* for GPU_RESET case */
/* reset MQD to a clean status */
if (adev->gfx.mec.mqd_backup[mqd_idx])
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation));
/* reset ring buffer */
ring->wptr = 0;
amdgpu_ring_clear_ring(ring);
@ -5138,7 +5079,6 @@ static int gfx_v8_0_hw_fini(void *handle)
pr_debug("For SRIOV client, shouldn't do anything.\n");
return 0;
}
gfx_v8_0_kiq_kcq_disable(adev);
gfx_v8_0_cp_enable(adev, false);
gfx_v8_0_rlc_stop(adev);
@ -7080,7 +7020,9 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev)
mask <<= 1;
}
active_cu_number += counter;
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
if (i < 2 && j < 2)
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
cu_info->ao_cu_bitmap[i][j] = ao_bitmap;
}
}
gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);

View file

@ -1475,21 +1475,23 @@ static void gfx_v9_0_tiling_mode_table_init(struct amdgpu_device *adev)
static void gfx_v9_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 instance)
{
u32 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1);
u32 data;
if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) {
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
if (instance == 0xffffffff)
data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1);
else
data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance);
if (se_num == 0xffffffff)
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
} else if (se_num == 0xffffffff) {
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
} else if (sh_num == 0xffffffff) {
else
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
if (sh_num == 0xffffffff)
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
} else {
else
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
}
WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
}
@ -1964,8 +1966,8 @@ static void gfx_v9_0_enable_gfx_pipeline_powergating(struct amdgpu_device *adev,
data = RREG32(SOC15_REG_OFFSET(GC, 0, mmDB_RENDER_CONTROL));
}
void gfx_v9_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
bool enable)
static void gfx_v9_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
bool enable)
{
uint32_t data, default_data;
@ -1978,7 +1980,7 @@ void gfx_v9_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data);
}
void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev,
static void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev,
bool enable)
{
uint32_t data, default_data;
@ -2502,56 +2504,6 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev)
return r;
}
static int gfx_v9_0_kiq_kcq_disable(struct amdgpu_device *adev)
{
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
uint32_t scratch, tmp = 0;
int r, i;
r = amdgpu_gfx_scratch_get(adev, &scratch);
if (r) {
DRM_ERROR("Failed to get scratch reg (%d).\n", r);
return r;
}
WREG32(scratch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(kiq_ring, 6 + 3);
if (r) {
DRM_ERROR("Failed to lock KIQ (%d).\n", r);
amdgpu_gfx_scratch_free(adev, scratch);
return r;
}
/* unmap queues */
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4));
amdgpu_ring_write(kiq_ring,
PACKET3_UNMAP_QUEUES_ACTION(1)| /* RESET_QUEUES */
PACKET3_UNMAP_QUEUES_QUEUE_SEL(2)); /* select all queues */
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
amdgpu_ring_write(kiq_ring, 0);
/* write to scratch for completion */
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
amdgpu_ring_write(kiq_ring, (scratch - PACKET3_SET_UCONFIG_REG_START));
amdgpu_ring_write(kiq_ring, 0xDEADBEEF);
amdgpu_ring_commit(kiq_ring);
for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(scratch);
if (tmp == 0xDEADBEEF)
break;
DRM_UDELAY(1);
}
if (i >= adev->usec_timeout) {
DRM_ERROR("KCQ disable failed (scratch(0x%04X)=0x%08X)\n",
scratch, tmp);
r = -EINVAL;
}
amdgpu_gfx_scratch_free(adev, scratch);
return r;
}
static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
@ -2996,7 +2948,6 @@ static int gfx_v9_0_hw_fini(void *handle)
pr_debug("For SRIOV client, shouldn't do anything.\n");
return 0;
}
gfx_v9_0_kiq_kcq_disable(adev);
gfx_v9_0_cp_enable(adev, false);
gfx_v9_0_rlc_stop(adev);
@ -4416,6 +4367,20 @@ static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev)
}
}
static void gfx_v9_0_set_user_cu_inactive_bitmap(struct amdgpu_device *adev,
u32 bitmap)
{
u32 data;
if (!bitmap)
return;
data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT;
data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK;
WREG32_SOC15(GC, 0, mmGC_USER_SHADER_ARRAY_CONFIG, data);
}
static u32 gfx_v9_0_get_cu_active_bitmap(struct amdgpu_device *adev)
{
u32 data, mask;
@ -4436,10 +4401,13 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
{
int i, j, k, counter, active_cu_number = 0;
u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0;
unsigned disable_masks[4 * 2];
if (!adev || !cu_info)
return -EINVAL;
amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
mutex_lock(&adev->grbm_idx_mutex);
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
@ -4447,6 +4415,9 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
ao_bitmap = 0;
counter = 0;
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
if (i < 4 && j < 2)
gfx_v9_0_set_user_cu_inactive_bitmap(
adev, disable_masks[i * 2 + j]);
bitmap = gfx_v9_0_get_cu_active_bitmap(adev);
cu_info->bitmap[i][j] = bitmap;
@ -4459,7 +4430,9 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
mask <<= 1;
}
active_cu_number += counter;
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
if (i < 2 && j < 2)
ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
cu_info->ao_cu_bitmap[i][j] = ao_bitmap;
}
}
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);

View file

@ -794,14 +794,6 @@ static int gmc_v6_0_early_init(void *handle)
gmc_v6_0_set_gart_funcs(adev);
gmc_v6_0_set_irq_funcs(adev);
if (adev->flags & AMD_IS_APU) {
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
} else {
u32 tmp = RREG32(mmMC_SEQ_MISC0);
tmp &= MC_SEQ_MISC0__MT__MASK;
adev->mc.vram_type = gmc_v6_0_convert_vram_type(tmp);
}
return 0;
}
@ -821,6 +813,14 @@ static int gmc_v6_0_sw_init(void *handle)
int dma_bits;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->flags & AMD_IS_APU) {
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
} else {
u32 tmp = RREG32(mmMC_SEQ_MISC0);
tmp &= MC_SEQ_MISC0__MT__MASK;
adev->mc.vram_type = gmc_v6_0_convert_vram_type(tmp);
}
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->mc.vm_fault);
if (r)
return r;

View file

@ -695,6 +695,15 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
else
nbio_v6_1_hdp_flush(adev);
switch (adev->asic_type) {
case CHIP_RAVEN:
mmhub_v1_0_initialize_power_gating(adev);
mmhub_v1_0_update_power_gating(adev, true);
break;
default:
break;
}
r = gfxhub_v1_0_gart_enable(adev);
if (r)
return r;

View file

@ -244,6 +244,224 @@ static void mmhub_v1_0_program_invalidation(struct amdgpu_device *adev)
}
}
struct pctl_data {
uint32_t index;
uint32_t data;
};
const struct pctl_data pctl0_data[] = {
{0x0, 0x7a640},
{0x9, 0x2a64a},
{0xd, 0x2a680},
{0x11, 0x6a684},
{0x19, 0xea68e},
{0x29, 0xa69e},
{0x2b, 0x34a6c0},
{0x61, 0x83a707},
{0xe6, 0x8a7a4},
{0xf0, 0x1a7b8},
{0xf3, 0xfa7cc},
{0x104, 0x17a7dd},
{0x11d, 0xa7dc},
{0x11f, 0x12a7f5},
{0x133, 0xa808},
{0x135, 0x12a810},
{0x149, 0x7a82c}
};
#define PCTL0_DATA_LEN (sizeof(pctl0_data)/sizeof(pctl0_data[0]))
#define PCTL0_RENG_EXEC_END_PTR 0x151
#define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640
#define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833
const struct pctl_data pctl1_data[] = {
{0x0, 0x39a000},
{0x3b, 0x44a040},
{0x81, 0x2a08d},
{0x85, 0x6ba094},
{0xf2, 0x18a100},
{0x10c, 0x4a132},
{0x112, 0xca141},
{0x120, 0x2fa158},
{0x151, 0x17a1d0},
{0x16a, 0x1a1e9},
{0x16d, 0x13a1ec},
{0x182, 0x7a201},
{0x18b, 0x3a20a},
{0x190, 0x7a580},
{0x199, 0xa590},
{0x19b, 0x4a594},
{0x1a1, 0x1a59c},
{0x1a4, 0x7a82c},
{0x1ad, 0xfa7cc},
{0x1be, 0x17a7dd},
{0x1d7, 0x12a810}
};
#define PCTL1_DATA_LEN (sizeof(pctl1_data)/sizeof(pctl1_data[0]))
#define PCTL1_RENG_EXEC_END_PTR 0x1ea
#define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000
#define PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa20d
#define PCTL1_STCTRL_REG_SAVE_RANGE1_BASE 0xa580
#define PCTL1_STCTRL_REG_SAVE_RANGE1_LIMIT 0xa59d
#define PCTL1_STCTRL_REG_SAVE_RANGE2_BASE 0xa82c
#define PCTL1_STCTRL_REG_SAVE_RANGE2_LIMIT 0xa833
static void mmhub_v1_0_power_gating_write_save_ranges(struct amdgpu_device *adev)
{
uint32_t tmp = 0;
/* PCTL0_STCTRL_REGISTER_SAVE_RANGE0 */
tmp = REG_SET_FIELD(tmp, PCTL0_STCTRL_REGISTER_SAVE_RANGE0,
STCTRL_REGISTER_SAVE_BASE,
PCTL0_STCTRL_REG_SAVE_RANGE0_BASE);
tmp = REG_SET_FIELD(tmp, PCTL0_STCTRL_REGISTER_SAVE_RANGE0,
STCTRL_REGISTER_SAVE_LIMIT,
PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT);
WREG32_SOC15(MMHUB, 0, mmPCTL0_STCTRL_REGISTER_SAVE_RANGE0, tmp);
/* PCTL1_STCTRL_REGISTER_SAVE_RANGE0 */
tmp = 0;
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE0,
STCTRL_REGISTER_SAVE_BASE,
PCTL1_STCTRL_REG_SAVE_RANGE0_BASE);
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE0,
STCTRL_REGISTER_SAVE_LIMIT,
PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT);
WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE0, tmp);
/* PCTL1_STCTRL_REGISTER_SAVE_RANGE1 */
tmp = 0;
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE1,
STCTRL_REGISTER_SAVE_BASE,
PCTL1_STCTRL_REG_SAVE_RANGE1_BASE);
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE1,
STCTRL_REGISTER_SAVE_LIMIT,
PCTL1_STCTRL_REG_SAVE_RANGE1_LIMIT);
WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE1, tmp);
/* PCTL1_STCTRL_REGISTER_SAVE_RANGE2 */
tmp = 0;
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE2,
STCTRL_REGISTER_SAVE_BASE,
PCTL1_STCTRL_REG_SAVE_RANGE2_BASE);
tmp = REG_SET_FIELD(tmp, PCTL1_STCTRL_REGISTER_SAVE_RANGE2,
STCTRL_REGISTER_SAVE_LIMIT,
PCTL1_STCTRL_REG_SAVE_RANGE2_LIMIT);
WREG32_SOC15(MMHUB, 0, mmPCTL1_STCTRL_REGISTER_SAVE_RANGE2, tmp);
}
void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev)
{
uint32_t pctl0_misc = 0;
uint32_t pctl0_reng_execute = 0;
uint32_t pctl1_misc = 0;
uint32_t pctl1_reng_execute = 0;
int i = 0;
if (amdgpu_sriov_vf(adev))
return;
pctl0_misc = RREG32_SOC15(MMHUB, 0, mmPCTL0_MISC);
pctl0_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE);
pctl1_misc = RREG32_SOC15(MMHUB, 0, mmPCTL1_MISC);
pctl1_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE);
/* Light sleep must be disabled before writing to pctl0 registers */
pctl0_misc &= ~PCTL0_MISC__RENG_MEM_LS_ENABLE_MASK;
WREG32_SOC15(MMHUB, 0, mmPCTL0_MISC, pctl0_misc);
/* Write data used to access ram of register engine */
for (i = 0; i < PCTL0_DATA_LEN; i++) {
WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_RAM_INDEX,
pctl0_data[i].index);
WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_RAM_DATA,
pctl0_data[i].data);
}
/* Set the reng execute end ptr for pctl0 */
pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute,
PCTL0_RENG_EXECUTE,
RENG_EXECUTE_END_PTR,
PCTL0_RENG_EXEC_END_PTR);
WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute);
/* Light sleep must be disabled before writing to pctl1 registers */
pctl1_misc &= ~PCTL1_MISC__RENG_MEM_LS_ENABLE_MASK;
WREG32_SOC15(MMHUB, 0, mmPCTL1_MISC, pctl1_misc);
/* Write data used to access ram of register engine */
for (i = 0; i < PCTL1_DATA_LEN; i++) {
WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_RAM_INDEX,
pctl1_data[i].index);
WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_RAM_DATA,
pctl1_data[i].data);
}
/* Set the reng execute end ptr for pctl1 */
pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute,
PCTL1_RENG_EXECUTE,
RENG_EXECUTE_END_PTR,
PCTL1_RENG_EXEC_END_PTR);
WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute);
mmhub_v1_0_power_gating_write_save_ranges(adev);
/* Re-enable light sleep */
pctl0_misc |= PCTL0_MISC__RENG_MEM_LS_ENABLE_MASK;
WREG32_SOC15(MMHUB, 0, mmPCTL0_MISC, pctl0_misc);
pctl1_misc |= PCTL1_MISC__RENG_MEM_LS_ENABLE_MASK;
WREG32_SOC15(MMHUB, 0, mmPCTL1_MISC, pctl1_misc);
}
void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
bool enable)
{
uint32_t pctl0_reng_execute = 0;
uint32_t pctl1_reng_execute = 0;
if (amdgpu_sriov_vf(adev))
return;
pctl0_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE);
pctl1_reng_execute = RREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE);
if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) {
pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute,
PCTL0_RENG_EXECUTE,
RENG_EXECUTE_ON_PWR_UP, 1);
pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute,
PCTL0_RENG_EXECUTE,
RENG_EXECUTE_ON_REG_UPDATE, 1);
WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute);
pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute,
PCTL1_RENG_EXECUTE,
RENG_EXECUTE_ON_PWR_UP, 1);
pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute,
PCTL1_RENG_EXECUTE,
RENG_EXECUTE_ON_REG_UPDATE, 1);
WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute);
} else {
pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute,
PCTL0_RENG_EXECUTE,
RENG_EXECUTE_ON_PWR_UP, 0);
pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute,
PCTL0_RENG_EXECUTE,
RENG_EXECUTE_ON_REG_UPDATE, 0);
WREG32_SOC15(MMHUB, 0, mmPCTL0_RENG_EXECUTE, pctl0_reng_execute);
pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute,
PCTL1_RENG_EXECUTE,
RENG_EXECUTE_ON_PWR_UP, 0);
pctl1_reng_execute = REG_SET_FIELD(pctl1_reng_execute,
PCTL1_RENG_EXECUTE,
RENG_EXECUTE_ON_REG_UPDATE, 0);
WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute);
}
}
int mmhub_v1_0_gart_enable(struct amdgpu_device *adev)
{
if (amdgpu_sriov_vf(adev)) {

View file

@ -32,6 +32,9 @@ void mmhub_v1_0_init(struct amdgpu_device *adev);
int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
enum amd_clockgating_state state);
void mmhub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags);
void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev);
void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
bool enable);
extern const struct amd_ip_funcs mmhub_v1_0_ip_funcs;
extern const struct amdgpu_ip_block_version mmhub_v1_0_ip_block;

View file

@ -96,8 +96,8 @@ int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cm
header = (struct common_firmware_header *)ucode->fw;
cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = (uint32_t)fw_mem_mc_addr;
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = (uint32_t)((uint64_t)fw_mem_mc_addr >> 32);
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
cmd->cmd.cmd_load_ip_fw.fw_size = le32_to_cpu(header->ucode_size_bytes);
ret = psp_v10_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
@ -172,10 +172,10 @@ int psp_v10_0_cmd_submit(struct psp_context *psp,
write_frame = ring->ring_mem + (psp_write_ptr_reg / (sizeof(struct psp_gfx_rb_frame) / 4));
/* Update KM RB frame */
write_frame->cmd_buf_addr_hi = (unsigned int)(cmd_buf_mc_addr >> 32);
write_frame->cmd_buf_addr_lo = (unsigned int)(cmd_buf_mc_addr);
write_frame->fence_addr_hi = (unsigned int)(fence_mc_addr >> 32);
write_frame->fence_addr_lo = (unsigned int)(fence_mc_addr);
write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr);
write_frame->cmd_buf_addr_lo = lower_32_bits(cmd_buf_mc_addr);
write_frame->fence_addr_hi = upper_32_bits(fence_mc_addr);
write_frame->fence_addr_lo = lower_32_bits(fence_mc_addr);
write_frame->fence_value = index;
/* Update the write Pointer in DWORDs */

View file

@ -254,8 +254,8 @@ int psp_v3_1_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = (uint32_t)fw_mem_mc_addr;
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = (uint32_t)((uint64_t)fw_mem_mc_addr >> 32);
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
ret = psp_v3_1_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
@ -375,10 +375,10 @@ int psp_v3_1_cmd_submit(struct psp_context *psp,
memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame));
/* Update KM RB frame */
write_frame->cmd_buf_addr_hi = (unsigned int)(cmd_buf_mc_addr >> 32);
write_frame->cmd_buf_addr_lo = (unsigned int)(cmd_buf_mc_addr);
write_frame->fence_addr_hi = (unsigned int)(fence_mc_addr >> 32);
write_frame->fence_addr_lo = (unsigned int)(fence_mc_addr);
write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr);
write_frame->cmd_buf_addr_lo = lower_32_bits(cmd_buf_mc_addr);
write_frame->fence_addr_hi = upper_32_bits(fence_mc_addr);
write_frame->fence_addr_lo = lower_32_bits(fence_mc_addr);
write_frame->fence_value = index;
/* Update the write Pointer in DWORDs */

View file

@ -1385,6 +1385,7 @@ static void si_init_golden_registers(struct amdgpu_device *adev)
amdgpu_program_register_sequence(adev,
pitcairn_mgcg_cgcg_init,
(const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
break;
case CHIP_VERDE:
amdgpu_program_register_sequence(adev,
verde_golden_registers,
@ -1409,6 +1410,7 @@ static void si_init_golden_registers(struct amdgpu_device *adev)
amdgpu_program_register_sequence(adev,
oland_mgcg_cgcg_init,
(const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
break;
case CHIP_HAINAN:
amdgpu_program_register_sequence(adev,
hainan_golden_registers,

View file

@ -625,7 +625,8 @@ static int soc15_common_early_init(void *handle)
AMD_CG_SUPPORT_MC_LS |
AMD_CG_SUPPORT_SDMA_MGCG |
AMD_CG_SUPPORT_SDMA_LS;
adev->pg_flags = AMD_PG_SUPPORT_SDMA;
adev->pg_flags = AMD_PG_SUPPORT_SDMA |
AMD_PG_SUPPORT_MMHUB;
adev->external_rev_id = 0x1;
break;
default:

View file

@ -226,10 +226,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->shared_resources = *gpu_resources;
/* We only use the first MEC */
if (kfd->shared_resources.num_mec > 1)
kfd->shared_resources.num_mec = 1;
/* calculate max size of mqds needed for queues */
size = max_num_of_queues_per_device *
kfd->device_info->mqd_size_aligned;

View file

@ -77,13 +77,6 @@ static bool is_pipe_enabled(struct device_queue_manager *dqm, int mec, int pipe)
return false;
}
unsigned int get_mec_num(struct device_queue_manager *dqm)
{
BUG_ON(!dqm || !dqm->dev);
return dqm->dev->shared_resources.num_mec;
}
unsigned int get_queues_num(struct device_queue_manager *dqm)
{
BUG_ON(!dqm || !dqm->dev);

View file

@ -180,7 +180,6 @@ void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops);
void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops);
void program_sh_mem_settings(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
unsigned int get_mec_num(struct device_queue_manager *dqm);
unsigned int get_queues_num(struct device_queue_manager *dqm);
unsigned int get_queues_per_pipe(struct device_queue_manager *dqm);
unsigned int get_pipes_per_mec(struct device_queue_manager *dqm);

View file

@ -318,12 +318,13 @@ static struct kfd_process *create_process(const struct task_struct *thread)
/* init process apertures*/
process->is_32bit_user_mode = in_compat_syscall();
if (kfd_init_apertures(process) != 0)
goto err_init_apretures;
err = kfd_init_apertures(process);
if (err != 0)
goto err_init_apertures;
return process;
err_init_apretures:
err_init_apertures:
pqm_uninit(&process->pqm);
err_process_pqm_init:
hash_del_rcu(&process->kfd_processes);

View file

@ -184,6 +184,7 @@ enum amd_fan_ctrl_mode {
#define AMD_PG_SUPPORT_SAMU (1 << 10)
#define AMD_PG_SUPPORT_GFX_QUICK_MG (1 << 11)
#define AMD_PG_SUPPORT_GFX_PIPELINE (1 << 12)
#define AMD_PG_SUPPORT_MMHUB (1 << 13)
enum amd_pm_state_type {
/* not used for dpm */

View file

@ -63,9 +63,6 @@ struct kgd2kfd_shared_resources {
/* Bit n == 1 means VMID n is available for KFD. */
unsigned int compute_vmid_bitmap;
/* number of mec available from the hardware */
uint32_t num_mec;
/* number of pipes per mec */
uint32_t num_pipe_per_mec;

View file

@ -156,6 +156,274 @@ struct vi_sdma_mqd {
};
struct vi_mqd {
uint32_t header;
uint32_t compute_dispatch_initiator;
uint32_t compute_dim_x;
uint32_t compute_dim_y;
uint32_t compute_dim_z;
uint32_t compute_start_x;
uint32_t compute_start_y;
uint32_t compute_start_z;
uint32_t compute_num_thread_x;
uint32_t compute_num_thread_y;
uint32_t compute_num_thread_z;
uint32_t compute_pipelinestat_enable;
uint32_t compute_perfcount_enable;
uint32_t compute_pgm_lo;
uint32_t compute_pgm_hi;
uint32_t compute_tba_lo;
uint32_t compute_tba_hi;
uint32_t compute_tma_lo;
uint32_t compute_tma_hi;
uint32_t compute_pgm_rsrc1;
uint32_t compute_pgm_rsrc2;
uint32_t compute_vmid;
uint32_t compute_resource_limits;
uint32_t compute_static_thread_mgmt_se0;
uint32_t compute_static_thread_mgmt_se1;
uint32_t compute_tmpring_size;
uint32_t compute_static_thread_mgmt_se2;
uint32_t compute_static_thread_mgmt_se3;
uint32_t compute_restart_x;
uint32_t compute_restart_y;
uint32_t compute_restart_z;
uint32_t compute_thread_trace_enable;
uint32_t compute_misc_reserved;
uint32_t compute_dispatch_id;
uint32_t compute_threadgroup_id;
uint32_t compute_relaunch;
uint32_t compute_wave_restore_addr_lo;
uint32_t compute_wave_restore_addr_hi;
uint32_t compute_wave_restore_control;
uint32_t reserved9;
uint32_t reserved10;
uint32_t reserved11;
uint32_t reserved12;
uint32_t reserved13;
uint32_t reserved14;
uint32_t reserved15;
uint32_t reserved16;
uint32_t reserved17;
uint32_t reserved18;
uint32_t reserved19;
uint32_t reserved20;
uint32_t reserved21;
uint32_t reserved22;
uint32_t reserved23;
uint32_t reserved24;
uint32_t reserved25;
uint32_t reserved26;
uint32_t reserved27;
uint32_t reserved28;
uint32_t reserved29;
uint32_t reserved30;
uint32_t reserved31;
uint32_t reserved32;
uint32_t reserved33;
uint32_t reserved34;
uint32_t compute_user_data_0;
uint32_t compute_user_data_1;
uint32_t compute_user_data_2;
uint32_t compute_user_data_3;
uint32_t compute_user_data_4;
uint32_t compute_user_data_5;
uint32_t compute_user_data_6;
uint32_t compute_user_data_7;
uint32_t compute_user_data_8;
uint32_t compute_user_data_9;
uint32_t compute_user_data_10;
uint32_t compute_user_data_11;
uint32_t compute_user_data_12;
uint32_t compute_user_data_13;
uint32_t compute_user_data_14;
uint32_t compute_user_data_15;
uint32_t cp_compute_csinvoc_count_lo;
uint32_t cp_compute_csinvoc_count_hi;
uint32_t reserved35;
uint32_t reserved36;
uint32_t reserved37;
uint32_t cp_mqd_query_time_lo;
uint32_t cp_mqd_query_time_hi;
uint32_t cp_mqd_connect_start_time_lo;
uint32_t cp_mqd_connect_start_time_hi;
uint32_t cp_mqd_connect_end_time_lo;
uint32_t cp_mqd_connect_end_time_hi;
uint32_t cp_mqd_connect_end_wf_count;
uint32_t cp_mqd_connect_end_pq_rptr;
uint32_t cp_mqd_connect_endvi_sdma_mqd_pq_wptr;
uint32_t cp_mqd_connect_end_ib_rptr;
uint32_t reserved38;
uint32_t reserved39;
uint32_t cp_mqd_save_start_time_lo;
uint32_t cp_mqd_save_start_time_hi;
uint32_t cp_mqd_save_end_time_lo;
uint32_t cp_mqd_save_end_time_hi;
uint32_t cp_mqd_restore_start_time_lo;
uint32_t cp_mqd_restore_start_time_hi;
uint32_t cp_mqd_restore_end_time_lo;
uint32_t cp_mqd_restore_end_time_hi;
uint32_t disable_queue;
uint32_t reserved41;
uint32_t gds_cs_ctxsw_cnt0;
uint32_t gds_cs_ctxsw_cnt1;
uint32_t gds_cs_ctxsw_cnt2;
uint32_t gds_cs_ctxsw_cnt3;
uint32_t reserved42;
uint32_t reserved43;
uint32_t cp_pq_exe_status_lo;
uint32_t cp_pq_exe_status_hi;
uint32_t cp_packet_id_lo;
uint32_t cp_packet_id_hi;
uint32_t cp_packet_exe_status_lo;
uint32_t cp_packet_exe_status_hi;
uint32_t gds_save_base_addr_lo;
uint32_t gds_save_base_addr_hi;
uint32_t gds_save_mask_lo;
uint32_t gds_save_mask_hi;
uint32_t ctx_save_base_addr_lo;
uint32_t ctx_save_base_addr_hi;
uint32_t dynamic_cu_mask_addr_lo;
uint32_t dynamic_cu_mask_addr_hi;
uint32_t cp_mqd_base_addr_lo;
uint32_t cp_mqd_base_addr_hi;
uint32_t cp_hqd_active;
uint32_t cp_hqd_vmid;
uint32_t cp_hqd_persistent_state;
uint32_t cp_hqd_pipe_priority;
uint32_t cp_hqd_queue_priority;
uint32_t cp_hqd_quantum;
uint32_t cp_hqd_pq_base_lo;
uint32_t cp_hqd_pq_base_hi;
uint32_t cp_hqd_pq_rptr;
uint32_t cp_hqd_pq_rptr_report_addr_lo;
uint32_t cp_hqd_pq_rptr_report_addr_hi;
uint32_t cp_hqd_pq_wptr_poll_addr_lo;
uint32_t cp_hqd_pq_wptr_poll_addr_hi;
uint32_t cp_hqd_pq_doorbell_control;
uint32_t cp_hqd_pq_wptr;
uint32_t cp_hqd_pq_control;
uint32_t cp_hqd_ib_base_addr_lo;
uint32_t cp_hqd_ib_base_addr_hi;
uint32_t cp_hqd_ib_rptr;
uint32_t cp_hqd_ib_control;
uint32_t cp_hqd_iq_timer;
uint32_t cp_hqd_iq_rptr;
uint32_t cp_hqd_dequeue_request;
uint32_t cp_hqd_dma_offload;
uint32_t cp_hqd_sema_cmd;
uint32_t cp_hqd_msg_type;
uint32_t cp_hqd_atomic0_preop_lo;
uint32_t cp_hqd_atomic0_preop_hi;
uint32_t cp_hqd_atomic1_preop_lo;
uint32_t cp_hqd_atomic1_preop_hi;
uint32_t cp_hqd_hq_status0;
uint32_t cp_hqd_hq_control0;
uint32_t cp_mqd_control;
uint32_t cp_hqd_hq_status1;
uint32_t cp_hqd_hq_control1;
uint32_t cp_hqd_eop_base_addr_lo;
uint32_t cp_hqd_eop_base_addr_hi;
uint32_t cp_hqd_eop_control;
uint32_t cp_hqd_eop_rptr;
uint32_t cp_hqd_eop_wptr;
uint32_t cp_hqd_eop_done_events;
uint32_t cp_hqd_ctx_save_base_addr_lo;
uint32_t cp_hqd_ctx_save_base_addr_hi;
uint32_t cp_hqd_ctx_save_control;
uint32_t cp_hqd_cntl_stack_offset;
uint32_t cp_hqd_cntl_stack_size;
uint32_t cp_hqd_wg_state_offset;
uint32_t cp_hqd_ctx_save_size;
uint32_t cp_hqd_gds_resource_state;
uint32_t cp_hqd_error;
uint32_t cp_hqd_eop_wptr_mem;
uint32_t cp_hqd_eop_dones;
uint32_t reserved46;
uint32_t reserved47;
uint32_t reserved48;
uint32_t reserved49;
uint32_t reserved50;
uint32_t reserved51;
uint32_t reserved52;
uint32_t reserved53;
uint32_t reserved54;
uint32_t reserved55;
uint32_t iqtimer_pkt_header;
uint32_t iqtimer_pkt_dw0;
uint32_t iqtimer_pkt_dw1;
uint32_t iqtimer_pkt_dw2;
uint32_t iqtimer_pkt_dw3;
uint32_t iqtimer_pkt_dw4;
uint32_t iqtimer_pkt_dw5;
uint32_t iqtimer_pkt_dw6;
uint32_t iqtimer_pkt_dw7;
uint32_t iqtimer_pkt_dw8;
uint32_t iqtimer_pkt_dw9;
uint32_t iqtimer_pkt_dw10;
uint32_t iqtimer_pkt_dw11;
uint32_t iqtimer_pkt_dw12;
uint32_t iqtimer_pkt_dw13;
uint32_t iqtimer_pkt_dw14;
uint32_t iqtimer_pkt_dw15;
uint32_t iqtimer_pkt_dw16;
uint32_t iqtimer_pkt_dw17;
uint32_t iqtimer_pkt_dw18;
uint32_t iqtimer_pkt_dw19;
uint32_t iqtimer_pkt_dw20;
uint32_t iqtimer_pkt_dw21;
uint32_t iqtimer_pkt_dw22;
uint32_t iqtimer_pkt_dw23;
uint32_t iqtimer_pkt_dw24;
uint32_t iqtimer_pkt_dw25;
uint32_t iqtimer_pkt_dw26;
uint32_t iqtimer_pkt_dw27;
uint32_t iqtimer_pkt_dw28;
uint32_t iqtimer_pkt_dw29;
uint32_t iqtimer_pkt_dw30;
uint32_t iqtimer_pkt_dw31;
uint32_t reserved56;
uint32_t reserved57;
uint32_t reserved58;
uint32_t set_resources_header;
uint32_t set_resources_dw1;
uint32_t set_resources_dw2;
uint32_t set_resources_dw3;
uint32_t set_resources_dw4;
uint32_t set_resources_dw5;
uint32_t set_resources_dw6;
uint32_t set_resources_dw7;
uint32_t reserved59;
uint32_t reserved60;
uint32_t reserved61;
uint32_t reserved62;
uint32_t reserved63;
uint32_t reserved64;
uint32_t reserved65;
uint32_t reserved66;
uint32_t reserved67;
uint32_t reserved68;
uint32_t reserved69;
uint32_t reserved70;
uint32_t reserved71;
uint32_t reserved72;
uint32_t reserved73;
uint32_t reserved74;
uint32_t reserved75;
uint32_t reserved76;
uint32_t reserved77;
uint32_t reserved78;
uint32_t reserved_t[256];
};
struct vi_mqd_allocation {
struct vi_mqd mqd;
uint32_t wptr_poll_mem;
uint32_t rptr_report_mem;
uint32_t dyamic_cu_mask;
uint32_t dyamic_rb_mask;
};
struct cz_mqd {
uint32_t header;
uint32_t compute_dispatch_initiator;
uint32_t compute_dim_x;

View file

@ -2128,15 +2128,9 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->AvfsGbCksOff.m2_shift = 12;
pp_table->AvfsGbCksOff.b_shift = 0;
for (i = 0; i < dep_table->count; i++) {
if (dep_table->entries[i].sclk_offset == 0)
pp_table->StaticVoltageOffsetVid[i] = 248;
else
pp_table->StaticVoltageOffsetVid[i] =
(uint8_t)(dep_table->entries[i].sclk_offset *
VOLTAGE_VID_OFFSET_SCALE2 /
VOLTAGE_VID_OFFSET_SCALE1);
}
for (i = 0; i < dep_table->count; i++)
pp_table->StaticVoltageOffsetVid[i] =
convert_to_vid((uint8_t)(dep_table->entries[i].sclk_offset));
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->disp_clk_quad_eqn_a) &&
@ -2865,6 +2859,7 @@ static int vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
void *state, struct pp_power_state *power_state,
void *pp_table, uint32_t classification_flag)
{
ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_V2;
struct vega10_power_state *vega10_power_state =
cast_phw_vega10_power_state(&(power_state->hardware));
struct vega10_performance_level *performance_level;
@ -2941,11 +2936,16 @@ static int vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
performance_level = &(vega10_power_state->performance_levels
[vega10_power_state->performance_level_count++]);
performance_level->soc_clock = socclk_dep_table->entries
[state_entry->ucSocClockIndexHigh].ulClk;
performance_level->gfx_clock = gfxclk_dep_table->entries
[state_entry->ucSocClockIndexHigh].ulClk;
if (gfxclk_dep_table->ucRevId == 0) {
performance_level->gfx_clock = gfxclk_dep_table->entries
[state_entry->ucGfxClockIndexHigh].ulClk;
} else if (gfxclk_dep_table->ucRevId == 1) {
patom_record_V2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries;
performance_level->gfx_clock = patom_record_V2[state_entry->ucGfxClockIndexHigh].ulClk;
}
performance_level->mem_clock = mclk_dep_table->entries
[state_entry->ucMemClockIndexHigh].ulMemClk;
return 0;
@ -3349,7 +3349,6 @@ static int vega10_populate_and_upload_sclk_mclk_dpm_levels(
dpm_table->
gfx_table.dpm_levels[dpm_table->gfx_table.count - 1].
value = sclk;
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_OD6PlusinACSupport) ||
phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
@ -3472,7 +3471,6 @@ static int vega10_populate_and_upload_sclk_mclk_dpm_levels(
return result);
}
}
return result;
}
@ -3828,13 +3826,18 @@ static int vega10_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
struct pp_gpu_power *query)
{
uint32_t value;
PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr->smumgr,
PPSMC_MSG_GetCurrPkgPwr),
"Failed to get current package power!",
return -EINVAL);
return vega10_read_arg_from_smc(hwmgr->smumgr,
&query->average_gpu_power);
vega10_read_arg_from_smc(hwmgr->smumgr, &value);
/* power value is an integer */
query->average_gpu_power = value << 8;
return 0;
}
static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,

View file

@ -144,6 +144,15 @@ typedef struct _ATOM_Vega10_GFXCLK_Dependency_Record {
USHORT usAVFSOffset; /* AVFS Voltage offset */
} ATOM_Vega10_GFXCLK_Dependency_Record;
typedef struct _ATOM_Vega10_GFXCLK_Dependency_Record_V2 {
ULONG ulClk;
UCHAR ucVddInd;
USHORT usCKSVOffsetandDisable;
USHORT usAVFSOffset;
UCHAR ucACGEnable;
UCHAR ucReserved[3];
} ATOM_Vega10_GFXCLK_Dependency_Record_V2;
typedef struct _ATOM_Vega10_MCLK_Dependency_Record {
ULONG ulMemClk; /* Clock Frequency */
UCHAR ucVddInd; /* SOC_VDD index */

View file

@ -585,6 +585,7 @@ static int get_gfxclk_voltage_dependency_table(
uint32_t table_size, i;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
@ -601,18 +602,41 @@ static int get_gfxclk_voltage_dependency_table(
clk_table->count = clk_dep_table->ucNumEntries;
for (i = 0; i < clk_table->count; i++) {
clk_table->entries[i].vddInd =
if (clk_dep_table->ucRevId == 0) {
for (i = 0; i < clk_table->count; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
clk_table->entries[i].clk =
le32_to_cpu(clk_dep_table->entries[i].ulClk);
clk_table->entries[i].cks_enable =
(((clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x8000)
clk_table->entries[i].cks_enable =
(((le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x8000)
>> 15) == 0) ? 1 : 0;
clk_table->entries[i].cks_voffset =
(clk_dep_table->entries[i].usCKSVOffsetandDisable & 0x7F);
clk_table->entries[i].sclk_offset =
clk_dep_table->entries[i].usAVFSOffset;
clk_table->entries[i].cks_voffset =
le16_to_cpu(clk_dep_table->entries[i].usCKSVOffsetandDisable) & 0x7F;
clk_table->entries[i].sclk_offset =
le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset);
}
} else if (clk_dep_table->ucRevId == 1) {
patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)clk_dep_table->entries;
for (i = 0; i < clk_table->count; i++) {
clk_table->entries[i].vddInd =
patom_record_v2->ucVddInd;
clk_table->entries[i].clk =
le32_to_cpu(patom_record_v2->ulClk);
clk_table->entries[i].cks_enable =
(((le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x8000)
>> 15) == 0) ? 1 : 0;
clk_table->entries[i].cks_voffset =
le16_to_cpu(patom_record_v2->usCKSVOffsetandDisable) & 0x7F;
clk_table->entries[i].sclk_offset =
le16_to_cpu(patom_record_v2->usAVFSOffset);
patom_record_v2++;
}
} else {
kfree(clk_table);
PP_ASSERT_WITH_CODE(false,
"Unsupported GFXClockDependencyTable Revision!",
return -EINVAL);
}
*pp_vega10_clk_dep_table = clk_table;

View file

@ -124,8 +124,8 @@ typedef uint16_t PPSMC_Result;
#define PPSMC_MSG_NumOfDisplays 0x56
#define PPSMC_MSG_ReadSerialNumTop32 0x58
#define PPSMC_MSG_ReadSerialNumBottom32 0x59
#define PPSMC_MSG_GetCurrPkgPwr 0x5C
#define PPSMC_Message_Count 0x5D
#define PPSMC_MSG_GetCurrPkgPwr 0x61
#define PPSMC_Message_Count 0x62
typedef int PPSMC_Msg;

View file

@ -72,7 +72,7 @@ static int cz_send_msg_to_smc_async(struct pp_smumgr *smumgr,
result = SMUM_WAIT_FIELD_UNEQUAL(smumgr,
SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
if (result != 0) {
pr_err("cz_send_msg_to_smc_async failed\n");
pr_err("cz_send_msg_to_smc_async (0x%04x) failed\n", msg);
return result;
}

View file

@ -133,7 +133,7 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
}
/* Framebuffer objects must have a valid device address for scanout */
if (obj->dev_addr == DMA_ERROR_CODE) {
if (!obj->mapped) {
ret = -EINVAL;
goto err_unref;
}

View file

@ -175,6 +175,7 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
obj->phys_addr = obj->linear->start;
obj->dev_addr = obj->linear->start;
obj->mapped = true;
}
DRM_DEBUG_DRIVER("obj %p phys %#llx dev %#llx\n", obj,
@ -205,7 +206,6 @@ armada_gem_alloc_private_object(struct drm_device *dev, size_t size)
return NULL;
drm_gem_private_object_init(dev, &obj->obj, size);
obj->dev_addr = DMA_ERROR_CODE;
DRM_DEBUG_DRIVER("alloc private obj %p size %zu\n", obj, size);
@ -229,8 +229,6 @@ static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev,
return NULL;
}
obj->dev_addr = DMA_ERROR_CODE;
mapping = obj->obj.filp->f_mapping;
mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
@ -610,5 +608,6 @@ int armada_gem_map_import(struct armada_gem_object *dobj)
return -EINVAL;
}
dobj->dev_addr = sg_dma_address(dobj->sgt->sgl);
dobj->mapped = true;
return 0;
}

View file

@ -16,6 +16,7 @@ struct armada_gem_object {
void *addr;
phys_addr_t phys_addr;
resource_size_t dev_addr;
bool mapped;
struct drm_mm_node *linear; /* for linear backed */
struct page *page; /* for page backed */
struct sg_table *sgt; /* for imported */

View file

@ -11,6 +11,7 @@
#include <sound/hdmi-codec.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <linux/of_graph.h>
#include "adv7511.h"
@ -182,10 +183,31 @@ static void audio_shutdown(struct device *dev, void *data)
{
}
static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
struct device_node *endpoint)
{
struct of_endpoint of_ep;
int ret;
ret = of_graph_parse_endpoint(endpoint, &of_ep);
if (ret < 0)
return ret;
/*
* HDMI sound should be located as reg = <2>
* Then, it is sound port 0
*/
if (of_ep.port == 2)
return 0;
return -EINVAL;
}
static const struct hdmi_codec_ops adv7511_codec_ops = {
.hw_params = adv7511_hdmi_hw_params,
.audio_shutdown = audio_shutdown,
.audio_startup = audio_startup,
.get_dai_id = adv7511_hdmi_i2s_get_dai_id,
};
static struct hdmi_codec_pdata codec_data = {

View file

@ -82,9 +82,30 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
}
static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
struct device_node *endpoint)
{
struct of_endpoint of_ep;
int ret;
ret = of_graph_parse_endpoint(endpoint, &of_ep);
if (ret < 0)
return ret;
/*
* HDMI sound should be located as reg = <2>
* Then, it is sound port 0
*/
if (of_ep.port == 2)
return 0;
return -EINVAL;
}
static struct hdmi_codec_ops dw_hdmi_i2s_ops = {
.hw_params = dw_hdmi_i2s_hw_params,
.audio_shutdown = dw_hdmi_i2s_audio_shutdown,
.get_dai_id = dw_hdmi_i2s_get_dai_id,
};
static int snd_dw_hdmi_probe(struct platform_device *pdev)

View file

@ -1258,11 +1258,11 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
* lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space.
*/
int drm_legacy_infobufs(struct drm_device *dev, void *data,
struct drm_file *file_priv)
int __drm_legacy_infobufs(struct drm_device *dev,
void *data, int *p,
int (*f)(void *, int, struct drm_buf_entry *))
{
struct drm_device_dma *dma = dev->dma;
struct drm_buf_info *request = data;
int i;
int count;
@ -1290,26 +1290,12 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
DRM_DEBUG("count = %d\n", count);
if (request->count >= count) {
if (*p >= count) {
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
if (dma->bufs[i].buf_count) {
struct drm_buf_desc __user *to =
&request->list[count];
struct drm_buf_entry *from = &dma->bufs[i];
if (copy_to_user(&to->count,
&from->buf_count,
sizeof(from->buf_count)) ||
copy_to_user(&to->size,
&from->buf_size,
sizeof(from->buf_size)) ||
copy_to_user(&to->low_mark,
&from->low_mark,
sizeof(from->low_mark)) ||
copy_to_user(&to->high_mark,
&from->high_mark,
sizeof(from->high_mark)))
struct drm_buf_entry *from = &dma->bufs[i];
if (from->buf_count) {
if (f(data, count, from) < 0)
return -EFAULT;
DRM_DEBUG("%d %d %d %d %d\n",
i,
dma->bufs[i].buf_count,
@ -1320,11 +1306,29 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
}
}
}
request->count = count;
*p = count;
return 0;
}
static int copy_one_buf(void *data, int count, struct drm_buf_entry *from)
{
struct drm_buf_info *request = data;
struct drm_buf_desc __user *to = &request->list[count];
struct drm_buf_desc v = {.count = from->buf_count,
.size = from->buf_size,
.low_mark = from->low_mark,
.high_mark = from->high_mark};
return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags));
}
int drm_legacy_infobufs(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_buf_info *request = data;
return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf);
}
/**
* Specifies a low and high water mark for buffer allocation
*
@ -1439,15 +1443,15 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data,
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
* drm_mmap_dma().
*/
int drm_legacy_mapbufs(struct drm_device *dev, void *data,
struct drm_file *file_priv)
int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p,
void __user **v,
int (*f)(void *, int, unsigned long,
struct drm_buf *),
struct drm_file *file_priv)
{
struct drm_device_dma *dma = dev->dma;
int retcode = 0;
const int zero = 0;
unsigned long virtual;
unsigned long address;
struct drm_buf_map *request = data;
int i;
if (!drm_core_check_feature(dev, DRIVER_LEGACY))
@ -1467,7 +1471,7 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data,
dev->buf_use++; /* Can't allocate more after this call */
spin_unlock(&dev->buf_lock);
if (request->count >= dma->buf_count) {
if (*p >= dma->buf_count) {
if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP))
|| (drm_core_check_feature(dev, DRIVER_SG)
&& (dma->flags & _DRM_DMA_USE_SG))) {
@ -1492,41 +1496,51 @@ int drm_legacy_mapbufs(struct drm_device *dev, void *data,
retcode = (signed long)virtual;
goto done;
}
request->virtual = (void __user *)virtual;
*v = (void __user *)virtual;
for (i = 0; i < dma->buf_count; i++) {
if (copy_to_user(&request->list[i].idx,
&dma->buflist[i]->idx,
sizeof(request->list[0].idx))) {
retcode = -EFAULT;
goto done;
}
if (copy_to_user(&request->list[i].total,
&dma->buflist[i]->total,
sizeof(request->list[0].total))) {
retcode = -EFAULT;
goto done;
}
if (copy_to_user(&request->list[i].used,
&zero, sizeof(zero))) {
retcode = -EFAULT;
goto done;
}
address = virtual + dma->buflist[i]->offset; /* *** */
if (copy_to_user(&request->list[i].address,
&address, sizeof(address))) {
if (f(data, i, virtual, dma->buflist[i]) < 0) {
retcode = -EFAULT;
goto done;
}
}
}
done:
request->count = dma->buf_count;
DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
*p = dma->buf_count;
DRM_DEBUG("%d buffers, retcode = %d\n", *p, retcode);
return retcode;
}
static int map_one_buf(void *data, int idx, unsigned long virtual,
struct drm_buf *buf)
{
struct drm_buf_map *request = data;
unsigned long address = virtual + buf->offset; /* *** */
if (copy_to_user(&request->list[idx].idx, &buf->idx,
sizeof(request->list[0].idx)))
return -EFAULT;
if (copy_to_user(&request->list[idx].total, &buf->total,
sizeof(request->list[0].total)))
return -EFAULT;
if (clear_user(&request->list[idx].used, sizeof(int)))
return -EFAULT;
if (copy_to_user(&request->list[idx].address, &address,
sizeof(address)))
return -EFAULT;
return 0;
}
int drm_legacy_mapbufs(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_buf_map *request = data;
return __drm_legacy_mapbufs(dev, data, &request->count,
&request->virtual, map_one_buf,
file_priv);
}
int drm_legacy_dma_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{

View file

@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/uio.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drmP.h>
@ -140,101 +141,83 @@ static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
return fixed_size_llseek(file, offset, whence, AUX_MAX_OFFSET);
}
static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
loff_t *offset)
static ssize_t auxdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
size_t bytes_pending, num_bytes_processed = 0;
struct drm_dp_aux_dev *aux_dev = file->private_data;
struct drm_dp_aux_dev *aux_dev = iocb->ki_filp->private_data;
loff_t pos = iocb->ki_pos;
ssize_t res = 0;
if (!atomic_inc_not_zero(&aux_dev->usecount))
return -ENODEV;
bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - (*offset));
iov_iter_truncate(to, AUX_MAX_OFFSET - pos);
if (!access_ok(VERIFY_WRITE, buf, bytes_pending)) {
res = -EFAULT;
goto out;
}
while (bytes_pending > 0) {
uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
while (iov_iter_count(to)) {
uint8_t buf[DP_AUX_MAX_PAYLOAD_BYTES];
ssize_t todo = min(iov_iter_count(to), sizeof(buf));
if (signal_pending(current)) {
res = num_bytes_processed ?
num_bytes_processed : -ERESTARTSYS;
goto out;
res = -ERESTARTSYS;
break;
}
res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
if (res <= 0) {
res = num_bytes_processed ? num_bytes_processed : res;
goto out;
res = drm_dp_dpcd_read(aux_dev->aux, pos, buf, todo);
if (res <= 0)
break;
if (copy_to_iter(buf, res, to) != res) {
res = -EFAULT;
break;
}
if (__copy_to_user(buf + num_bytes_processed, localbuf, res)) {
res = num_bytes_processed ?
num_bytes_processed : -EFAULT;
goto out;
}
bytes_pending -= res;
*offset += res;
num_bytes_processed += res;
res = num_bytes_processed;
pos += res;
}
out:
if (pos != iocb->ki_pos)
res = pos - iocb->ki_pos;
iocb->ki_pos = pos;
atomic_dec(&aux_dev->usecount);
wake_up_atomic_t(&aux_dev->usecount);
return res;
}
static ssize_t auxdev_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
static ssize_t auxdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
size_t bytes_pending, num_bytes_processed = 0;
struct drm_dp_aux_dev *aux_dev = file->private_data;
struct drm_dp_aux_dev *aux_dev = iocb->ki_filp->private_data;
loff_t pos = iocb->ki_pos;
ssize_t res = 0;
if (!atomic_inc_not_zero(&aux_dev->usecount))
return -ENODEV;
bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - *offset);
iov_iter_truncate(from, AUX_MAX_OFFSET - pos);
if (!access_ok(VERIFY_READ, buf, bytes_pending)) {
res = -EFAULT;
goto out;
}
while (bytes_pending > 0) {
uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
while (iov_iter_count(from)) {
uint8_t buf[DP_AUX_MAX_PAYLOAD_BYTES];
ssize_t todo = min(iov_iter_count(from), sizeof(buf));
if (signal_pending(current)) {
res = num_bytes_processed ?
num_bytes_processed : -ERESTARTSYS;
goto out;
res = -ERESTARTSYS;
break;
}
if (__copy_from_user(localbuf,
buf + num_bytes_processed, todo)) {
res = num_bytes_processed ?
num_bytes_processed : -EFAULT;
goto out;
if (!copy_from_iter_full(buf, todo, from)) {
res = -EFAULT;
break;
}
res = drm_dp_dpcd_write(aux_dev->aux, *offset, localbuf, todo);
if (res <= 0) {
res = num_bytes_processed ? num_bytes_processed : res;
goto out;
}
bytes_pending -= res;
*offset += res;
num_bytes_processed += res;
res = num_bytes_processed;
res = drm_dp_dpcd_write(aux_dev->aux, pos, buf, todo);
if (res <= 0)
break;
pos += res;
}
out:
if (pos != iocb->ki_pos)
res = pos - iocb->ki_pos;
iocb->ki_pos = pos;
atomic_dec(&aux_dev->usecount);
wake_up_atomic_t(&aux_dev->usecount);
return res;
@ -251,8 +234,8 @@ static int auxdev_release(struct inode *inode, struct file *file)
static const struct file_operations auxdev_fops = {
.owner = THIS_MODULE,
.llseek = auxdev_llseek,
.read = auxdev_read,
.write = auxdev_write,
.read_iter = auxdev_read_iter,
.write_iter = auxdev_write_iter,
.open = auxdev_open,
.release = auxdev_release,
};

View file

@ -146,6 +146,10 @@ static inline int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc)
#endif
drm_ioctl_t drm_version;
drm_ioctl_t drm_getunique;
drm_ioctl_t drm_getclient;
/* drm_syncobj.c */
void drm_syncobj_open(struct drm_file *file_private);
void drm_syncobj_release(struct drm_file *file_private);

File diff suppressed because it is too large Load diff

View file

@ -107,7 +107,7 @@
*
* Copies the bus id from drm_device::unique into user space.
*/
static int drm_getunique(struct drm_device *dev, void *data,
int drm_getunique(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_unique *u = data;
@ -172,7 +172,7 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
* Searches for the client with the specified index and copies its information
* into userspace
*/
static int drm_getclient(struct drm_device *dev, void *data,
int drm_getclient(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_client *client = data;
@ -464,7 +464,7 @@ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
*
* Fills in the version information in \p arg.
*/
static int drm_version(struct drm_device *dev, void *data,
int drm_version(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_version *version = data;
@ -706,6 +706,33 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
* structure.
*/
long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
u32 flags)
{
struct drm_file *file_priv = file->private_data;
struct drm_device *dev = file_priv->minor->dev;
int retcode;
if (drm_device_is_unplugged(dev))
return -ENODEV;
retcode = drm_ioctl_permit(flags, file_priv);
if (unlikely(retcode))
return retcode;
/* Enforce sane locking for modern driver ioctls. */
if (!drm_core_check_feature(dev, DRIVER_LEGACY) ||
(flags & DRM_UNLOCKED))
retcode = func(dev, kdata, file_priv);
else {
mutex_lock(&drm_global_mutex);
retcode = func(dev, kdata, file_priv);
mutex_unlock(&drm_global_mutex);
}
return retcode;
}
EXPORT_SYMBOL(drm_ioctl_kernel);
/**
* drm_ioctl - ioctl callback implementation for DRM drivers
* @filp: file this ioctl is called on
@ -774,10 +801,6 @@ long drm_ioctl(struct file *filp,
goto err_i1;
}
retcode = drm_ioctl_permit(ioctl->flags, file_priv);
if (unlikely(retcode))
goto err_i1;
if (ksize <= sizeof(stack_kdata)) {
kdata = stack_kdata;
} else {
@ -796,16 +819,7 @@ long drm_ioctl(struct file *filp,
if (ksize > in_size)
memset(kdata + in_size, 0, ksize - in_size);
/* Enforce sane locking for modern driver ioctls. */
if (!drm_core_check_feature(dev, DRIVER_LEGACY) ||
(ioctl->flags & DRM_UNLOCKED))
retcode = func(dev, kdata, file_priv);
else {
mutex_lock(&drm_global_mutex);
retcode = func(dev, kdata, file_priv);
mutex_unlock(&drm_global_mutex);
}
retcode = drm_ioctl_kernel(filp, func, kdata, ioctl->flags);
if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
retcode = -EFAULT;

View file

@ -74,6 +74,13 @@ int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f);
int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f);
int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f);
int __drm_legacy_infobufs(struct drm_device *, void *, int *,
int (*)(void *, int, struct drm_buf_entry *));
int __drm_legacy_mapbufs(struct drm_device *, void *, int *,
void __user **,
int (*)(void *, int, unsigned long, struct drm_buf *),
struct drm_file *);
#ifdef CONFIG_DRM_VM
void drm_legacy_vma_flush(struct drm_device *d);
#else

View file

@ -77,17 +77,15 @@ EXPORT_SYMBOL(drm_syncobj_find);
/**
* drm_syncobj_replace_fence - replace fence in a sync object.
* @file_private: drm file private pointer.
* @syncobj: Sync object to replace fence in
* @fence: fence to install in sync file.
*
* This replaces the fence on a sync object.
*/
void drm_syncobj_replace_fence(struct drm_file *file_private,
struct drm_syncobj *syncobj,
void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
struct dma_fence *fence)
{
struct dma_fence *old_fence = NULL;
struct dma_fence *old_fence;
if (fence)
dma_fence_get(fence);
@ -292,7 +290,7 @@ int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
return -ENOENT;
}
drm_syncobj_replace_fence(file_private, syncobj, fence);
drm_syncobj_replace_fence(syncobj, fence);
dma_fence_put(fence);
drm_syncobj_put(syncobj);
return 0;

View file

@ -8,10 +8,38 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- state_hi.xml ( 24309 bytes, from 2015-12-12 09:02:53)
- common.xml ( 18379 bytes, from 2015-12-12 09:02:53)
- state.xml ( 19930 bytes, from 2017-03-09 15:43:43)
- common.xml ( 23473 bytes, from 2017-03-09 15:43:43)
- state_hi.xml ( 26403 bytes, from 2017-03-09 15:43:43)
- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56)
- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56)
- state_3d.xml ( 66957 bytes, from 2017-03-09 15:43:43)
- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56)
Copyright (C) 2015
Copyright (C) 2012-2017 by the following authors:
- Wladimir J. van der Laan <laanwj@gmail.com>
- Christian Gmeiner <christian.gmeiner@gmail.com>
- Lucas Stach <l.stach@pengutronix.de>
- Russell King <rmk@arm.linux.org.uk>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sub license,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
@ -162,129 +190,129 @@ Copyright (C) 2015
#define chipMinorFeatures1_FC_FLUSH_STALL 0x80000000
#define chipMinorFeatures2_LINE_LOOP 0x00000001
#define chipMinorFeatures2_LOGIC_OP 0x00000002
#define chipMinorFeatures2_UNK2 0x00000004
#define chipMinorFeatures2_SEAMLESS_CUBE_MAP 0x00000004
#define chipMinorFeatures2_SUPERTILED_TEXTURE 0x00000008
#define chipMinorFeatures2_UNK4 0x00000010
#define chipMinorFeatures2_LINEAR_PE 0x00000010
#define chipMinorFeatures2_RECT_PRIMITIVE 0x00000020
#define chipMinorFeatures2_COMPOSITION 0x00000040
#define chipMinorFeatures2_CORRECT_AUTO_DISABLE_COUNT 0x00000080
#define chipMinorFeatures2_UNK8 0x00000100
#define chipMinorFeatures2_UNK9 0x00000200
#define chipMinorFeatures2_UNK10 0x00000400
#define chipMinorFeatures2_PE_SWIZZLE 0x00000100
#define chipMinorFeatures2_END_EVENT 0x00000200
#define chipMinorFeatures2_S1S8 0x00000400
#define chipMinorFeatures2_HALTI1 0x00000800
#define chipMinorFeatures2_UNK12 0x00001000
#define chipMinorFeatures2_UNK13 0x00002000
#define chipMinorFeatures2_UNK14 0x00004000
#define chipMinorFeatures2_RGB888 0x00001000
#define chipMinorFeatures2_TX__YUV_ASSEMBLER 0x00002000
#define chipMinorFeatures2_DYNAMIC_FREQUENCY_SCALING 0x00004000
#define chipMinorFeatures2_EXTRA_TEXTURE_STATE 0x00008000
#define chipMinorFeatures2_FULL_DIRECTFB 0x00010000
#define chipMinorFeatures2_2D_TILING 0x00020000
#define chipMinorFeatures2_THREAD_WALKER_IN_PS 0x00040000
#define chipMinorFeatures2_TILE_FILLER 0x00080000
#define chipMinorFeatures2_UNK20 0x00100000
#define chipMinorFeatures2_YUV_STANDARD 0x00100000
#define chipMinorFeatures2_2D_MULTI_SOURCE_BLIT 0x00200000
#define chipMinorFeatures2_UNK22 0x00400000
#define chipMinorFeatures2_UNK23 0x00800000
#define chipMinorFeatures2_UNK24 0x01000000
#define chipMinorFeatures2_YUV_CONVERSION 0x00400000
#define chipMinorFeatures2_FLUSH_FIXED_2D 0x00800000
#define chipMinorFeatures2_INTERLEAVER 0x01000000
#define chipMinorFeatures2_MIXED_STREAMS 0x02000000
#define chipMinorFeatures2_2D_420_L2CACHE 0x04000000
#define chipMinorFeatures2_UNK27 0x08000000
#define chipMinorFeatures2_BUG_FIXES7 0x08000000
#define chipMinorFeatures2_2D_NO_INDEX8_BRUSH 0x10000000
#define chipMinorFeatures2_TEXTURE_TILED_READ 0x20000000
#define chipMinorFeatures2_UNK30 0x40000000
#define chipMinorFeatures2_UNK31 0x80000000
#define chipMinorFeatures2_DECOMPRESS_Z16 0x40000000
#define chipMinorFeatures2_BUG_FIXES8 0x80000000
#define chipMinorFeatures3_ROTATION_STALL_FIX 0x00000001
#define chipMinorFeatures3_UNK1 0x00000002
#define chipMinorFeatures3_OCL_ONLY 0x00000002
#define chipMinorFeatures3_2D_MULTI_SOURCE_BLT_EX 0x00000004
#define chipMinorFeatures3_UNK3 0x00000008
#define chipMinorFeatures3_UNK4 0x00000010
#define chipMinorFeatures3_UNK5 0x00000020
#define chipMinorFeatures3_UNK6 0x00000040
#define chipMinorFeatures3_UNK7 0x00000080
#define chipMinorFeatures3_INSTRUCTION_CACHE 0x00000008
#define chipMinorFeatures3_GEOMETRY_SHADER 0x00000010
#define chipMinorFeatures3_TEX_COMPRESSION_SUPERTILED 0x00000020
#define chipMinorFeatures3_GENERICS 0x00000040
#define chipMinorFeatures3_BUG_FIXES9 0x00000080
#define chipMinorFeatures3_FAST_MSAA 0x00000100
#define chipMinorFeatures3_UNK9 0x00000200
#define chipMinorFeatures3_WCLIP 0x00000200
#define chipMinorFeatures3_BUG_FIXES10 0x00000400
#define chipMinorFeatures3_UNK11 0x00000800
#define chipMinorFeatures3_UNIFIED_SAMPLERS 0x00000800
#define chipMinorFeatures3_BUG_FIXES11 0x00001000
#define chipMinorFeatures3_UNK13 0x00002000
#define chipMinorFeatures3_UNK14 0x00004000
#define chipMinorFeatures3_UNK15 0x00008000
#define chipMinorFeatures3_UNK16 0x00010000
#define chipMinorFeatures3_UNK17 0x00020000
#define chipMinorFeatures3_PERFORMANCE_COUNTERS 0x00002000
#define chipMinorFeatures3_HAS_FAST_TRANSCENDENTALS 0x00004000
#define chipMinorFeatures3_BUG_FIXES12 0x00008000
#define chipMinorFeatures3_BUG_FIXES13 0x00010000
#define chipMinorFeatures3_DE_ENHANCEMENTS1 0x00020000
#define chipMinorFeatures3_ACE 0x00040000
#define chipMinorFeatures3_UNK19 0x00080000
#define chipMinorFeatures3_UNK20 0x00100000
#define chipMinorFeatures3_UNK21 0x00200000
#define chipMinorFeatures3_TX_ENHANCEMENTS1 0x00080000
#define chipMinorFeatures3_SH_ENHANCEMENTS1 0x00100000
#define chipMinorFeatures3_SH_ENHANCEMENTS2 0x00200000
#define chipMinorFeatures3_UNK22 0x00400000
#define chipMinorFeatures3_UNK23 0x00800000
#define chipMinorFeatures3_2D_FC_SOURCE 0x00800000
#define chipMinorFeatures3_UNK24 0x01000000
#define chipMinorFeatures3_UNK25 0x02000000
#define chipMinorFeatures3_NEW_HZ 0x04000000
#define chipMinorFeatures3_UNK27 0x08000000
#define chipMinorFeatures3_UNK28 0x10000000
#define chipMinorFeatures3_UNK29 0x20000000
#define chipMinorFeatures3_SH_ENHANCEMENTS3 0x20000000
#define chipMinorFeatures3_UNK30 0x40000000
#define chipMinorFeatures3_UNK31 0x80000000
#define chipMinorFeatures4_UNK0 0x00000001
#define chipMinorFeatures4_UNK1 0x00000002
#define chipMinorFeatures4_UNK2 0x00000004
#define chipMinorFeatures4_PE_ENHANCEMENTS2 0x00000002
#define chipMinorFeatures4_FRUSTUM_CLIP_FIX 0x00000004
#define chipMinorFeatures4_UNK3 0x00000008
#define chipMinorFeatures4_UNK4 0x00000010
#define chipMinorFeatures4_UNK5 0x00000020
#define chipMinorFeatures4_UNK6 0x00000040
#define chipMinorFeatures4_2D_GAMMA 0x00000020
#define chipMinorFeatures4_SINGLE_BUFFER 0x00000040
#define chipMinorFeatures4_UNK7 0x00000080
#define chipMinorFeatures4_UNK8 0x00000100
#define chipMinorFeatures4_UNK9 0x00000200
#define chipMinorFeatures4_UNK10 0x00000400
#define chipMinorFeatures4_UNK11 0x00000800
#define chipMinorFeatures4_UNK12 0x00001000
#define chipMinorFeatures4_UNK13 0x00002000
#define chipMinorFeatures4_TX_LERP_PRECISION_FIX 0x00000800
#define chipMinorFeatures4_2D_COLOR_SPACE_CONVERSION 0x00001000
#define chipMinorFeatures4_TEXTURE_ASTC 0x00002000
#define chipMinorFeatures4_UNK14 0x00004000
#define chipMinorFeatures4_UNK15 0x00008000
#define chipMinorFeatures4_HALTI2 0x00010000
#define chipMinorFeatures4_UNK17 0x00020000
#define chipMinorFeatures4_SMALL_MSAA 0x00040000
#define chipMinorFeatures4_UNK19 0x00080000
#define chipMinorFeatures4_UNK20 0x00100000
#define chipMinorFeatures4_UNK21 0x00200000
#define chipMinorFeatures4_UNK22 0x00400000
#define chipMinorFeatures4_UNK23 0x00800000
#define chipMinorFeatures4_UNK24 0x01000000
#define chipMinorFeatures4_UNK25 0x02000000
#define chipMinorFeatures4_UNK26 0x04000000
#define chipMinorFeatures4_UNK27 0x08000000
#define chipMinorFeatures4_NEW_RA 0x00100000
#define chipMinorFeatures4_2D_OPF_YUV_OUTPUT 0x00200000
#define chipMinorFeatures4_2D_MULTI_SOURCE_BLT_EX2 0x00400000
#define chipMinorFeatures4_NO_USER_CSC 0x00800000
#define chipMinorFeatures4_ZFIXES 0x01000000
#define chipMinorFeatures4_BUG_FIXES18 0x02000000
#define chipMinorFeatures4_2D_COMPRESSION 0x04000000
#define chipMinorFeatures4_PROBE 0x08000000
#define chipMinorFeatures4_UNK28 0x10000000
#define chipMinorFeatures4_UNK29 0x20000000
#define chipMinorFeatures4_2D_SUPER_TILE_VERSION 0x20000000
#define chipMinorFeatures4_UNK30 0x40000000
#define chipMinorFeatures4_UNK31 0x80000000
#define chipMinorFeatures5_UNK0 0x00000001
#define chipMinorFeatures5_UNK1 0x00000002
#define chipMinorFeatures5_UNK2 0x00000004
#define chipMinorFeatures5_UNK3 0x00000008
#define chipMinorFeatures5_UNK4 0x00000010
#define chipMinorFeatures5_EEZ 0x00000010
#define chipMinorFeatures5_UNK5 0x00000020
#define chipMinorFeatures5_UNK6 0x00000040
#define chipMinorFeatures5_UNK7 0x00000080
#define chipMinorFeatures5_UNK8 0x00000100
#define chipMinorFeatures5_HALTI3 0x00000200
#define chipMinorFeatures5_UNK10 0x00000400
#define chipMinorFeatures5_UNK11 0x00000800
#define chipMinorFeatures5_2D_ONE_PASS_FILTER_TAP 0x00000800
#define chipMinorFeatures5_UNK12 0x00001000
#define chipMinorFeatures5_UNK13 0x00002000
#define chipMinorFeatures5_UNK14 0x00004000
#define chipMinorFeatures5_SEPARATE_SRC_DST 0x00002000
#define chipMinorFeatures5_HALTI4 0x00004000
#define chipMinorFeatures5_UNK15 0x00008000
#define chipMinorFeatures5_UNK16 0x00010000
#define chipMinorFeatures5_UNK17 0x00020000
#define chipMinorFeatures5_ANDROID_ONLY 0x00010000
#define chipMinorFeatures5_HAS_PRODUCTID 0x00020000
#define chipMinorFeatures5_UNK18 0x00040000
#define chipMinorFeatures5_UNK19 0x00080000
#define chipMinorFeatures5_UNK20 0x00100000
#define chipMinorFeatures5_PE_DITHER_FIX2 0x00100000
#define chipMinorFeatures5_UNK21 0x00200000
#define chipMinorFeatures5_UNK22 0x00400000
#define chipMinorFeatures5_UNK23 0x00800000
#define chipMinorFeatures5_UNK24 0x01000000
#define chipMinorFeatures5_UNK25 0x02000000
#define chipMinorFeatures5_UNK26 0x04000000
#define chipMinorFeatures5_UNK27 0x08000000
#define chipMinorFeatures5_UNK28 0x10000000
#define chipMinorFeatures5_RS_DEPTHSTENCIL_NATIVE_SUPPORT 0x08000000
#define chipMinorFeatures5_V2_MSAA_COMP_FIX 0x10000000
#define chipMinorFeatures5_UNK29 0x20000000
#define chipMinorFeatures5_UNK30 0x40000000
#define chipMinorFeatures5_UNK31 0x80000000

View file

@ -495,6 +495,7 @@ static struct drm_driver etnaviv_drm_driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_import = drm_gem_prime_import,
.gem_prime_res_obj = etnaviv_gem_prime_res_obj,
.gem_prime_pin = etnaviv_gem_prime_pin,
.gem_prime_unpin = etnaviv_gem_prime_unpin,
.gem_prime_get_sg_table = etnaviv_gem_prime_get_sg_table,

View file

@ -80,6 +80,7 @@ void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj);
void etnaviv_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
int etnaviv_gem_prime_mmap(struct drm_gem_object *obj,
struct vm_area_struct *vma);
struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj);
struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach, struct sg_table *sg);
int etnaviv_gem_prime_pin(struct drm_gem_object *obj);

View file

@ -411,16 +411,20 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
struct drm_device *dev = obj->dev;
bool write = !!(op & ETNA_PREP_WRITE);
unsigned long remain =
op & ETNA_PREP_NOSYNC ? 0 : etnaviv_timeout_to_jiffies(timeout);
long lret;
int ret;
lret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv,
write, true, remain);
if (lret < 0)
return lret;
else if (lret == 0)
return remain == 0 ? -EBUSY : -ETIMEDOUT;
if (op & ETNA_PREP_NOSYNC) {
if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv,
write))
return -EBUSY;
} else {
unsigned long remain = etnaviv_timeout_to_jiffies(timeout);
ret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv,
write, true, remain);
if (ret <= 0)
return ret == 0 ? -ETIMEDOUT : ret;
}
if (etnaviv_obj->flags & ETNA_BO_CACHED) {
if (!etnaviv_obj->sgt) {

View file

@ -106,9 +106,10 @@ struct etnaviv_gem_submit {
struct etnaviv_gpu *gpu;
struct ww_acquire_ctx ticket;
struct dma_fence *fence;
u32 flags;
unsigned int nr_bos;
struct etnaviv_gem_submit_bo bos[0];
u32 flags;
/* No new members here, the previous one is variable-length! */
};
int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct drm_gem_object *obj,

View file

@ -150,3 +150,10 @@ fail:
return ERR_PTR(ret);
}
struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
return etnaviv_obj->resv;
}

View file

@ -172,7 +172,7 @@ static int submit_fence_sync(const struct etnaviv_gem_submit *submit)
for (i = 0; i < submit->nr_bos; i++) {
struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE;
bool explicit = !(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
bool explicit = !!(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
ret = etnaviv_gpu_fence_sync_obj(etnaviv_obj, context, write,
explicit);
@ -270,8 +270,8 @@ static int submit_reloc(struct etnaviv_gem_submit *submit, void *stream,
if (ret)
return ret;
if (r->reloc_offset >= bo->obj->base.size - sizeof(*ptr)) {
DRM_ERROR("relocation %u outside object", i);
if (r->reloc_offset > bo->obj->base.size - sizeof(*ptr)) {
DRM_ERROR("relocation %u outside object\n", i);
return -EINVAL;
}

View file

@ -412,13 +412,19 @@ static void etnaviv_gpu_load_clock(struct etnaviv_gpu *gpu, u32 clock)
static void etnaviv_gpu_update_clock(struct etnaviv_gpu *gpu)
{
unsigned int fscale = 1 << (6 - gpu->freq_scale);
u32 clock;
if (gpu->identity.minor_features2 &
chipMinorFeatures2_DYNAMIC_FREQUENCY_SCALING) {
clk_set_rate(gpu->clk_core,
gpu->base_rate_core >> gpu->freq_scale);
clk_set_rate(gpu->clk_shader,
gpu->base_rate_shader >> gpu->freq_scale);
} else {
unsigned int fscale = 1 << (6 - gpu->freq_scale);
u32 clock = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale);
clock = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale);
etnaviv_gpu_load_clock(gpu, clock);
etnaviv_gpu_load_clock(gpu, clock);
}
}
static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
@ -523,9 +529,10 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
/* Disable PA clock gating for GC400+ except for GC420 */
/* Disable PA clock gating for GC400+ without bugfix except for GC420 */
if (gpu->identity.model >= chipModel_GC400 &&
gpu->identity.model != chipModel_GC420)
gpu->identity.model != chipModel_GC420 &&
!(gpu->identity.minor_features3 & chipMinorFeatures3_BUG_FIXES12))
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_PA;
/*
@ -541,6 +548,11 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
if (gpu->identity.revision < 0x5422)
pmc |= BIT(15); /* Unknown bit */
/* Disable TX clock gating on affected core revisions. */
if (etnaviv_is_model_rev(gpu, GC4000, 0x5222) ||
etnaviv_is_model_rev(gpu, GC2000, 0x5108))
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;
@ -1736,11 +1748,13 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
DBG("clk_core: %p", gpu->clk_core);
if (IS_ERR(gpu->clk_core))
gpu->clk_core = NULL;
gpu->base_rate_core = clk_get_rate(gpu->clk_core);
gpu->clk_shader = devm_clk_get(&pdev->dev, "shader");
DBG("clk_shader: %p", gpu->clk_shader);
if (IS_ERR(gpu->clk_shader))
gpu->clk_shader = NULL;
gpu->base_rate_shader = clk_get_rate(gpu->clk_shader);
/* TODO: figure out max mapped size */
dev_set_drvdata(dev, gpu);

View file

@ -152,6 +152,8 @@ struct etnaviv_gpu {
u32 hangcheck_dma_addr;
struct work_struct recover_work;
unsigned int freq_scale;
unsigned long base_rate_core;
unsigned long base_rate_shader;
};
static inline void gpu_write(struct etnaviv_gpu *gpu, u32 reg, u32 data)

View file

@ -75,6 +75,7 @@ config DRM_EXYNOS_DP
config DRM_EXYNOS_HDMI
bool "HDMI"
depends on DRM_EXYNOS_MIXER || DRM_EXYNOS5433_DECON
select CEC_CORE if CEC_NOTIFIER
help
Choose this option if you want to use Exynos HDMI for DRM.

View file

@ -453,7 +453,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
struct component_match *match;
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
match = exynos_drm_match_add(&pdev->dev);
if (IS_ERR(match))

View file

@ -1651,8 +1651,6 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
return ret;
dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
if (!dsi->bridge_node)
return -EINVAL;
return 0;
}
@ -1687,9 +1685,11 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
return ret;
}
bridge = of_drm_find_bridge(dsi->bridge_node);
if (bridge)
drm_bridge_attach(encoder, bridge, NULL);
if (dsi->bridge_node) {
bridge = of_drm_find_bridge(dsi->bridge_node);
if (bridge)
drm_bridge_attach(encoder, bridge, NULL);
}
return mipi_dsi_host_register(&dsi->dsi_host);
}

View file

@ -145,13 +145,19 @@ static struct drm_framebuffer *
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
const struct drm_format_info *info = drm_get_format_info(dev, mode_cmd);
struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
int i;
int ret;
for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) {
for (i = 0; i < info->num_planes; i++) {
unsigned int height = (i == 0) ? mode_cmd->height :
DIV_ROUND_UP(mode_cmd->height, info->vsub);
unsigned long size = height * mode_cmd->pitches[i] +
mode_cmd->offsets[i];
obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
@ -160,6 +166,12 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
}
exynos_gem[i] = to_exynos_gem(obj);
if (size > exynos_gem[i]->size) {
i++;
ret = -EINVAL;
goto err;
}
}
fb = exynos_drm_framebuffer_init(dev, mode_cmd, exynos_gem, i);
@ -181,8 +193,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
if (index >= MAX_FB_BUFFER)
return DMA_ERROR_CODE;
if (WARN_ON_ONCE(index >= MAX_FB_BUFFER))
return 0;
return exynos_fb->dma_addr[index];
}

View file

@ -340,16 +340,10 @@ static int exynos_mic_bind(struct device *dev, struct device *master,
void *data)
{
struct exynos_mic *mic = dev_get_drvdata(dev);
int ret;
mic->bridge.funcs = &mic_bridge_funcs;
mic->bridge.of_node = dev->of_node;
mic->bridge.driver_private = mic;
ret = drm_bridge_add(&mic->bridge);
if (ret)
DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
return ret;
return 0;
}
static void exynos_mic_unbind(struct device *dev, struct device *master,
@ -365,8 +359,6 @@ static void exynos_mic_unbind(struct device *dev, struct device *master,
already_disabled:
mutex_unlock(&mic_mutex);
drm_bridge_remove(&mic->bridge);
}
static const struct component_ops exynos_mic_component_ops = {
@ -461,6 +453,15 @@ static int exynos_mic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mic);
mic->bridge.funcs = &mic_bridge_funcs;
mic->bridge.of_node = dev->of_node;
ret = drm_bridge_add(&mic->bridge);
if (ret) {
DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
return ret;
}
pm_runtime_enable(dev);
ret = component_add(dev, &exynos_mic_component_ops);
@ -479,8 +480,13 @@ err:
static int exynos_mic_remove(struct platform_device *pdev)
{
struct exynos_mic *mic = platform_get_drvdata(pdev);
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
drm_bridge_remove(&mic->bridge);
return 0;
}

View file

@ -1501,8 +1501,6 @@ static void hdmi_disable(struct drm_encoder *encoder)
*/
cancel_delayed_work(&hdata->hotplug_work);
cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
hdmiphy_disable(hdata);
}
static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@ -1676,7 +1674,7 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
return hdmi_bridge_init(hdata);
}
static struct of_device_id hdmi_match_types[] = {
static const struct of_device_id hdmi_match_types[] = {
{
.compatible = "samsung,exynos4210-hdmi",
.data = &exynos4210_hdmi_driver_data,
@ -1934,8 +1932,7 @@ static int hdmi_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM
static int exynos_hdmi_suspend(struct device *dev)
static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
{
struct hdmi_context *hdata = dev_get_drvdata(dev);
@ -1944,7 +1941,7 @@ static int exynos_hdmi_suspend(struct device *dev)
return 0;
}
static int exynos_hdmi_resume(struct device *dev)
static int __maybe_unused exynos_hdmi_resume(struct device *dev)
{
struct hdmi_context *hdata = dev_get_drvdata(dev);
int ret;
@ -1955,7 +1952,6 @@ static int exynos_hdmi_resume(struct device *dev)
return 0;
}
#endif
static const struct dev_pm_ops exynos_hdmi_pm_ops = {
SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)

View file

@ -1094,28 +1094,28 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
.atomic_check = mixer_atomic_check,
};
static struct mixer_drv_data exynos5420_mxr_drv_data = {
static const struct mixer_drv_data exynos5420_mxr_drv_data = {
.version = MXR_VER_128_0_0_184,
.is_vp_enabled = 0,
};
static struct mixer_drv_data exynos5250_mxr_drv_data = {
static const struct mixer_drv_data exynos5250_mxr_drv_data = {
.version = MXR_VER_16_0_33_0,
.is_vp_enabled = 0,
};
static struct mixer_drv_data exynos4212_mxr_drv_data = {
static const struct mixer_drv_data exynos4212_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
};
static struct mixer_drv_data exynos4210_mxr_drv_data = {
static const struct mixer_drv_data exynos4210_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
.has_sclk = 1,
};
static struct of_device_id mixer_match_types[] = {
static const struct of_device_id mixer_match_types[] = {
{
.compatible = "samsung,exynos4210-mixer",
.data = &exynos4210_mxr_drv_data,

View file

@ -2536,6 +2536,11 @@ static int scan_workload(struct intel_vgpu_workload *workload)
gma_head == gma_tail)
return 0;
if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
ret = -EINVAL;
goto out;
}
ret = ip_gma_set(&s, gma_head);
if (ret)
goto out;
@ -2579,6 +2584,11 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
s.rb_va = wa_ctx->indirect_ctx.shadow_va;
s.workload = workload;
if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
ret = -EINVAL;
goto out;
}
ret = ip_gma_set(&s, gma_head);
if (ret)
goto out;

View file

@ -197,6 +197,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_B << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
if (IS_BROADWELL(dev_priv)) {
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_B)) &=
~PORT_CLK_SEL_MASK;
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_B)) |=
PORT_CLK_SEL_LCPLL_810;
}
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_B)) |= DDI_BUF_CTL_ENABLE;
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_B)) &= ~DDI_BUF_IS_IDLE;
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
@ -211,6 +217,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_C << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
if (IS_BROADWELL(dev_priv)) {
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_C)) &=
~PORT_CLK_SEL_MASK;
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_C)) |=
PORT_CLK_SEL_LCPLL_810;
}
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_C)) |= DDI_BUF_CTL_ENABLE;
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_C)) &= ~DDI_BUF_IS_IDLE;
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
@ -225,6 +237,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_D << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
if (IS_BROADWELL(dev_priv)) {
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_D)) &=
~PORT_CLK_SEL_MASK;
vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_D)) |=
PORT_CLK_SEL_LCPLL_810;
}
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_D)) |= DDI_BUF_CTL_ENABLE;
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_D)) &= ~DDI_BUF_IS_IDLE;
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
@ -244,6 +262,10 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED;
}
/* Clear host CRT status, so guest couldn't detect this host CRT. */
if (IS_BROADWELL(dev_priv))
vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
}
static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
@ -301,27 +323,27 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt)
{
struct intel_gvt_irq *irq = &gvt->irq;
struct intel_vgpu *vgpu;
bool have_enabled_pipe = false;
int pipe, id;
if (WARN_ON(!mutex_is_locked(&gvt->lock)))
return;
hrtimer_cancel(&irq->vblank_timer.timer);
for_each_active_vgpu(gvt, vgpu, id) {
for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) {
have_enabled_pipe =
pipe_is_enabled(vgpu, pipe);
if (have_enabled_pipe)
break;
if (pipe_is_enabled(vgpu, pipe))
goto out;
}
}
if (have_enabled_pipe)
hrtimer_start(&irq->vblank_timer.timer,
ktime_add_ns(ktime_get(), irq->vblank_timer.period),
HRTIMER_MODE_ABS);
/* all the pipes are disabled */
hrtimer_cancel(&irq->vblank_timer.timer);
return;
out:
hrtimer_start(&irq->vblank_timer.timer,
ktime_add_ns(ktime_get(), irq->vblank_timer.period),
HRTIMER_MODE_ABS);
}
static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)

View file

@ -46,6 +46,8 @@
#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
((a)->lrca == (b)->lrca))
static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask);
static int context_switch_events[] = {
[RCS] = RCS_AS_CONTEXT_SWITCH,
[BCS] = BCS_AS_CONTEXT_SWITCH,
@ -499,10 +501,10 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
static int complete_execlist_workload(struct intel_vgpu_workload *workload)
{
struct intel_vgpu *vgpu = workload->vgpu;
struct intel_vgpu_execlist *execlist =
&vgpu->execlist[workload->ring_id];
int ring_id = workload->ring_id;
struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id];
struct intel_vgpu_workload *next_workload;
struct list_head *next = workload_q_head(vgpu, workload->ring_id)->next;
struct list_head *next = workload_q_head(vgpu, ring_id)->next;
bool lite_restore = false;
int ret;
@ -512,10 +514,25 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload)
release_shadow_batch_buffer(workload);
release_shadow_wa_ctx(&workload->wa_ctx);
if (workload->status || vgpu->resetting)
if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) {
/* if workload->status is not successful means HW GPU
* has occurred GPU hang or something wrong with i915/GVT,
* and GVT won't inject context switch interrupt to guest.
* So this error is a vGPU hang actually to the guest.
* According to this we should emunlate a vGPU hang. If
* there are pending workloads which are already submitted
* from guest, we should clean them up like HW GPU does.
*
* if it is in middle of engine resetting, the pending
* workloads won't be submitted to HW GPU and will be
* cleaned up during the resetting process later, so doing
* the workload clean up here doesn't have any impact.
**/
clean_workloads(vgpu, ENGINE_MASK(ring_id));
goto out;
}
if (!list_empty(workload_q_head(vgpu, workload->ring_id))) {
if (!list_empty(workload_q_head(vgpu, ring_id))) {
struct execlist_ctx_descriptor_format *this_desc, *next_desc;
next_workload = container_of(next,

View file

@ -72,11 +72,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
struct intel_gvt_mmio_info *e;
struct gvt_mmio_block *block = gvt->mmio.mmio_block;
int num = gvt->mmio.num_mmio_block;
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
int i;
int i, j;
int ret;
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
@ -105,6 +107,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
hash_for_each(gvt->mmio.mmio_info_table, i, e, node)
*(u32 *)(p + e->offset) = I915_READ_NOTRACE(_MMIO(e->offset));
for (i = 0; i < num; i++, block++) {
for (j = 0; j < block->size; j += 4)
*(u32 *)(p + INTEL_GVT_MMIO_OFFSET(block->offset) + j) =
I915_READ_NOTRACE(_MMIO(INTEL_GVT_MMIO_OFFSET(
block->offset) + j));
}
memcpy(gvt->firmware.mmio, p, info->mmio_size);
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;

View file

@ -2259,6 +2259,8 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
ret = setup_spt_oos(gvt);
if (ret) {
gvt_err("fail to initialize SPT oos\n");
dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL);
__free_page(gvt->gtt.scratch_ggtt_page);
return ret;
}
}

View file

@ -149,7 +149,7 @@ struct intel_vgpu {
bool active;
bool pv_notified;
bool failsafe;
bool resetting;
unsigned int resetting_eng;
void *sched_data;
struct vgpu_sched_ctl sched_ctl;
@ -195,6 +195,15 @@ struct intel_gvt_fence {
unsigned long vgpu_allocated_fence_num;
};
/* Special MMIO blocks. */
struct gvt_mmio_block {
unsigned int device;
i915_reg_t offset;
unsigned int size;
gvt_mmio_func read;
gvt_mmio_func write;
};
#define INTEL_GVT_MMIO_HASH_BITS 11
struct intel_gvt_mmio {
@ -214,6 +223,9 @@ struct intel_gvt_mmio {
/* This reg could be accessed by unaligned address */
#define F_UNALIGN (1 << 6)
struct gvt_mmio_block *mmio_block;
unsigned int num_mmio_block;
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
unsigned int num_tracked_mmio;
};

View file

@ -367,21 +367,24 @@ static int lcpll_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
static int dpy_reg_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
*(u32 *)p_data = (1 << 17);
return 0;
}
switch (offset) {
case 0xe651c:
case 0xe661c:
case 0xe671c:
case 0xe681c:
vgpu_vreg(vgpu, offset) = 1 << 17;
break;
case 0xe6c04:
vgpu_vreg(vgpu, offset) = 0x3;
break;
case 0xe6e1c:
vgpu_vreg(vgpu, offset) = 0x2f << 16;
break;
default:
return -EINVAL;
}
static int dpy_reg_mmio_read_2(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
*(u32 *)p_data = 3;
return 0;
}
static int dpy_reg_mmio_read_3(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
*(u32 *)p_data = (0x2f << 16);
read_vreg(vgpu, offset, p_data, bytes);
return 0;
}
@ -1925,7 +1928,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_F(_PCH_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
dp_aux_ch_ctl_mmio_write);
MMIO_RO(PCH_ADPA, D_ALL, 0, ADPA_CRT_HOTPLUG_MONITOR_MASK, NULL, pch_adpa_mmio_write);
MMIO_DH(PCH_ADPA, D_PRE_SKL, NULL, pch_adpa_mmio_write);
MMIO_DH(_PCH_TRANSACONF, D_ALL, NULL, transconf_mmio_write);
MMIO_DH(_PCH_TRANSBCONF, D_ALL, NULL, transconf_mmio_write);
@ -2011,8 +2014,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_DH(0xe661c, D_ALL, dpy_reg_mmio_read, NULL);
MMIO_DH(0xe671c, D_ALL, dpy_reg_mmio_read, NULL);
MMIO_DH(0xe681c, D_ALL, dpy_reg_mmio_read, NULL);
MMIO_DH(0xe6c04, D_ALL, dpy_reg_mmio_read_2, NULL);
MMIO_DH(0xe6e1c, D_ALL, dpy_reg_mmio_read_3, NULL);
MMIO_DH(0xe6c04, D_ALL, dpy_reg_mmio_read, NULL);
MMIO_DH(0xe6e1c, D_ALL, dpy_reg_mmio_read, NULL);
MMIO_RO(PCH_PORT_HOTPLUG, D_ALL, 0,
PORTA_HOTPLUG_STATUS_MASK
@ -2854,31 +2857,15 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
return 0;
}
/* Special MMIO blocks. */
static struct gvt_mmio_block {
unsigned int device;
i915_reg_t offset;
unsigned int size;
gvt_mmio_func read;
gvt_mmio_func write;
} gvt_mmio_blocks[] = {
{D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
{D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
{D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
pvinfo_mmio_read, pvinfo_mmio_write},
{D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
{D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
{D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
};
static struct gvt_mmio_block *find_mmio_block(struct intel_gvt *gvt,
unsigned int offset)
{
unsigned long device = intel_gvt_get_device_type(gvt);
struct gvt_mmio_block *block = gvt_mmio_blocks;
struct gvt_mmio_block *block = gvt->mmio.mmio_block;
int num = gvt->mmio.num_mmio_block;
int i;
for (i = 0; i < ARRAY_SIZE(gvt_mmio_blocks); i++, block++) {
for (i = 0; i < num; i++, block++) {
if (!(device & block->device))
continue;
if (offset >= INTEL_GVT_MMIO_OFFSET(block->offset) &&
@ -2909,6 +2896,17 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt)
gvt->mmio.mmio_attribute = NULL;
}
/* Special MMIO blocks. */
static struct gvt_mmio_block mmio_blocks[] = {
{D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
{D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
{D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
pvinfo_mmio_read, pvinfo_mmio_write},
{D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
{D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
{D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
};
/**
* intel_gvt_setup_mmio_info - setup MMIO information table for GVT device
* @gvt: GVT device
@ -2948,6 +2946,9 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt)
goto err;
}
gvt->mmio.mmio_block = mmio_blocks;
gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks);
gvt_dbg_mmio("traced %u virtual mmio registers\n",
gvt->mmio.num_tracked_mmio);
return 0;
@ -3027,7 +3028,7 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset,
gvt_mmio_func func;
int ret;
if (WARN_ON(bytes > 4))
if (WARN_ON(bytes > 8))
return -EINVAL;
/*

View file

@ -232,16 +232,20 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
struct device *dev = mdev_dev(vgpu->vdev.mdev);
unsigned long gfn;
mutex_lock(&vgpu->vdev.cache_lock);
while ((node = rb_first(&vgpu->vdev.cache))) {
for (;;) {
mutex_lock(&vgpu->vdev.cache_lock);
node = rb_first(&vgpu->vdev.cache);
if (!node) {
mutex_unlock(&vgpu->vdev.cache_lock);
break;
}
dma = rb_entry(node, struct gvt_dma, node);
gvt_dma_unmap_iova(vgpu, dma->iova);
gfn = dma->gfn;
vfio_unpin_pages(dev, &gfn, 1);
__gvt_cache_remove_entry(vgpu, dma);
mutex_unlock(&vgpu->vdev.cache_lock);
vfio_unpin_pages(dev, &gfn, 1);
}
mutex_unlock(&vgpu->vdev.cache_lock);
}
static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt,

View file

@ -174,15 +174,6 @@ static int shadow_context_status_change(struct notifier_block *nb,
atomic_set(&workload->shadow_ctx_active, 1);
break;
case INTEL_CONTEXT_SCHEDULE_OUT:
/* If the status is -EINPROGRESS means this workload
* doesn't meet any issue during dispatching so when
* get the SCHEDULE_OUT set the status to be zero for
* good. If the status is NOT -EINPROGRESS means there
* is something wrong happened during dispatching and
* the status should not be set to zero
*/
if (workload->status == -EINPROGRESS)
workload->status = 0;
atomic_set(&workload->shadow_ctx_active, 0);
break;
default:
@ -427,9 +418,22 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
wait_event(workload->shadow_ctx_status_wq,
!atomic_read(&workload->shadow_ctx_active));
/* If this request caused GPU hang, req->fence.error will
* be set to -EIO. Use -EIO to set workload status so
* that when this request caused GPU hang, didn't trigger
* context switch interrupt to guest.
*/
if (likely(workload->status == -EINPROGRESS)) {
if (workload->req->fence.error == -EIO)
workload->status = -EIO;
else
workload->status = 0;
}
i915_gem_request_put(fetch_and_zero(&workload->req));
if (!workload->status && !vgpu->resetting) {
if (!workload->status && !(vgpu->resetting_eng &
ENGINE_MASK(ring_id))) {
update_guest_context(workload);
for_each_set_bit(event, workload->pending_events,
@ -464,8 +468,6 @@ struct workload_thread_param {
int ring_id;
};
static DEFINE_MUTEX(scheduler_mutex);
static int workload_thread(void *priv)
{
struct workload_thread_param *p = (struct workload_thread_param *)priv;
@ -497,8 +499,6 @@ static int workload_thread(void *priv)
if (!workload)
break;
mutex_lock(&scheduler_mutex);
gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
workload->ring_id, workload,
workload->vgpu->id);
@ -537,9 +537,6 @@ complete:
FORCEWAKE_ALL);
intel_runtime_pm_put(gvt->dev_priv);
mutex_unlock(&scheduler_mutex);
}
return 0;
}

View file

@ -480,11 +480,13 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
{
struct intel_gvt *gvt = vgpu->gvt;
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
unsigned int resetting_eng = dmlr ? ALL_ENGINES : engine_mask;
gvt_dbg_core("------------------------------------------\n");
gvt_dbg_core("resseting vgpu%d, dmlr %d, engine_mask %08x\n",
vgpu->id, dmlr, engine_mask);
vgpu->resetting = true;
vgpu->resetting_eng = resetting_eng;
intel_vgpu_stop_schedule(vgpu);
/*
@ -497,7 +499,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
mutex_lock(&gvt->lock);
}
intel_vgpu_reset_execlist(vgpu, dmlr ? ALL_ENGINES : engine_mask);
intel_vgpu_reset_execlist(vgpu, resetting_eng);
/* full GPU reset or device model level reset */
if (engine_mask == ALL_ENGINES || dmlr) {
@ -520,7 +522,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
}
}
vgpu->resetting = false;
vgpu->resetting_eng = 0;
gvt_dbg_core("reset vgpu%d done\n", vgpu->id);
gvt_dbg_core("------------------------------------------\n");
}

View file

@ -292,6 +292,8 @@ static int per_file_stats(int id, void *ptr, void *data)
struct file_stats *stats = data;
struct i915_vma *vma;
lockdep_assert_held(&obj->base.dev->struct_mutex);
stats->count++;
stats->total += obj->base.size;
if (!obj->bind_count)
@ -476,6 +478,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
struct drm_i915_gem_request *request;
struct task_struct *task;
mutex_lock(&dev->struct_mutex);
memset(&stats, 0, sizeof(stats));
stats.file_priv = file->driver_priv;
spin_lock(&file->table_lock);
@ -487,7 +491,6 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
* still alive (e.g. get_pid(current) => fork() => exit()).
* Therefore, we need to protect this ->comm access using RCU.
*/
mutex_lock(&dev->struct_mutex);
request = list_first_entry_or_null(&file_priv->mm.request_list,
struct drm_i915_gem_request,
client_link);
@ -497,6 +500,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
PIDTYPE_PID);
print_file_stats(m, task ? task->comm : "<unknown>", stats);
rcu_read_unlock();
mutex_unlock(&dev->struct_mutex);
}
mutex_unlock(&dev->filelist_mutex);
@ -3083,7 +3087,7 @@ static void intel_connector_info(struct seq_file *m,
connector->display_info.cea_rev);
}
if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
if (!intel_encoder)
return;
switch (connector->connector_type) {

View file

@ -1132,10 +1132,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
* and the registers being closely associated.
*
* According to chipset errata, on the 965GM, MSI interrupts may
* be lost or delayed, but we use them anyways to avoid
* stuck interrupts on some machines.
* be lost or delayed, and was defeatured. MSI interrupts seem to
* get lost on g4x as well, and interrupt delivery seems to stay
* properly dead afterwards. So we'll just disable them for all
* pre-gen5 chipsets.
*/
if (!IS_I945G(dev_priv) && !IS_I945GM(dev_priv)) {
if (INTEL_GEN(dev_priv) >= 5) {
if (pci_enable_msi(pdev) < 0)
DRM_DEBUG_DRIVER("can't enable MSI");
}

View file

@ -2434,8 +2434,9 @@ rebuild_st:
* again with !__GFP_NORETRY. However, we still
* want to fail this allocation rather than
* trigger the out-of-memory killer and for
* this we want the future __GFP_MAYFAIL.
* this we want __GFP_RETRY_MAYFAIL.
*/
gfp |= __GFP_RETRY_MAYFAIL;
}
} while (1);

View file

@ -114,7 +114,7 @@ i915_clflush_notify(struct i915_sw_fence *fence,
return NOTIFY_DONE;
}
void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
unsigned int flags)
{
struct clflush *clflush;
@ -128,7 +128,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
*/
if (!i915_gem_object_has_struct_page(obj)) {
obj->cache_dirty = false;
return;
return false;
}
/* If the GPU is snooping the contents of the CPU cache,
@ -140,7 +140,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
* tracking.
*/
if (!(flags & I915_CLFLUSH_FORCE) && obj->cache_coherent)
return;
return false;
trace_i915_gem_object_clflush(obj);
@ -179,4 +179,5 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
}
obj->cache_dirty = false;
return true;
}

View file

@ -28,7 +28,7 @@
struct drm_i915_private;
struct drm_i915_gem_object;
void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
unsigned int flags);
#define I915_CLFLUSH_FORCE BIT(0)
#define I915_CLFLUSH_SYNC BIT(1)

View file

@ -288,20 +288,26 @@ static int eb_create(struct i915_execbuffer *eb)
* direct lookup.
*/
do {
unsigned int flags;
/* While we can still reduce the allocation size, don't
* raise a warning and allow the allocation to fail.
* On the last pass though, we want to try as hard
* as possible to perform the allocation and warn
* if it fails.
*/
flags = GFP_TEMPORARY;
if (size > 1)
flags |= __GFP_NORETRY | __GFP_NOWARN;
eb->buckets = kzalloc(sizeof(struct hlist_head) << size,
GFP_TEMPORARY |
__GFP_NORETRY |
__GFP_NOWARN);
flags);
if (eb->buckets)
break;
} while (--size);
if (unlikely(!eb->buckets)) {
eb->buckets = kzalloc(sizeof(struct hlist_head),
GFP_TEMPORARY);
if (unlikely(!eb->buckets))
return -ENOMEM;
}
if (unlikely(!size))
return -ENOMEM;
eb->lut_size = size;
} else {
@ -452,7 +458,7 @@ eb_add_vma(struct i915_execbuffer *eb,
return err;
}
if (eb->lut_size >= 0) {
if (eb->lut_size > 0) {
vma->exec_handle = entry->handle;
hlist_add_head(&vma->exec_node,
&eb->buckets[hash_32(entry->handle,
@ -554,9 +560,6 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
eb->args->flags |= __EXEC_HAS_RELOC;
}
entry->flags |= __EXEC_OBJECT_HAS_PIN;
GEM_BUG_ON(eb_vma_misplaced(entry, vma));
if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) {
err = i915_vma_get_fence(vma);
if (unlikely(err)) {
@ -568,6 +571,9 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
entry->flags |= __EXEC_OBJECT_HAS_FENCE;
}
entry->flags |= __EXEC_OBJECT_HAS_PIN;
GEM_BUG_ON(eb_vma_misplaced(entry, vma));
return 0;
}
@ -878,6 +884,7 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
GEM_BUG_ON(vma->exec_entry != entry);
vma->exec_entry = NULL;
__exec_to_vma(entry) = 0;
if (entry->flags & __EXEC_OBJECT_HAS_PIN)
__eb_unreserve_vma(vma, entry);
@ -893,7 +900,7 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
static void eb_reset_vmas(const struct i915_execbuffer *eb)
{
eb_release_vmas(eb);
if (eb->lut_size >= 0)
if (eb->lut_size > 0)
memset(eb->buckets, 0,
sizeof(struct hlist_head) << eb->lut_size);
}
@ -902,7 +909,7 @@ static void eb_destroy(const struct i915_execbuffer *eb)
{
GEM_BUG_ON(eb->reloc_cache.rq);
if (eb->lut_size >= 0)
if (eb->lut_size > 0)
kfree(eb->buckets);
}
@ -1199,7 +1206,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
reservation_object_unlock(batch->resv);
i915_vma_unpin(batch);
i915_vma_move_to_active(vma, rq, true);
i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
reservation_object_lock(vma->resv, NULL);
reservation_object_add_excl_fence(vma->resv, &rq->fence);
reservation_object_unlock(vma->resv);
@ -1451,7 +1458,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
* to read. However, if the array is not writable the user loses
* the updated relocation values.
*/
if (unlikely(!access_ok(VERIFY_READ, urelocs, remain*sizeof(urelocs))))
if (unlikely(!access_ok(VERIFY_READ, urelocs, remain*sizeof(*urelocs))))
return -EFAULT;
do {
@ -1768,7 +1775,7 @@ out:
}
}
return err ?: have_copy;
return err;
}
static int eb_relocate(struct i915_execbuffer *eb)
@ -1818,7 +1825,7 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
int err;
for (i = 0; i < count; i++) {
const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
struct i915_vma *vma = exec_to_vma(entry);
struct drm_i915_gem_object *obj = vma->obj;
@ -1834,12 +1841,14 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
eb->request->capture_list = capture;
}
if (unlikely(obj->cache_dirty && !obj->cache_coherent)) {
if (i915_gem_clflush_object(obj, 0))
entry->flags &= ~EXEC_OBJECT_ASYNC;
}
if (entry->flags & EXEC_OBJECT_ASYNC)
goto skip_flushes;
if (unlikely(obj->cache_dirty && !obj->cache_coherent))
i915_gem_clflush_object(obj, 0);
err = i915_gem_request_await_object
(eb->request, obj, entry->flags & EXEC_OBJECT_WRITE);
if (err)
@ -2179,8 +2188,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
}
}
if (eb_create(&eb))
return -ENOMEM;
err = eb_create(&eb);
if (err)
goto err_out_fence;
GEM_BUG_ON(!eb.lut_size);
/*
* Take a local wakeref for preparing to dispatch the execbuf as
@ -2199,7 +2211,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
goto err_unlock;
err = eb_relocate(&eb);
if (err)
if (err) {
/*
* If the user expects the execobject.offset and
* reloc.presumed_offset to be an exact match,
@ -2208,8 +2220,8 @@ i915_gem_do_execbuffer(struct drm_device *dev,
* relocation.
*/
args->flags &= ~__EXEC_HAS_RELOC;
if (err < 0)
goto err_vma;
}
if (unlikely(eb.batch->exec_entry->flags & EXEC_OBJECT_WRITE)) {
DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
@ -2339,6 +2351,7 @@ err_unlock:
err_rpm:
intel_runtime_pm_put(eb.i915);
eb_destroy(&eb);
err_out_fence:
if (out_fence_fd != -1)
put_unused_fd(out_fence_fd);
err_in_fence:

View file

@ -129,7 +129,7 @@ struct drm_i915_gem_request {
* It is used by the driver to then queue the request for execution.
*/
struct i915_sw_fence submit;
wait_queue_t submitq;
wait_queue_entry_t submitq;
wait_queue_head_t execute;
/* A list of everyone we wait upon, and everyone who waits upon us.

View file

@ -43,16 +43,21 @@ static bool shrinker_lock(struct drm_i915_private *dev_priv, bool *unlock)
return true;
case MUTEX_TRYLOCK_FAILED:
*unlock = false;
preempt_disable();
do {
cpu_relax();
if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
case MUTEX_TRYLOCK_SUCCESS:
*unlock = true;
return true;
break;
}
} while (!need_resched());
preempt_enable();
return *unlock;
return false;
case MUTEX_TRYLOCK_SUCCESS:
*unlock = true;
return true;
}
BUG();

View file

@ -1601,11 +1601,11 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
u32 *cs;
int i;
cs = intel_ring_begin(req, n_flex_regs * 2 + 4);
cs = intel_ring_begin(req, ARRAY_SIZE(flex_mmio) * 2 + 4);
if (IS_ERR(cs))
return PTR_ERR(cs);
*cs++ = MI_LOAD_REGISTER_IMM(n_flex_regs + 1);
*cs++ = MI_LOAD_REGISTER_IMM(ARRAY_SIZE(flex_mmio) + 1);
*cs++ = i915_mmio_reg_offset(GEN8_OACTXCONTROL);
*cs++ = (dev_priv->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
@ -2067,10 +2067,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return ret;
}
ret = alloc_oa_buffer(dev_priv);
if (ret)
goto err_oa_buf_alloc;
/* PRM - observability performance counters:
*
* OACONTROL, performance counter enable, note:
@ -2086,6 +2082,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
intel_runtime_pm_get(dev_priv);
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
ret = alloc_oa_buffer(dev_priv);
if (ret)
goto err_oa_buf_alloc;
ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv);
if (ret)
goto err_enable;
@ -2097,11 +2097,11 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return 0;
err_enable:
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
intel_runtime_pm_put(dev_priv);
free_oa_buffer(dev_priv);
err_oa_buf_alloc:
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
intel_runtime_pm_put(dev_priv);
if (stream->ctx)
oa_put_render_ctx_id(stream);

View file

@ -1764,8 +1764,11 @@ enum skl_disp_power_wells {
_CNL_PORT_TX_DW2_LN0_AE, \
_CNL_PORT_TX_DW2_LN0_F)
#define SWING_SEL_UPPER(x) ((x >> 3) << 15)
#define SWING_SEL_UPPER_MASK (1 << 15)
#define SWING_SEL_LOWER(x) ((x & 0x7) << 11)
#define SWING_SEL_LOWER_MASK (0x7 << 11)
#define RCOMP_SCALAR(x) ((x) << 0)
#define RCOMP_SCALAR_MASK (0xFF << 0)
#define _CNL_PORT_TX_DW4_GRP_AE 0x162350
#define _CNL_PORT_TX_DW4_GRP_B 0x1623D0
@ -1795,8 +1798,11 @@ enum skl_disp_power_wells {
_CNL_PORT_TX_DW4_LN0_F)
#define LOADGEN_SELECT (1 << 31)
#define POST_CURSOR_1(x) ((x) << 12)
#define POST_CURSOR_1_MASK (0x3F << 12)
#define POST_CURSOR_2(x) ((x) << 6)
#define POST_CURSOR_2_MASK (0x3F << 6)
#define CURSOR_COEFF(x) ((x) << 0)
#define CURSOR_COEFF_MASK (0x3F << 0)
#define _CNL_PORT_TX_DW5_GRP_AE 0x162354
#define _CNL_PORT_TX_DW5_GRP_B 0x1623D4
@ -1825,7 +1831,9 @@ enum skl_disp_power_wells {
#define TX_TRAINING_EN (1 << 31)
#define TAP3_DISABLE (1 << 29)
#define SCALING_MODE_SEL(x) ((x) << 18)
#define SCALING_MODE_SEL_MASK (0x7 << 18)
#define RTERM_SELECT(x) ((x) << 3)
#define RTERM_SELECT_MASK (0x7 << 3)
#define _CNL_PORT_TX_DW7_GRP_AE 0x16235C
#define _CNL_PORT_TX_DW7_GRP_B 0x1623DC
@ -1852,6 +1860,7 @@ enum skl_disp_power_wells {
_CNL_PORT_TX_DW7_LN0_AE, \
_CNL_PORT_TX_DW7_LN0_F)
#define N_SCALAR(x) ((x) << 24)
#define N_SCALAR_MASK (0x7F << 24)
/* The spec defines this only for BXT PHY0, but lets assume that this
* would exist for PHY1 too if it had a second channel.

View file

@ -125,7 +125,7 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence,
struct list_head *continuation)
{
wait_queue_head_t *x = &fence->wait;
wait_queue_t *pos, *next;
wait_queue_entry_t *pos, *next;
unsigned long flags;
debug_fence_deactivate(fence);
@ -133,31 +133,30 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence,
/*
* To prevent unbounded recursion as we traverse the graph of
* i915_sw_fences, we move the task_list from this, the next ready
* fence, to the tail of the original fence's task_list
* i915_sw_fences, we move the entry list from this, the next ready
* fence, to the tail of the original fence's entry list
* (and so added to the list to be woken).
*/
spin_lock_irqsave_nested(&x->lock, flags, 1 + !!continuation);
if (continuation) {
list_for_each_entry_safe(pos, next, &x->task_list, task_list) {
list_for_each_entry_safe(pos, next, &x->head, entry) {
if (pos->func == autoremove_wake_function)
pos->func(pos, TASK_NORMAL, 0, continuation);
else
list_move_tail(&pos->task_list, continuation);
list_move_tail(&pos->entry, continuation);
}
} else {
LIST_HEAD(extra);
do {
list_for_each_entry_safe(pos, next,
&x->task_list, task_list)
list_for_each_entry_safe(pos, next, &x->head, entry)
pos->func(pos, TASK_NORMAL, 0, &extra);
if (list_empty(&extra))
break;
list_splice_tail_init(&extra, &x->task_list);
list_splice_tail_init(&extra, &x->head);
} while (1);
}
spin_unlock_irqrestore(&x->lock, flags);
@ -222,9 +221,9 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence)
i915_sw_fence_complete(fence);
}
static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void *key)
static int i915_sw_fence_wake(wait_queue_entry_t *wq, unsigned mode, int flags, void *key)
{
list_del(&wq->task_list);
list_del(&wq->entry);
__i915_sw_fence_complete(wq->private, key);
if (wq->flags & I915_SW_FENCE_FLAG_ALLOC)
@ -235,7 +234,7 @@ static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void *
static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
const struct i915_sw_fence * const signaler)
{
wait_queue_t *wq;
wait_queue_entry_t *wq;
if (__test_and_set_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags))
return false;
@ -243,7 +242,7 @@ static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
if (fence == signaler)
return true;
list_for_each_entry(wq, &fence->wait.task_list, task_list) {
list_for_each_entry(wq, &fence->wait.head, entry) {
if (wq->func != i915_sw_fence_wake)
continue;
@ -256,12 +255,12 @@ static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
static void __i915_sw_fence_clear_checked_bit(struct i915_sw_fence *fence)
{
wait_queue_t *wq;
wait_queue_entry_t *wq;
if (!__test_and_clear_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags))
return;
list_for_each_entry(wq, &fence->wait.task_list, task_list) {
list_for_each_entry(wq, &fence->wait.head, entry) {
if (wq->func != i915_sw_fence_wake)
continue;
@ -288,7 +287,7 @@ static bool i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
struct i915_sw_fence *signaler,
wait_queue_t *wq, gfp_t gfp)
wait_queue_entry_t *wq, gfp_t gfp)
{
unsigned long flags;
int pending;
@ -318,7 +317,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
pending |= I915_SW_FENCE_FLAG_ALLOC;
}
INIT_LIST_HEAD(&wq->task_list);
INIT_LIST_HEAD(&wq->entry);
wq->flags = pending;
wq->func = i915_sw_fence_wake;
wq->private = fence;
@ -327,7 +326,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
spin_lock_irqsave(&signaler->wait.lock, flags);
if (likely(!i915_sw_fence_done(signaler))) {
__add_wait_queue_tail(&signaler->wait, wq);
__add_wait_queue_entry_tail(&signaler->wait, wq);
pending = 1;
} else {
i915_sw_fence_wake(wq, 0, 0, NULL);
@ -340,7 +339,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
struct i915_sw_fence *signaler,
wait_queue_t *wq)
wait_queue_entry_t *wq)
{
return __i915_sw_fence_await_sw_fence(fence, signaler, wq, 0);
}

View file

@ -65,7 +65,7 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence);
int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
struct i915_sw_fence *after,
wait_queue_t *wq);
wait_queue_entry_t *wq);
int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
struct i915_sw_fence *after,
gfp_t gfp);

View file

@ -672,6 +672,11 @@ int i915_vma_unbind(struct i915_vma *vma)
break;
}
if (!ret) {
ret = i915_gem_active_retire(&vma->last_fence,
&vma->vm->i915->drm.struct_mutex);
}
__i915_vma_unpin(vma);
if (ret)
return ret;

View file

@ -284,12 +284,12 @@ static inline void __i915_vma_pin(struct i915_vma *vma)
static inline void __i915_vma_unpin(struct i915_vma *vma)
{
GEM_BUG_ON(!i915_vma_is_pinned(vma));
vma->flags--;
}
static inline void i915_vma_unpin(struct i915_vma *vma)
{
GEM_BUG_ON(!i915_vma_is_pinned(vma));
GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
__i915_vma_unpin(vma);
}

View file

@ -15,13 +15,9 @@ static struct intel_dsm_priv {
acpi_handle dhandle;
} intel_dsm_priv;
static const u8 intel_dsm_guid[] = {
0xd3, 0x73, 0xd8, 0x7e,
0xd0, 0xc2,
0x4f, 0x4e,
0xa8, 0x54,
0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c
};
static const guid_t intel_dsm_guid =
GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f,
0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c);
static char *intel_dsm_port_name(u8 id)
{
@ -80,7 +76,7 @@ static void intel_dsm_platform_mux_info(void)
int i;
union acpi_object *pkg, *connector_count;
pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, &intel_dsm_guid,
INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
NULL, ACPI_TYPE_PACKAGE);
if (!pkg) {
@ -118,7 +114,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev)
if (!dhandle)
return false;
if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID,
if (!acpi_check_dsm(dhandle, &intel_dsm_guid, INTEL_DSM_REVISION_ID,
1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) {
DRM_DEBUG_KMS("no _DSM method for intel device\n");
return false;

View file

@ -491,6 +491,14 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
int cdclk = cdclk_state->cdclk;
u32 val, cmd;
/* There are cases where we can end up here with power domains
* off and a CDCLK frequency other than the minimum, like when
* issuing a modeset without actually changing any display after
* a system suspend. So grab the PIPE-A domain, which covers
* the HW blocks needed for the following programming.
*/
intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
cmd = 2;
else if (cdclk == 266667)
@ -549,6 +557,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
intel_update_cdclk(dev_priv);
vlv_program_pfi_credits(dev_priv);
intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
}
static void chv_set_cdclk(struct drm_i915_private *dev_priv,
@ -568,6 +578,14 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
return;
}
/* There are cases where we can end up here with power domains
* off and a CDCLK frequency other than the minimum, like when
* issuing a modeset without actually changing any display after
* a system suspend. So grab the PIPE-A domain, which covers
* the HW blocks needed for the following programming.
*/
intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
/*
* Specs are full of misinformation, but testing on actual
* hardware has shown that we just need to write the desired
@ -590,6 +608,8 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
intel_update_cdclk(dev_priv);
vlv_program_pfi_credits(dev_priv);
intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
}
static int bdw_calc_cdclk(int max_pixclk)

View file

@ -398,6 +398,7 @@ static void bdw_load_gamma_lut(struct drm_crtc_state *state, u32 offset)
}
/* Program the max register to clamp values > 1.0. */
i = lut_size - 1;
I915_WRITE(PREC_PAL_GC_MAX(pipe, 0),
drm_color_lut_extract(lut[i].red, 16));
I915_WRITE(PREC_PAL_GC_MAX(pipe, 1),

View file

@ -1813,11 +1813,14 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv,
/* Set PORT_TX_DW5 Scaling Mode Sel to 010b. */
val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
val &= ~SCALING_MODE_SEL_MASK;
val |= SCALING_MODE_SEL(2);
I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
/* Program PORT_TX_DW2 */
val = I915_READ(CNL_PORT_TX_DW2_LN0(port));
val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
RCOMP_SCALAR_MASK);
val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel);
val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel);
/* Rcomp scalar is fixed as 0x98 for every table entry */
@ -1828,6 +1831,8 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv,
/* We cannot write to GRP. It would overrite individual loadgen */
for (ln = 0; ln < 4; ln++) {
val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln));
val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
CURSOR_COEFF_MASK);
val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1);
val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2);
val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff);
@ -1837,12 +1842,14 @@ static void cnl_ddi_vswing_program(struct drm_i915_private *dev_priv,
/* Program PORT_TX_DW5 */
/* All DW5 values are fixed for every table entry */
val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
val &= ~RTERM_SELECT_MASK;
val |= RTERM_SELECT(6);
val |= TAP3_DISABLE;
I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
/* Program PORT_TX_DW7 */
val = I915_READ(CNL_PORT_TX_DW7_LN0(port));
val &= ~N_SCALAR_MASK;
val |= N_SCALAR(ddi_translations[level].dw7_n_scalar);
I915_WRITE(CNL_PORT_TX_DW7_GRP(port), val);
}
@ -1889,8 +1896,8 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln));
val &= ~LOADGEN_SELECT;
if (((rate < 600000) && (width == 4) && (ln >= 1)) ||
((rate < 600000) && (width < 4) && ((ln == 1) || (ln == 2)))) {
if ((rate <= 600000 && width == 4 && ln >= 1) ||
(rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
val |= LOADGEN_SELECT;
}
I915_WRITE(CNL_PORT_TX_DW4_LN(port, ln), val);

View file

@ -3427,26 +3427,6 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
intel_finish_page_flip_cs(dev_priv, crtc->pipe);
}
static void intel_update_primary_planes(struct drm_device *dev)
{
struct drm_crtc *crtc;
for_each_crtc(dev, crtc) {
struct intel_plane *plane = to_intel_plane(crtc->primary);
struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
if (plane_state->base.visible) {
trace_intel_update_plane(&plane->base,
to_intel_crtc(crtc));
plane->update_plane(plane,
to_intel_crtc_state(crtc->state),
plane_state);
}
}
}
static int
__intel_display_resume(struct drm_device *dev,
struct drm_atomic_state *state,
@ -3499,6 +3479,12 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state;
int ret;
/* reset doesn't touch the display */
if (!i915.force_reset_modeset_test &&
!gpu_reset_clobbers_display(dev_priv))
return;
/*
* Need mode_config.mutex so that we don't
* trample ongoing ->detect() and whatnot.
@ -3512,12 +3498,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
drm_modeset_backoff(ctx);
}
/* reset doesn't touch the display, but flips might get nuked anyway, */
if (!i915.force_reset_modeset_test &&
!gpu_reset_clobbers_display(dev_priv))
return;
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
@ -3547,6 +3527,14 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
int ret;
/* reset doesn't touch the display */
if (!i915.force_reset_modeset_test &&
!gpu_reset_clobbers_display(dev_priv))
return;
if (!state)
goto unlock;
/*
* Flips in the rings will be nuked by the reset,
* so complete all pending flips so that user space
@ -3558,22 +3546,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
/* reset doesn't touch the display */
if (!gpu_reset_clobbers_display(dev_priv)) {
if (!state) {
/*
* Flips in the rings have been nuked by the reset,
* so update the base address of all primary
* planes to the the last fb to make sure we're
* showing the correct fb after a reset.
*
* FIXME: Atomic will make this obsolete since we won't schedule
* CS-based flips (which might get lost in gpu resets) any more.
*/
intel_update_primary_planes(dev);
} else {
ret = __intel_display_resume(dev, state, ctx);
/* for testing only restore the display */
ret = __intel_display_resume(dev, state, ctx);
if (ret)
DRM_ERROR("Restoring old state failed with %i\n", ret);
}
} else {
/*
* The display has been reset as well,
@ -3597,8 +3573,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
intel_hpd_init(dev_priv);
}
if (state)
drm_atomic_state_put(state);
drm_atomic_state_put(state);
unlock:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
mutex_unlock(&dev->mode_config.mutex);
@ -9117,6 +9093,13 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
u64 power_domain_mask;
bool active;
if (INTEL_GEN(dev_priv) >= 9) {
intel_crtc_init_scalers(crtc, pipe_config);
pipe_config->scaler_state.scaler_id = -1;
pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
}
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
@ -9145,13 +9128,6 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
pipe_config->gamma_mode =
I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
if (INTEL_GEN(dev_priv) >= 9) {
intel_crtc_init_scalers(crtc, pipe_config);
pipe_config->scaler_state.scaler_id = -1;
pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
}
power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
power_domain_mask |= BIT_ULL(power_domain);
@ -9540,7 +9516,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
* On some platforms writing CURCNTR first will also
* cause CURPOS to be armed by the CURBASE write.
* Without the CURCNTR write the CURPOS write would
* arm itself.
* arm itself. Thus we always start the full update
* with a CURCNTR write.
*
* On other platforms CURPOS always requires the
* CURBASE write to arm the update. Additonally
* a write to any of the cursor register will cancel
* an already armed cursor update. Thus leaving out
* the CURBASE write after CURPOS could lead to a
* cursor that doesn't appear to move, or even change
* shape. Thus we always write CURBASE.
*
* CURCNTR and CUR_FBC_CTL are always
* armed by the CURBASE write only.
@ -9559,6 +9544,7 @@ static void i9xx_update_cursor(struct intel_plane *plane,
plane->cursor.cntl = cntl;
} else {
I915_WRITE_FW(CURPOS(pipe), pos);
I915_WRITE_FW(CURBASE(pipe), base);
}
POSTING_READ_FW(CURBASE(pipe));

View file

@ -821,9 +821,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
/* WaDisableKillLogic:bxt,skl,kbl,cfl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
ECOCHK_DIS_TLB);
/* WaDisableKillLogic:bxt,skl,kbl */
if (!IS_COFFEELAKE(dev_priv))
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
ECOCHK_DIS_TLB);
/* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
/* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
@ -894,10 +895,9 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
WA_SET_BIT_MASKED(HDC_CHICKEN0,
HDC_FORCE_NON_COHERENT);
/* WaDisableHDCInvalidation:skl,bxt,kbl */
if (!IS_COFFEELAKE(dev_priv))
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
BDW_DISABLE_HDC_INVALIDATION);
/* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
BDW_DISABLE_HDC_INVALIDATION);
/* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
if (IS_SKYLAKE(dev_priv) ||

View file

@ -535,14 +535,15 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
drm_fb_helper_fini(&ifbdev->helper);
if (ifbdev->fb) {
if (ifbdev->vma) {
mutex_lock(&ifbdev->helper.dev->struct_mutex);
intel_unpin_fb_vma(ifbdev->vma);
mutex_unlock(&ifbdev->helper.dev->struct_mutex);
drm_framebuffer_remove(&ifbdev->fb->base);
}
if (ifbdev->fb)
drm_framebuffer_remove(&ifbdev->fb->base);
kfree(ifbdev);
}
@ -765,7 +766,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
struct intel_fbdev *ifbdev = dev_priv->fbdev;
struct fb_info *info;
if (!ifbdev || !ifbdev->fb)
if (!ifbdev || !ifbdev->vma)
return;
info = ifbdev->helper.fbdev;
@ -812,7 +813,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
if (ifbdev && ifbdev->fb)
if (ifbdev && ifbdev->vma)
drm_fb_helper_hotplug_event(&ifbdev->helper);
}
@ -824,7 +825,7 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
return;
intel_fbdev_sync(ifbdev);
if (!ifbdev->fb)
if (!ifbdev->vma)
return;
if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)

View file

@ -45,7 +45,7 @@ static bool is_supported_device(struct drm_i915_private *dev_priv)
return true;
if (IS_SKYLAKE(dev_priv))
return true;
if (IS_KABYLAKE(dev_priv) && INTEL_DEVID(dev_priv) == 0x591D)
if (IS_KABYLAKE(dev_priv))
return true;
return false;
}

View file

@ -469,7 +469,7 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
if (i915.invert_brightness > 0 ||
dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
return panel->backlight.max - val;
return panel->backlight.max - val + panel->backlight.min;
}
return val;

View file

@ -4463,8 +4463,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
else if ((ddb_allocation && ddb_allocation /
fixed_16_16_to_u32_round_up(plane_blocks_per_line)) >= 1)
else if (ddb_allocation >=
fixed_16_16_to_u32_round_up(plane_blocks_per_line))
selected_result = min_fixed_16_16(method1, method2);
else if (latency >= linetime_us)
selected_result = min_fixed_16_16(method1, method2);

View file

@ -246,9 +246,9 @@ static int igt_dmabuf_export_vmap(void *arg)
i915_gem_object_put(obj);
ptr = dma_buf_vmap(dmabuf);
if (IS_ERR(ptr)) {
err = PTR_ERR(ptr);
pr_err("dma_buf_vmap failed with err=%d\n", err);
if (!ptr) {
pr_err("dma_buf_vmap failed\n");
err = -ENOMEM;
goto out;
}

View file

@ -206,7 +206,7 @@ struct drm_i915_private *mock_gem_device(void)
mkwrite_device_info(i915)->ring_mask = BIT(0);
i915->engine[RCS] = mock_engine(i915, "mock");
if (!i915->engine[RCS])
goto err_dependencies;
goto err_priorities;
i915->kernel_context = mock_context(i915, NULL);
if (!i915->kernel_context)

Some files were not shown because too many files have changed in this diff Show more