Skip to content

Commit b9cc335

Browse files
committed
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "A few fixes all over the place: radeon is probably the biggest standout, it's a fix for screen corruption or hung black outputs so I thought it was worth pulling in. Otherwise some amdgpu power control fixes, some misc vmwgfx fixes, one etnaviv fix, one virtio-gpu fix, two DP MST fixes, and a single TTM fix" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/vmwgfx: Fix order of operation drm/vmwgfx: use vmw_cmd_dx_cid_check for query commands. drm/vmwgfx: Enable SVGA_3D_CMD_DX_SET_PREDICATION drm/amdgpu: disable vm interrupts with vm_fault_stop=2 drm/amdgpu: print a message if ATPX dGPU power control is missing Revert "drm/amdgpu: disable runtime pm on PX laptops without dGPU power control" drm/radeon: fix vertical bars appear on monitor (v2) drm/ttm: fix kref count mess in ttm_bo_move_to_lru_tail drm/virtio: send vblank event after crtc updates drm/dp/mst: Restore primary hub guid on resume drm/dp/mst: Get validated port ref in drm_dp_update_payload_part1() drm/etnaviv: don't move linear memory window on 3D cores without MC2.0
2 parents 925d96a + ea99697 commit b9cc335

File tree

12 files changed

+277
-48
lines changed

12 files changed

+277
-48
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) {
6363
return amdgpu_atpx_priv.atpx_detected;
6464
}
6565

66-
bool amdgpu_has_atpx_dgpu_power_cntl(void) {
67-
return amdgpu_atpx_priv.atpx.functions.power_cntl;
68-
}
69-
7066
/**
7167
* amdgpu_atpx_call - call an ATPX method
7268
*
@@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas
146142
*/
147143
static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
148144
{
145+
/* make sure required functions are enabled */
146+
/* dGPU power control is required */
147+
if (atpx->functions.power_cntl == false) {
148+
printk("ATPX dGPU power cntl not present, forcing\n");
149+
atpx->functions.power_cntl = true;
150+
}
151+
149152
if (atpx->functions.px_params) {
150153
union acpi_object *info;
151154
struct atpx_px_params output;

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = {
6262
"LAST",
6363
};
6464

65-
#if defined(CONFIG_VGA_SWITCHEROO)
66-
bool amdgpu_has_atpx_dgpu_power_cntl(void);
67-
#else
68-
static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; }
69-
#endif
70-
7165
bool amdgpu_device_is_px(struct drm_device *dev)
7266
{
7367
struct amdgpu_device *adev = dev->dev_private;
@@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
14851479

14861480
if (amdgpu_runtime_pm == 1)
14871481
runtime = true;
1488-
if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl())
1482+
if (amdgpu_device_is_px(ddev))
14891483
runtime = true;
14901484
vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
14911485
if (runtime)

drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle)
910910
{
911911
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
912912

913-
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
913+
if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
914+
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
915+
else
916+
return 0;
914917
}
915918

916919
static int gmc_v7_0_sw_init(void *handle)

drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,10 @@ static int gmc_v8_0_late_init(void *handle)
870870
{
871871
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
872872

873-
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
873+
if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
874+
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
875+
else
876+
return 0;
874877
}
875878

876879
#define mmMC_SEQ_MISC0_FIJI 0xA71

drivers/gpu/drm/drm_dp_mst_topology.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
17961796
req_payload.start_slot = cur_slots;
17971797
if (mgr->proposed_vcpis[i]) {
17981798
port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
1799+
port = drm_dp_get_validated_port_ref(mgr, port);
1800+
if (!port) {
1801+
mutex_unlock(&mgr->payload_lock);
1802+
return -EINVAL;
1803+
}
17991804
req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots;
18001805
req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi;
18011806
} else {
@@ -1823,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
18231828
mgr->payloads[i].payload_state = req_payload.payload_state;
18241829
}
18251830
cur_slots += req_payload.num_slots;
1831+
1832+
if (port)
1833+
drm_dp_put_port(port);
18261834
}
18271835

