Skip to content

Commit

Permalink
Merge tag 'drm-fixes-for-v4.9-rc5' of git://people.freedesktop.org/~a…
Browse files Browse the repository at this point in the history
…irlied/linux

Pull drm fixes from Dave Airlie:
 "AMD, radeon, i915, imx, msm and udl fixes:

   - amdgpu/radeon have a number of power management regressions and
     fixes along with some better error checking

   - imx has a single regression fix

   - udl has a single kmalloc instead of stack for usb control msg fix

   - msm has some fixes for modesetting bugs and regressions

   - i915 has a one fix for a Sandybridge regression along with some
     others for DP audio.

  They all seem pretty okay at this stage, we've got one MST fix I know
  going through process for i915, but I expect it'll be next week"

* tag 'drm-fixes-for-v4.9-rc5' of git://people.freedesktop.org/~airlied/linux: (30 commits)
  drm/udl: make control msg static const. (v2)
  drm/amd/powerplay: implement get_clock_by_type for iceland.
  drm/amd/powerplay/smu7: fix checks in smu7_get_evv_voltages (v2)
  drm/amd/powerplay: update phm_get_voltage_evv_on_sclk for iceland
  drm/amd/powerplay: propagate errors in phm_get_voltage_evv_on_sclk
  drm/imx: disable planes before DC
  drm/amd/powerplay: return false instead of -EINVAL
  drm/amdgpu/powerplay/smu7: fix unintialized data usage
  drm/amdgpu: fix crash in acp_hw_fini
  drm/i915: Limit Valleyview and earlier to only using mappable scanout
  drm/i915: Round tile chunks up for constructing partial VMAs
  drm/i915/dp: Extend BDW DP audio workaround to GEN9 platforms
  drm/i915/dp: BDW cdclk fix for DP audio
  drm/i915/vlv: Prevent enabling hpd polling in late suspend
  drm/i915: Respect alternate_ddc_pin for all DDI ports
  drm/msm: Fix error handling crashes seen when VRAM allocation fails
  drm/msm/mdp5: 8x16 actually has 8 mixer stages
  drm/msm/mdp5: no scaling support on RGBn pipes for 8x16
  drm/msm/mdp5: handle non-fullscreen base plane case
  drm/msm: Set CLK_IGNORE_UNUSED flag for PLL clocks
  ...
  • Loading branch information
torvalds committed Nov 12, 2016
2 parents b8b73df + 24399f4 commit 4fb68f9
Show file tree
Hide file tree
Showing 31 changed files with 299 additions and 136 deletions.
5 changes: 4 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,12 @@ static int acp_hw_fini(void *handle)
{
int i, ret;
struct device *dev;

struct amdgpu_device *adev = (struct amdgpu_device *)handle;

/* return early if no ACP */
if (!adev->acp.acp_genpd)
return 0;

for (i = 0; i < ACP_DEVS ; i++) {
dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
Expand Down
13 changes: 11 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
if (!adev->pm.fw) {
switch (adev->asic_type) {
case CHIP_TOPAZ:
strcpy(fw_name, "amdgpu/topaz_smc.bin");
if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)))
strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
else
strcpy(fw_name, "amdgpu/topaz_smc.bin");
break;
case CHIP_TONGA:
strcpy(fw_name, "amdgpu/tonga_smc.bin");
if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1)))
strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
else
strcpy(fw_name, "amdgpu/tonga_smc.bin");
break;
case CHIP_FIJI:
strcpy(fw_name, "amdgpu/fiji_smc.bin");
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);

if (amdgpu_connector->ddc_bus->has_aux) {
if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) {
drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);
amdgpu_connector->ddc_bus->has_aux = false;
}
Expand Down
26 changes: 24 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = {

static int __init amdgpu_init(void)
{
amdgpu_sync_init();
amdgpu_fence_slab_init();
int r;

r = amdgpu_sync_init();
if (r)
goto error_sync;

r = amdgpu_fence_slab_init();
if (r)
goto error_fence;

r = amd_sched_fence_slab_init();
if (r)
goto error_sched;

if (vgacon_text_force()) {
DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
return -EINVAL;
Expand All @@ -748,6 +760,15 @@ static int __init amdgpu_init(void)
amdgpu_register_atpx_handler();
/* let modprobe override vga console setting */
return drm_pci_init(driver, pdriver);

error_sched:
amdgpu_fence_slab_fini();

error_fence:
amdgpu_sync_fini();

error_sync:
return r;
}

static void __exit amdgpu_exit(void)
Expand All @@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void)
drm_pci_exit(driver, pdriver);
amdgpu_unregister_atpx_handler();
amdgpu_sync_fini();
amd_sched_fence_slab_fini();
amdgpu_fence_slab_fini();
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)

if ((amdgpu_runtime_pm != 0) &&
amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0))
flags |= AMD_IS_PX;

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
#include "dce_virtual.h"

MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin");
MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");
MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hw
PHM_FUNC_CHECK(hwmgr);

if (hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration == NULL)
return -EINVAL;
return false;

return hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration(hwmgr);
}
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,8 +710,10 @@ int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
uint32_t vol;
int ret = 0;

if (hwmgr->chip_id < CHIP_POLARIS10) {
atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage);
if (hwmgr->chip_id < CHIP_TONGA) {
ret = atomctrl_get_voltage_evv(hwmgr, id, voltage);
} else if (hwmgr->chip_id < CHIP_POLARIS10) {
ret = atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage);
if (*voltage >= 2000 || *voltage == 0)
*voltage = 1150;
} else {
Expand Down
70 changes: 45 additions & 25 deletions drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1460,19 +1460,19 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr)
struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = NULL;


if (table_info == NULL)
return -EINVAL;

sclk_table = table_info->vdd_dep_on_sclk;

for (i = 0; i < SMU7_MAX_LEAKAGE_COUNT; i++) {
vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;

if (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) {
if (0 == phm_get_sclk_for_voltage_evv(hwmgr,
if ((hwmgr->pp_table_version == PP_TABLE_V1)
&& !phm_get_sclk_for_voltage_evv(hwmgr,
table_info->vddgfx_lookup_table, vv_id, &sclk)) {
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ClockStretcher)) {
if (table_info == NULL)
return -EINVAL;
sclk_table = table_info->vdd_dep_on_sclk;

for (j = 1; j < sclk_table->count; j++) {
if (sclk_table->entries[j].clk == sclk &&
sclk_table->entries[j].cks_enable == 0) {
Expand All @@ -1498,12 +1498,15 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr)
}
}
} else {

if ((hwmgr->pp_table_version == PP_TABLE_V0)
|| !phm_get_sclk_for_voltage_evv(hwmgr,
table_info->vddc_lookup_table, vv_id, &sclk)) {
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ClockStretcher)) {
if (table_info == NULL)
return -EINVAL;
sclk_table = table_info->vdd_dep_on_sclk;

for (j = 1; j < sclk_table->count; j++) {
if (sclk_table->entries[j].clk == sclk &&
sclk_table->entries[j].cks_enable == 0) {
Expand Down Expand Up @@ -2133,9 +2136,11 @@ static int smu7_patch_limits_vddc(struct pp_hwmgr *hwmgr,
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);

if (tab) {
vddc = tab->vddc;
smu7_patch_ppt_v0_with_vdd_leakage(hwmgr, &vddc,
&data->vddc_leakage);
tab->vddc = vddc;
vddci = tab->vddci;
smu7_patch_ppt_v0_with_vdd_leakage(hwmgr, &vddci,
&data->vddci_leakage);
tab->vddci = vddci;
Expand Down Expand Up @@ -4228,18 +4233,26 @@ static int smu7_get_sclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks)
{
struct phm_ppt_v1_information *table_info =
(struct phm_ppt_v1_information *)hwmgr->pptable;
struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table = NULL;
struct phm_clock_voltage_dependency_table *sclk_table;
int i;

if (table_info == NULL)
return -EINVAL;

dep_sclk_table = table_info->vdd_dep_on_sclk;

for (i = 0; i < dep_sclk_table->count; i++) {
clocks->clock[i] = dep_sclk_table->entries[i].clk;
clocks->count++;
if (hwmgr->pp_table_version == PP_TABLE_V1) {
if (table_info == NULL || table_info->vdd_dep_on_sclk == NULL)
return -EINVAL;
dep_sclk_table = table_info->vdd_dep_on_sclk;
for (i = 0; i < dep_sclk_table->count; i++) {
clocks->clock[i] = dep_sclk_table->entries[i].clk;
clocks->count++;
}
} else if (hwmgr->pp_table_version == PP_TABLE_V0) {
sclk_table = hwmgr->dyn_state.vddc_dependency_on_sclk;
for (i = 0; i < sclk_table->count; i++) {
clocks->clock[i] = sclk_table->entries[i].clk;
clocks->count++;
}
}

return 0;
}

Expand All @@ -4261,17 +4274,24 @@ static int smu7_get_mclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks)
(struct phm_ppt_v1_information *)hwmgr->pptable;
struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table;
int i;
struct phm_clock_voltage_dependency_table *mclk_table;

if (table_info == NULL)
return -EINVAL;

dep_mclk_table = table_info->vdd_dep_on_mclk;

for (i = 0; i < dep_mclk_table->count; i++) {
clocks->clock[i] = dep_mclk_table->entries[i].clk;
clocks->latency[i] = smu7_get_mem_latency(hwmgr,
if (hwmgr->pp_table_version == PP_TABLE_V1) {
if (table_info == NULL)
return -EINVAL;
dep_mclk_table = table_info->vdd_dep_on_mclk;
for (i = 0; i < dep_mclk_table->count; i++) {
clocks->clock[i] = dep_mclk_table->entries[i].clk;
clocks->latency[i] = smu7_get_mem_latency(hwmgr,
dep_mclk_table->entries[i].clk);
clocks->count++;
clocks->count++;
}
} else if (hwmgr->pp_table_version == PP_TABLE_V0) {
mclk_table = hwmgr->dyn_state.vddc_dependency_on_mclk;
for (i = 0; i < mclk_table->count; i++) {
clocks->clock[i] = mclk_table->entries[i].clk;
clocks->count++;
}
}
return 0;
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int smu7_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
struct phm_fan_speed_info *fan_speed_info)
{
if (hwmgr->thermal_controller.fanInfo.bNoFan)
return 0;
return -ENODEV;

fan_speed_info->supports_percent_read = true;
fan_speed_info->supports_percent_write = true;
Expand Down Expand Up @@ -60,7 +60,7 @@ int smu7_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
uint64_t tmp64;

if (hwmgr->thermal_controller.fanInfo.bNoFan)
return 0;
return -ENODEV;

duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_FDO_CTRL1, FMAX_DUTY100);
Expand Down Expand Up @@ -89,7 +89,7 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
if (hwmgr->thermal_controller.fanInfo.bNoFan ||
(hwmgr->thermal_controller.fanInfo.
ucTachometerPulsesPerRevolution == 0))
return 0;
return -ENODEV;

tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_TACH_STATUS, TACH_PERIOD);
Expand Down
13 changes: 0 additions & 13 deletions drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity);
static void amd_sched_wakeup(struct amd_gpu_scheduler *sched);
static void amd_sched_process_job(struct fence *f, struct fence_cb *cb);

struct kmem_cache *sched_fence_slab;
atomic_t sched_fence_slab_ref = ATOMIC_INIT(0);

/* Initialize a given run queue struct */
static void amd_sched_rq_init(struct amd_sched_rq *rq)
{
Expand Down Expand Up @@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched,
INIT_LIST_HEAD(&sched->ring_mirror_list);
spin_lock_init(&sched->job_list_lock);
atomic_set(&sched->hw_rq_count, 0);
if (atomic_inc_return(&sched_fence_slab_ref) == 1) {
sched_fence_slab = kmem_cache_create(
"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!sched_fence_slab)
return -ENOMEM;
}

/* Each scheduler will run on a seperate kernel thread */
sched->thread = kthread_run(amd_sched_main, sched, sched->name);
Expand All @@ -645,7 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched)
{
if (sched->thread)
kthread_stop(sched->thread);
rcu_barrier();
if (atomic_dec_and_test(&sched_fence_slab_ref))
kmem_cache_destroy(sched_fence_slab);
}
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
struct amd_gpu_scheduler;
struct amd_sched_rq;

extern struct kmem_cache *sched_fence_slab;
extern atomic_t sched_fence_slab_ref;

/**
* A scheduler entity is a wrapper around a job queue or a group
* of other entities. Entities take turns emitting jobs from their
Expand Down Expand Up @@ -145,6 +142,9 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
struct amd_sched_entity *entity);
void amd_sched_entity_push_job(struct amd_sched_job *sched_job);

int amd_sched_fence_slab_init(void);
void amd_sched_fence_slab_fini(void);

struct amd_sched_fence *amd_sched_fence_create(
struct amd_sched_entity *s_entity, void *owner);
void amd_sched_fence_scheduled(struct amd_sched_fence *fence);
Expand Down
19 changes: 19 additions & 0 deletions drivers/gpu/drm/amd/scheduler/sched_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@
#include <drm/drmP.h>
#include "gpu_scheduler.h"

static struct kmem_cache *sched_fence_slab;

int amd_sched_fence_slab_init(void)
{
sched_fence_slab = kmem_cache_create(
"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!sched_fence_slab)
return -ENOMEM;

return 0;
}

void amd_sched_fence_slab_fini(void)
{
rcu_barrier();
kmem_cache_destroy(sched_fence_slab);
}

struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity,
void *owner)
{
Expand Down
20 changes: 17 additions & 3 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,7 @@ int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf)
/* Use a partial view if it is bigger than available space */
chunk_size = MIN_CHUNK_PAGES;
if (i915_gem_object_is_tiled(obj))
chunk_size = max(chunk_size, tile_row_pages(obj));
chunk_size = roundup(chunk_size, tile_row_pages(obj));

memset(&view, 0, sizeof(view));
view.type = I915_GGTT_VIEW_PARTIAL;
Expand Down Expand Up @@ -3543,8 +3543,22 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
if (view->type == I915_GGTT_VIEW_NORMAL)
vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment,
PIN_MAPPABLE | PIN_NONBLOCK);
if (IS_ERR(vma))
vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, 0);
if (IS_ERR(vma)) {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
unsigned int flags;

/* Valleyview is definitely limited to scanning out the first
* 512MiB. Lets presume this behaviour was inherited from the
* g4x display engine and that all earlier gen are similarly
* limited. Testing suggests that it is a little more
* complicated than this. For example, Cherryview appears quite
* happy to scanout from anywhere within its global aperture.
*/
flags = 0;
if (HAS_GMCH_DISPLAY(i915))
flags = PIN_MAPPABLE;
vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags);
}
if (IS_ERR(vma))
goto err_unpin_display;

Expand Down
Loading

0 comments on commit 4fb68f9

Please sign in to comment.