diff -ur radeon-11.26/atombios_dp.c radeon-13.29/atombios_dp.c --- radeon-11.26/atombios_dp.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/atombios_dp.c 2016-03-18 12:04:55.353871908 +0100 @@ -302,77 +302,31 @@ return bpc * 3; } -/* get the max pix clock supported by the link rate and lane num */ -static int dp_get_max_dp_pix_clock(int link_rate, - int lane_num, - int bpp) -{ - return (link_rate * lane_num * 8) / bpp; -} - /***** radeon specific DP functions *****/ -int radeon_dp_get_max_link_rate(struct drm_connector *connector, - const u8 dpcd[DP_DPCD_SIZE]) -{ - int max_link_rate; - - if (radeon_connector_is_dp12_capable(connector)) - max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000); - else - max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000); - - return max_link_rate; -} - -/* First get the min lane# when low rate is used according to pixel clock - * (prefer low rate), second check max lane# supported by DP panel, - * if the max lane# < low rate lane# then use max lane# instead. - */ -static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, - const u8 dpcd[DP_DPCD_SIZE], - int pix_clock) +int radeon_dp_get_dp_link_config(struct drm_connector *connector, + const u8 dpcd[DP_DPCD_SIZE], + unsigned pix_clock, + unsigned *dp_lanes, unsigned *dp_rate) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); - int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); - int max_lane_num = drm_dp_max_lane_count(dpcd); - int lane_num; - int max_dp_pix_clock; - - for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { - max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); - if (pix_clock <= max_dp_pix_clock) - break; - } - - return lane_num; -} - -static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, - const u8 dpcd[DP_DPCD_SIZE], - int pix_clock) -{ - int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); - int lane_num, max_pix_clock; - - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_NUTMEG) - return 270000; - - lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); - max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 162000; - max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 270000; - if (radeon_connector_is_dp12_capable(connector)) { - max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 540000; + static const unsigned link_rates[3] = { 162000, 270000, 540000 }; + unsigned max_link_rate = drm_dp_max_link_rate(dpcd); + unsigned max_lane_num = drm_dp_max_lane_count(dpcd); + unsigned lane_num, i, max_pix_clock; + + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; + return 0; + } + } } - return radeon_dp_get_max_link_rate(connector, dpcd); + return -EINVAL; } static u8 radeon_dp_encoder_service(struct radeon_device *rdev, @@ -491,6 +445,7 @@ { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *dig_connector; + int ret; if (!radeon_connector->con_priv) return; @@ -498,10 +453,14 @@ if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { - dig_connector->dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); - dig_connector->dp_lane_count = - radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); + if (ret) { + dig_connector->dp_clock = 0; + dig_connector->dp_lane_count = 0; + } } } @@ -510,7 +469,8 @@ { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *dig_connector; - int dp_clock; + unsigned dp_clock, dp_lanes; + int ret; if ((mode->clock > 340000) && (!radeon_connector_is_dp12_capable(connector))) @@ -520,8 +480,12 @@ return MODE_CLOCK_HIGH; dig_connector = radeon_connector->con_priv; - dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, + &dp_lanes, + &dp_clock); + if (ret) + return MODE_CLOCK_HIGH; if ((dp_clock == 540000) && (!radeon_connector_is_dp12_capable(connector))) Nur in radeon-11.26: cik_structs.h. Nur in radeon-11.26: kgd_kfd_interface.h. diff -ur radeon-11.26/radeon_asic.c radeon-13.29/radeon_asic.c --- radeon-11.26/radeon_asic.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_asic.c 2016-03-18 12:04:55.361871975 +0100 @@ -179,7 +179,7 @@ * ASIC */ -static struct radeon_asic_ring r100_gfx_ring = { +static const struct radeon_asic_ring r100_gfx_ring = { .ib_execute = &r100_ring_ib_execute, .emit_fence = &r100_fence_ring_emit, .emit_semaphore = &r100_semaphore_ring_emit, @@ -329,7 +329,7 @@ }, }; -static struct radeon_asic_ring r300_gfx_ring = { +static const struct radeon_asic_ring r300_gfx_ring = { .ib_execute = &r100_ring_ib_execute, .emit_fence = &r300_fence_ring_emit, .emit_semaphore = &r100_semaphore_ring_emit, @@ -343,7 +343,7 @@ .set_wptr = &r100_gfx_set_wptr, }; -static struct radeon_asic_ring rv515_gfx_ring = { +static const struct radeon_asic_ring rv515_gfx_ring = { .ib_execute = &r100_ring_ib_execute, .emit_fence = &r300_fence_ring_emit, .emit_semaphore = &r100_semaphore_ring_emit, @@ -901,7 +901,7 @@ }, }; -static struct radeon_asic_ring r600_gfx_ring = { +static const struct radeon_asic_ring r600_gfx_ring = { .ib_execute = &r600_ring_ib_execute, .emit_fence = &r600_fence_ring_emit, .emit_semaphore = &r600_semaphore_ring_emit, @@ -914,7 +914,7 @@ .set_wptr = &r600_gfx_set_wptr, }; -static struct radeon_asic_ring r600_dma_ring = { +static const struct radeon_asic_ring r600_dma_ring = { .ib_execute = &r600_dma_ring_ib_execute, .emit_fence = &r600_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, @@ -999,7 +999,7 @@ }, }; -static struct radeon_asic_ring rv6xx_uvd_ring = { +static const struct radeon_asic_ring rv6xx_uvd_ring = { .ib_execute = &uvd_v1_0_ib_execute, .emit_fence = &uvd_v1_0_fence_emit, .emit_semaphore = &uvd_v1_0_semaphore_emit, @@ -1198,7 +1198,7 @@ }, }; -static struct radeon_asic_ring rv770_uvd_ring = { +static const struct radeon_asic_ring rv770_uvd_ring = { .ib_execute = &uvd_v1_0_ib_execute, .emit_fence = &uvd_v2_2_fence_emit, .emit_semaphore = &uvd_v2_2_semaphore_emit, @@ -1305,7 +1305,7 @@ }, }; -static struct radeon_asic_ring evergreen_gfx_ring = { +static const struct radeon_asic_ring evergreen_gfx_ring = { .ib_execute = &evergreen_ring_ib_execute, .emit_fence = &r600_fence_ring_emit, .emit_semaphore = &r600_semaphore_ring_emit, @@ -1318,7 +1318,7 @@ .set_wptr = &r600_gfx_set_wptr, }; -static struct radeon_asic_ring evergreen_dma_ring = { +static const struct radeon_asic_ring evergreen_dma_ring = { .ib_execute = &evergreen_dma_ring_ib_execute, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, @@ -1612,7 +1612,7 @@ }, }; -static struct radeon_asic_ring cayman_gfx_ring = { +static const struct radeon_asic_ring cayman_gfx_ring = { .ib_execute = &cayman_ring_ib_execute, .ib_parse = &evergreen_ib_parse, .emit_fence = &cayman_fence_ring_emit, @@ -1627,7 +1627,7 @@ .set_wptr = &cayman_gfx_set_wptr, }; -static struct radeon_asic_ring cayman_dma_ring = { +static const struct radeon_asic_ring cayman_dma_ring = { .ib_execute = &cayman_dma_ring_ib_execute, .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, @@ -1642,7 +1642,7 @@ .set_wptr = &cayman_dma_set_wptr }; -static struct radeon_asic_ring cayman_uvd_ring = { +static const struct radeon_asic_ring cayman_uvd_ring = { .ib_execute = &uvd_v1_0_ib_execute, .emit_fence = &uvd_v2_2_fence_emit, .emit_semaphore = &uvd_v3_1_semaphore_emit, @@ -1760,7 +1760,7 @@ }, }; -static struct radeon_asic_ring trinity_vce_ring = { +static const struct radeon_asic_ring trinity_vce_ring = { .ib_execute = &radeon_vce_ib_execute, .emit_fence = &radeon_vce_fence_emit, .emit_semaphore = &radeon_vce_semaphore_emit, @@ -1881,7 +1881,7 @@ }, }; -static struct radeon_asic_ring si_gfx_ring = { +static const struct radeon_asic_ring si_gfx_ring = { .ib_execute = &si_ring_ib_execute, .ib_parse = &si_ib_parse, .emit_fence = &si_fence_ring_emit, @@ -1896,7 +1896,7 @@ .set_wptr = &cayman_gfx_set_wptr, }; -static struct radeon_asic_ring si_dma_ring = { +static const struct radeon_asic_ring si_dma_ring = { .ib_execute = &cayman_dma_ring_ib_execute, .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, @@ -2023,7 +2023,7 @@ }, }; -static struct radeon_asic_ring ci_gfx_ring = { +static const struct radeon_asic_ring ci_gfx_ring = { .ib_execute = &cik_ring_ib_execute, .ib_parse = &cik_ib_parse, .emit_fence = &cik_fence_gfx_ring_emit, @@ -2038,7 +2038,7 @@ .set_wptr = &cik_gfx_set_wptr, }; -static struct radeon_asic_ring ci_cp_ring = { +static const struct radeon_asic_ring ci_cp_ring = { .ib_execute = &cik_ring_ib_execute, .ib_parse = &cik_ib_parse, .emit_fence = &cik_fence_compute_ring_emit, @@ -2053,7 +2053,7 @@ .set_wptr = &cik_compute_set_wptr, }; -static struct radeon_asic_ring ci_dma_ring = { +static const struct radeon_asic_ring ci_dma_ring = { .ib_execute = &cik_sdma_ring_ib_execute, .ib_parse = &cik_ib_parse, .emit_fence = &cik_sdma_fence_ring_emit, @@ -2068,7 +2068,7 @@ .set_wptr = &cik_sdma_set_wptr, }; -static struct radeon_asic_ring ci_vce_ring = { +static const struct radeon_asic_ring ci_vce_ring = { .ib_execute = &radeon_vce_ib_execute, .emit_fence = &radeon_vce_fence_emit, .emit_semaphore = &radeon_vce_semaphore_emit, diff -ur radeon-11.26/radeon_device.c radeon-13.29/radeon_device.c --- radeon-11.26/radeon_device.c 2016-03-18 11:48:46.000000000 +0100 +++ radeon-13.29/radeon_device.c 2016-01-11 00:01:32.000000000 +0100 @@ -1744,7 +1744,6 @@ } drm_kms_helper_poll_enable(dev); - drm_helper_hpd_irq_event(dev); /* set the power state here in case we are a PX system or headless */ if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) diff -ur radeon-11.26/radeon_display.c radeon-13.29/radeon_display.c --- radeon-11.26/radeon_display.c 2016-03-18 11:48:47.000000000 +0100 +++ radeon-13.29/radeon_display.c 2016-03-18 12:04:55.361871975 +0100 @@ -1683,8 +1683,10 @@ /* setup afmt */ radeon_afmt_init(rdev); - radeon_fbdev_init(rdev); - drm_kms_helper_poll_init(rdev->ddev); + if (!list_empty(&rdev->ddev->mode_config.connector_list)) { + radeon_fbdev_init(rdev); + drm_kms_helper_poll_init(rdev->ddev); + } /* do pm late init */ ret = radeon_pm_late_init(rdev); diff -ur radeon-11.26/radeon_dp_mst.c radeon-13.29/radeon_dp_mst.c --- radeon-11.26/radeon_dp_mst.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_dp_mst.c 2016-03-18 12:04:55.365872009 +0100 @@ -525,11 +525,17 @@ drm_mode_set_crtcinfo(adjusted_mode, 0); { struct radeon_connector_atom_dig *dig_connector; + int ret; dig_connector = mst_enc->connector->con_priv; - dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd); - dig_connector->dp_clock = radeon_dp_get_max_link_rate(&mst_enc->connector->base, - dig_connector->dpcd); + ret = radeon_dp_get_dp_link_config(&mst_enc->connector->base, + dig_connector->dpcd, adjusted_mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); + if (ret) { + dig_connector->dp_lane_count = 0; + dig_connector->dp_clock = 0; + } DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector, dig_connector->dp_lane_count, dig_connector->dp_clock); } diff -ur radeon-11.26/radeon_fb.c radeon-13.29/radeon_fb.c --- radeon-11.26/radeon_fb.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_fb.c 2016-03-18 12:04:55.365872009 +0100 @@ -283,7 +283,7 @@ } if (fb && ret) { - drm_gem_object_unreference(gobj); + drm_gem_object_unreference_unlocked(gobj); drm_framebuffer_unregister_private(fb); drm_framebuffer_cleanup(fb); kfree(fb); diff -ur radeon-11.26/radeon_fence.c radeon-13.29/radeon_fence.c --- radeon-11.26/radeon_fence.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_fence.c 2016-03-18 12:04:55.365872009 +0100 @@ -130,7 +130,7 @@ struct radeon_fence **fence, int ring) { - u64 seq = ++rdev->fence_drv[ring].sync_seq[ring]; + u64 seq; /* we are protected by the ring emission mutex */ *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); @@ -138,7 +138,7 @@ return -ENOMEM; } (*fence)->rdev = rdev; - (*fence)->seq = seq; + (*fence)->seq = seq = ++rdev->fence_drv[ring].sync_seq[ring]; (*fence)->ring = ring; (*fence)->is_vm_update = false; fence_init(&(*fence)->base, &radeon_fence_ops, diff -ur radeon-11.26/radeon_gem.c radeon-13.29/radeon_gem.c --- radeon-11.26/radeon_gem.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_gem.c 2016-03-18 12:04:55.365872009 +0100 @@ -663,6 +663,7 @@ bo_va = radeon_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) { args->operation = RADEON_VA_RESULT_ERROR; + radeon_bo_unreserve(rbo); drm_gem_object_unreference_unlocked(gobj); return -ENOENT; } diff -ur radeon-11.26/radeon.h radeon-13.29/radeon.h --- radeon-11.26/radeon.h 2016-03-18 11:48:46.000000000 +0100 +++ radeon-13.29/radeon.h 2016-03-18 12:04:55.357871942 +0100 @@ -1890,7 +1890,7 @@ void (*pad_ib)(struct radeon_ib *ib); } vm; /* ring specific callbacks */ - struct radeon_asic_ring *ring[RADEON_NUM_RINGS]; + const struct radeon_asic_ring *ring[RADEON_NUM_RINGS]; /* irqs */ struct { int (*set)(struct radeon_device *rdev); diff -ur radeon-11.26/radeon_kms.c radeon-13.29/radeon_kms.c --- radeon-11.26/radeon_kms.c 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_kms.c 2016-03-18 12:04:55.365872009 +0100 @@ -748,19 +748,19 @@ * radeon_get_vblank_counter_kms - get frame count * * @dev: drm dev pointer - * @crtc: crtc to get the frame count from + * @pipe: crtc to get the frame count from * * Gets the frame count on the requested crtc (all asics). * Returns frame count on success, -EINVAL on failure. */ -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) +u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) { int vpos, hpos, stat; u32 count; struct radeon_device *rdev = dev->dev_private; - if (crtc < 0 || crtc >= rdev->num_crtc) { - DRM_ERROR("Invalid crtc %d\n", crtc); + if (pipe < 0 || pipe >= rdev->num_crtc) { + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } @@ -772,29 +772,29 @@ * and start of vsync, so vpos >= 0 means to bump the hw frame counter * result by 1 to give the proper appearance to caller. */ - if (rdev->mode_info.crtcs[crtc]) { + if (rdev->mode_info.crtcs[pipe]) { /* Repeat readout if needed to provide stable result if * we cross start of vsync during the queries. */ do { - count = radeon_get_vblank_counter(rdev, crtc); + count = radeon_get_vblank_counter(rdev, pipe); /* Ask radeon_get_crtc_scanoutpos to return vpos as * distance to start of vblank, instead of regular * vertical scanout pos. */ stat = radeon_get_crtc_scanoutpos( - dev, crtc, GET_DISTANCE_TO_VBLANKSTART, + dev, pipe, GET_DISTANCE_TO_VBLANKSTART, &vpos, &hpos, NULL, NULL, - &rdev->mode_info.crtcs[crtc]->base.hwmode); - } while (count != radeon_get_vblank_counter(rdev, crtc)); + &rdev->mode_info.crtcs[pipe]->base.hwmode); + } while (count != radeon_get_vblank_counter(rdev, pipe)); if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { DRM_DEBUG_VBL("Query failed! stat %d\n", stat); } else { - DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", - crtc, vpos); + DRM_DEBUG_VBL("crtc %u: dist from vblank start %d\n", + pipe, vpos); /* Bump counter if we are at >= leading edge of vblank, * but before vsync where vpos would turn negative and @@ -806,7 +806,7 @@ } else { /* Fallback to use value as is. */ - count = radeon_get_vblank_counter(rdev, crtc); + count = radeon_get_vblank_counter(rdev, pipe); DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); } diff -ur radeon-11.26/radeon_mode.h radeon-13.29/radeon_mode.h --- radeon-11.26/radeon_mode.h 2016-01-11 00:01:32.000000000 +0100 +++ radeon-13.29/radeon_mode.h 2016-03-18 12:04:55.365872009 +0100 @@ -757,8 +757,10 @@ extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_connector *connector); -int radeon_dp_get_max_link_rate(struct drm_connector *connector, - const u8 *dpcd); +extern int radeon_dp_get_dp_link_config(struct drm_connector *connector, + const u8 *dpcd, + unsigned pix_clock, + unsigned *dp_lanes, unsigned *dp_rate); extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, u8 power_state); extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector); diff -ur radeon-11.26/radeon_pm.c radeon-13.29/radeon_pm.c --- radeon-11.26/radeon_pm.c 2016-03-18 11:48:47.000000000 +0100 +++ radeon-13.29/radeon_pm.c 2016-03-18 12:04:55.365872009 +0100 @@ -713,7 +713,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, struct attribute *attr, int index) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct radeon_device *rdev = dev_get_drvdata(dev); umode_t effective_mode = attr->mode; @@ -1076,10 +1076,6 @@ /* update display watermarks based on new power state */ radeon_bandwidth_update(rdev); - rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; - rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; - rdev->pm.dpm.single_display = single_display; - /* wait for the rings to drain */ for (i = 0; i < RADEON_NUM_RINGS; i++) { struct radeon_ring *ring = &rdev->ring[i]; @@ -1098,6 +1094,10 @@ /* update displays */ radeon_dpm_display_configuration_changed(rdev); + rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; + rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; + rdev->pm.dpm.single_display = single_display; + if (rdev->asic->dpm.force_performance_level) { if (rdev->pm.dpm.thermal_active) { enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;