18281836
for (i = 0; i < mgr->max_payloads; i++) {
@@ -2128,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
21282136

21292137
if (mgr->mst_primary) {
21302138
int sret;
2139+
u8 guid[16];
2140+
21312141
sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
21322142
if (sret != DP_RECEIVER_CAP_SIZE) {
21332143
DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
@@ -2142,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
21422152
ret = -1;
21432153
goto out_unlock;
21442154
}
2155+
2156+
/* Some hubs forget their guids after they resume */
2157+
sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
2158+
if (sret != 16) {
2159+
DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
2160+
ret = -1;
2161+
goto out_unlock;
2162+
}
2163+
drm_dp_check_mstb_guid(mgr->mst_primary, guid);
2164+
21452165
ret = 0;
21462166
} else
21472167
ret = -1;

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,24 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
572572
goto fail;
573573
}
574574

575+
/*
576+
* Set the GPU linear window to be at the end of the DMA window, where
577+
* the CMA area is likely to reside. This ensures that we are able to
578+
* map the command buffers while having the linear window overlap as
579+
* much RAM as possible, so we can optimize mappings for other buffers.
580+
*
581+
* For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads
582+
* to different views of the memory on the individual engines.
583+
*/
584+
if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
585+
(gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
586+
u32 dma_mask = (u32)dma_get_required_mask(gpu->dev);
587+
if (dma_mask < PHYS_OFFSET + SZ_2G)
588+
gpu->memory_base = PHYS_OFFSET;
589+
else
590+
gpu->memory_base = dma_mask - SZ_2G + 1;
591+
}
592+
575593
ret = etnaviv_hw_reset(gpu);
576594
if (ret)
577595
goto fail;
@@ -1566,7 +1584,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
15661584
{
15671585
struct device *dev = &pdev->dev;
15681586
struct etnaviv_gpu *gpu;
1569-
u32 dma_mask;
15701587
int err = 0;
15711588

15721589
gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL);
@@ -1576,18 +1593,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
15761593
gpu->dev = &pdev->dev;
15771594
mutex_init(&gpu->lock);
15781595

1579-
/*
1580-
* Set the GPU linear window to be at the end of the DMA window, where
1581-
* the CMA area is likely to reside. This ensures that we are able to
1582-
* map the command buffers while having the linear window overlap as
1583-
* much RAM as possible, so we can optimize mappings for other buffers.
1584-
*/
1585-
dma_mask = (u32)dma_get_required_mask(dev);
1586-
if (dma_mask < PHYS_OFFSET + SZ_2G)
1587-
gpu->memory_base = PHYS_OFFSET;
1588-
else
1589-
gpu->memory_base = dma_mask - SZ_2G + 1;
1590-
15911596
/* Map registers: */
15921597
gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev));
15931598
if (IS_ERR(gpu->mmio))

drivers/gpu/drm/radeon/evergreen.c

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev)
26082608
WREG32(VM_CONTEXT1_CNTL, 0);
26092609
}
26102610

2611+
static const unsigned ni_dig_offsets[] =
2612+
{
2613+
NI_DIG0_REGISTER_OFFSET,
2614+
NI_DIG1_REGISTER_OFFSET,
2615+
NI_DIG2_REGISTER_OFFSET,
2616+
NI_DIG3_REGISTER_OFFSET,
2617+
NI_DIG4_REGISTER_OFFSET,
2618+
NI_DIG5_REGISTER_OFFSET
2619+
};
2620+
2621+
static const unsigned ni_tx_offsets[] =
2622+
{
2623+
NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
2624+
NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
2625+
NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
2626+
NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
2627+
NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
2628+
NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
2629+
};
2630+
2631+
static const unsigned evergreen_dp_offsets[] =
2632+
{
2633+
EVERGREEN_DP0_REGISTER_OFFSET,
2634+
EVERGREEN_DP1_REGISTER_OFFSET,
2635+
EVERGREEN_DP2_REGISTER_OFFSET,
2636+
EVERGREEN_DP3_REGISTER_OFFSET,
2637+
EVERGREEN_DP4_REGISTER_OFFSET,
2638+
EVERGREEN_DP5_REGISTER_OFFSET
2639+
};
2640+
2641+
2642+
/*
2643+
* Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
2644+
* We go from crtc to connector and it is not relible since it
2645+
* should be an opposite direction .If crtc is enable then
2646+
* find the dig_fe which selects this crtc and insure that it enable.
2647+
* if such dig_fe is found then find dig_be which selects found dig_be and
2648+
* insure that it enable and in DP_SST mode.
2649+
* if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
2650+
* from dp symbols clocks .
2651+
*/
2652+
static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
2653+
unsigned crtc_id, unsigned *ret_dig_fe)
2654+
{
2655+
unsigned i;
2656+
unsigned dig_fe;
2657+
unsigned dig_be;
2658+
unsigned dig_en_be;
2659+
unsigned uniphy_pll;
2660+
unsigned digs_fe_selected;
2661+
unsigned dig_be_mode;
2662+
unsigned dig_fe_mask;
2663+
bool is_enabled = false;
2664+
bool found_crtc = false;
2665+
2666+
/* loop through all running dig_fe to find selected crtc */
2667+
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
2668+
dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
2669+
if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
2670+
crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
2671+
/* found running pipe */
2672+
found_crtc = true;
2673+
dig_fe_mask = 1 << i;
2674+
dig_fe = i;
2675+
break;
2676+
}
2677+
}
2678+
2679+
if (found_crtc) {
2680+
/* loop through all running dig_be to find selected dig_fe */
2681+
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
2682+
dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
2683+
/* if dig_fe_selected by dig_be? */
2684+
digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
2685+
dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
2686+
if (dig_fe_mask & digs_fe_selected &&
2687+
/* if dig_be in sst mode? */
2688+
dig_be_mode == NI_DIG_BE_DPSST) {
2689+
dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
2690+
ni_dig_offsets[i]);
2691+
uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
2692+
ni_tx_offsets[i]);
2693+
/* dig_be enable and tx is running */
2694+
if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
2695+
dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
2696+
uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
2697+
is_enabled = true;
2698+
*ret_dig_fe = dig_fe;
2699+
break;
2700+
}
2701+
}
2702+
}
2703+
}
2704+
2705+
return is_enabled;
2706+
}
2707+
2708+
/*
2709+
* Blank dig when in dp sst mode
2710+
* Dig ignores crtc timing
2711+
*/
2712+
static void evergreen_blank_dp_output(struct radeon_device *rdev,
2713+
unsigned dig_fe)
2714+
{
2715+
unsigned stream_ctrl;
2716+
unsigned fifo_ctrl;
2717+
unsigned counter = 0;
2718+
2719+
if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
2720+
DRM_ERROR("invalid dig_fe %d\n", dig_fe);
2721+
return;
2722+
}
2723+
2724+
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
2725+
evergreen_dp_offsets[dig_fe]);
2726+
if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
2727+
DRM_ERROR("dig %d , should be enable\n", dig_fe);
2728+
return;
2729+
}
2730+
2731+
stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
2732+
WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
2733+
evergreen_dp_offsets[dig_fe], stream_ctrl);
2734+
2735+
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
2736+
evergreen_dp_offsets[dig_fe]);
2737+
while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
2738+
msleep(1);
2739+
counter++;
2740+
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
2741+
evergreen_dp_offsets[dig_fe]);
2742+
}
2743+
if (counter >= 32 )
2744+
DRM_ERROR("counter exceeds %d\n", counter);
2745+
2746+
fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
2747+
fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
2748+
WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);
2749+
2750+
}
2751+
26112752
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
26122753
{
26132754
u32 crtc_enabled, tmp, frame_count, blackout;
26142755
int i, j;
2756+
unsigned dig_fe;
26152757

26162758
if (!ASIC_IS_NODCE(rdev)) {
26172759
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
@@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
26512793
break;
26522794
udelay(1);
26532795
}
2654-
2796+
/*we should disable dig if it drives dp sst*/
2797+
/*but we are in radeon_device_init and the topology is unknown*/
2798+
/*and it is available after radeon_modeset_init*/
2799+
/*the following method radeon_atom_encoder_dpms_dig*/
2800+
/*does the job if we initialize it properly*/
2801+
/*for now we do it this manually*/
2802+
/**/
2803+
if (ASIC_IS_DCE5(rdev) &&
2804+
evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
2805+
evergreen_blank_dp_output(rdev, dig_fe);
2806+
/*we could remove 6 lines below*/
26552807
/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
26562808
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
26572809
tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);

0 commit comments

Comments
 (0)