Commit 9eabb911 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-fixes-3.15' of git://people.freedesktop.org/~deathsimple/linux into drm-fixes

this is the next pull quested for stashed up radeon fixes for 3.15. As discussed support for Mullins was separated out and will get it's own pull request. Remaining highlights are:
1. Some more patches to better handle PLL limits.
2. Making use of the PFLIP additional to the VBLANK interrupt, otherwise we sometimes miss page flip events.
3. Fix for the UVD command stream parser.
4. Fix for bootup UVD clocks on RV7xx systems.
5. Adding missing error check on dpcd reads.
6. Fixes number of banks calculation on SI.

* 'drm-fixes-3.15' of git://people.freedesktop.org/~deathsimple/linux:
  drm/radeon: lower the ref * post PLL maximum
  drm/radeon: check that we have a clock before PLL setup
  drm/radeon: drm/radeon: add missing radeon_semaphore_free to error path
  drm/radeon: Fix num_banks calculation for SI
  drm/radeon/dp: check for errors in dpcd reads
  drm/radeon: avoid high jitter with small frac divs
  drm/radeon: check buffer relocation offset
  drm/radeon: use pflip irq on R600+ v2
  drm/radeon/uvd: use lower clocks on old UVD to boot v2
parents 3cf0b031 cbe65513
...@@ -1177,16 +1177,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, ...@@ -1177,16 +1177,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
/* Set NUM_BANKS. */ /* Set NUM_BANKS. */
if (rdev->family >= CHIP_TAHITI) { if (rdev->family >= CHIP_TAHITI) {
unsigned tileb, index, num_banks, tile_split_bytes; unsigned index, num_banks;
if (rdev->family >= CHIP_BONAIRE) {
unsigned tileb, tile_split_bytes;
/* Calculate the macrotile mode index. */ /* Calculate the macrotile mode index. */
tile_split_bytes = 64 << tile_split; tile_split_bytes = 64 << tile_split;
tileb = 8 * 8 * target_fb->bits_per_pixel / 8; tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
tileb = min(tile_split_bytes, tileb); tileb = min(tile_split_bytes, tileb);
for (index = 0; tileb > 64; index++) { for (index = 0; tileb > 64; index++)
tileb >>= 1; tileb >>= 1;
}
if (index >= 16) { if (index >= 16) {
DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
...@@ -1194,10 +1196,24 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, ...@@ -1194,10 +1196,24 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
return -EINVAL; return -EINVAL;
} }
if (rdev->family >= CHIP_BONAIRE)
num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
else } else {
switch (target_fb->bits_per_pixel) {
case 8:
index = 10;
break;
case 16:
index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
break;
default:
case 32:
index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
break;
}
num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3; num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
}
fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
} else { } else {
/* NI and older. */ /* NI and older. */
...@@ -1885,6 +1901,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1885,6 +1901,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
is_tvcv = true; is_tvcv = true;
if (!radeon_crtc->adjusted_clock)
return -EINVAL;
atombios_crtc_set_pll(crtc, adjusted_mode); atombios_crtc_set_pll(crtc, adjusted_mode);
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
......
...@@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) ...@@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return; return;
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3)) if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]); buf[0], buf[1], buf[2]);
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3)) if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]); buf[0], buf[1], buf[2]);
} }
...@@ -419,8 +419,8 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ...@@ -419,8 +419,8 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
if (dp_bridge != ENCODER_OBJECT_ID_NONE) { if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
/* DP bridge chips */ /* DP bridge chips */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp); DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1) if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
...@@ -428,13 +428,15 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ...@@ -428,13 +428,15 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else else
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
}
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP */ /* eDP */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp); DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1) if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
} }
}
return panel_mode; return panel_mode;
} }
...@@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder, ...@@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
else else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp); if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
== 1) {
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true; dp_info.tp3_supported = true;
else else
dp_info.tp3_supported = false; dp_info.tp3_supported = false;
} else {
dp_info.tp3_supported = false;
}
memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
dp_info.rdev = rdev; dp_info.rdev = rdev;
......
...@@ -3702,6 +3702,7 @@ int cik_copy_cpdma(struct radeon_device *rdev, ...@@ -3702,6 +3702,7 @@ int cik_copy_cpdma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
...@@ -6693,6 +6694,19 @@ static void cik_disable_interrupt_state(struct radeon_device *rdev) ...@@ -6693,6 +6694,19 @@ static void cik_disable_interrupt_state(struct radeon_device *rdev)
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
} }
/* pflip */
if (rdev->num_crtc >= 2) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
}
if (rdev->num_crtc >= 4) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
}
if (rdev->num_crtc >= 6) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
/* dac hotplug */ /* dac hotplug */
WREG32(DAC_AUTODETECT_INT_CONTROL, 0); WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
...@@ -7049,6 +7063,25 @@ int cik_irq_set(struct radeon_device *rdev) ...@@ -7049,6 +7063,25 @@ int cik_irq_set(struct radeon_device *rdev)
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
} }
if (rdev->num_crtc >= 2) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
}
if (rdev->num_crtc >= 4) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
}
if (rdev->num_crtc >= 6) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
}
WREG32(DC_HPD1_INT_CONTROL, hpd1); WREG32(DC_HPD1_INT_CONTROL, hpd1);
WREG32(DC_HPD2_INT_CONTROL, hpd2); WREG32(DC_HPD2_INT_CONTROL, hpd2);
WREG32(DC_HPD3_INT_CONTROL, hpd3); WREG32(DC_HPD3_INT_CONTROL, hpd3);
...@@ -7085,6 +7118,29 @@ static inline void cik_irq_ack(struct radeon_device *rdev) ...@@ -7085,6 +7118,29 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6); rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6);
rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC0_REGISTER_OFFSET);
rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC1_REGISTER_OFFSET);
if (rdev->num_crtc >= 4) {
rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC2_REGISTER_OFFSET);
rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC3_REGISTER_OFFSET);
}
if (rdev->num_crtc >= 6) {
rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC4_REGISTER_OFFSET);
rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS +
EVERGREEN_CRTC5_REGISTER_OFFSET);
}
if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
...@@ -7095,6 +7151,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev) ...@@ -7095,6 +7151,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
if (rdev->num_crtc >= 4) { if (rdev->num_crtc >= 4) {
if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
...@@ -7106,6 +7168,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev) ...@@ -7106,6 +7168,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
} }
if (rdev->num_crtc >= 6) { if (rdev->num_crtc >= 6) {
if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET,
GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
...@@ -7457,6 +7525,15 @@ int cik_irq_process(struct radeon_device *rdev) ...@@ -7457,6 +7525,15 @@ int cik_irq_process(struct radeon_device *rdev)
break; break;
} }
break; break;
case 8: /* D1 page flip */
case 10: /* D2 page flip */
case 12: /* D3 page flip */
case 14: /* D4 page flip */
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */ case 42: /* HPD hotplug */
switch (src_data) { switch (src_data) {
case 0: case 0:
......
...@@ -562,6 +562,7 @@ int cik_copy_dma(struct radeon_device *rdev, ...@@ -562,6 +562,7 @@ int cik_copy_dma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
......
...@@ -888,6 +888,15 @@ ...@@ -888,6 +888,15 @@
# define DC_HPD6_RX_INTERRUPT (1 << 18) # define DC_HPD6_RX_INTERRUPT (1 << 18)
#define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780 #define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780
/* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */
#define GRPH_INT_STATUS 0x6858
# define GRPH_PFLIP_INT_OCCURRED (1 << 0)
# define GRPH_PFLIP_INT_CLEAR (1 << 8)
/* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */
#define GRPH_INT_CONTROL 0x685c
# define GRPH_PFLIP_INT_MASK (1 << 0)
# define GRPH_PFLIP_INT_TYPE (1 << 8)
#define DAC_AUTODETECT_INT_CONTROL 0x67c8 #define DAC_AUTODETECT_INT_CONTROL 0x67c8
#define DC_HPD1_INT_STATUS 0x601c #define DC_HPD1_INT_STATUS 0x601c
......
...@@ -4371,7 +4371,6 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4371,7 +4371,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
u32 grbm_int_cntl = 0; u32 grbm_int_cntl = 0;
u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
u32 dma_cntl, dma_cntl1 = 0; u32 dma_cntl, dma_cntl1 = 0;
u32 thermal_int = 0; u32 thermal_int = 0;
...@@ -4554,15 +4553,21 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -4554,15 +4553,21 @@ int evergreen_irq_set(struct radeon_device *rdev)
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
} }
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
if (rdev->num_crtc >= 4) { if (rdev->num_crtc >= 4) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
} }
if (rdev->num_crtc >= 6) { if (rdev->num_crtc >= 6) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
} }
WREG32(DC_HPD1_INT_CONTROL, hpd1); WREG32(DC_HPD1_INT_CONTROL, hpd1);
...@@ -4951,6 +4956,15 @@ int evergreen_irq_process(struct radeon_device *rdev) ...@@ -4951,6 +4956,15 @@ int evergreen_irq_process(struct radeon_device *rdev)
break; break;
} }
break; break;
case 8: /* D1 page flip */
case 10: /* D2 page flip */
case 12: /* D3 page flip */
case 14: /* D4 page flip */
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */ case 42: /* HPD hotplug */
switch (src_data) { switch (src_data) {
case 0: case 0:
......
...@@ -151,6 +151,7 @@ int evergreen_copy_dma(struct radeon_device *rdev, ...@@ -151,6 +151,7 @@ int evergreen_copy_dma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
......
...@@ -2839,6 +2839,7 @@ int r600_copy_cpdma(struct radeon_device *rdev, ...@@ -2839,6 +2839,7 @@ int r600_copy_cpdma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
...@@ -3505,7 +3506,6 @@ int r600_irq_set(struct radeon_device *rdev) ...@@ -3505,7 +3506,6 @@ int r600_irq_set(struct radeon_device *rdev)
u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
u32 grbm_int_cntl = 0; u32 grbm_int_cntl = 0;
u32 hdmi0, hdmi1; u32 hdmi0, hdmi1;
u32 d1grph = 0, d2grph = 0;
u32 dma_cntl; u32 dma_cntl;
u32 thermal_int = 0; u32 thermal_int = 0;
...@@ -3614,8 +3614,8 @@ int r600_irq_set(struct radeon_device *rdev) ...@@ -3614,8 +3614,8 @@ int r600_irq_set(struct radeon_device *rdev)
WREG32(CP_INT_CNTL, cp_int_cntl); WREG32(CP_INT_CNTL, cp_int_cntl);
WREG32(DMA_CNTL, dma_cntl); WREG32(DMA_CNTL, dma_cntl);
WREG32(DxMODE_INT_MASK, mode_int); WREG32(DxMODE_INT_MASK, mode_int);
WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
WREG32(GRBM_INT_CNTL, grbm_int_cntl); WREG32(GRBM_INT_CNTL, grbm_int_cntl);
if (ASIC_IS_DCE3(rdev)) { if (ASIC_IS_DCE3(rdev)) {
WREG32(DC_HPD1_INT_CONTROL, hpd1); WREG32(DC_HPD1_INT_CONTROL, hpd1);
...@@ -3918,6 +3918,14 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -3918,6 +3918,14 @@ int r600_irq_process(struct radeon_device *rdev)
break; break;
} }
break; break;
case 9: /* D1 pflip */
DRM_DEBUG("IH: D1 flip\n");
radeon_crtc_handle_flip(rdev, 0);
break;
case 11: /* D2 pflip */
DRM_DEBUG("IH: D2 flip\n");
radeon_crtc_handle_flip(rdev, 1);
break;
case 19: /* HPD/DAC hotplug */ case 19: /* HPD/DAC hotplug */
switch (src_data) { switch (src_data) {
case 0: case 0:
......
...@@ -489,6 +489,7 @@ int r600_copy_dma(struct radeon_device *rdev, ...@@ -489,6 +489,7 @@ int r600_copy_dma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
......
...@@ -730,6 +730,12 @@ struct cik_irq_stat_regs { ...@@ -730,6 +730,12 @@ struct cik_irq_stat_regs {
u32 disp_int_cont4; u32 disp_int_cont4;
u32 disp_int_cont5; u32 disp_int_cont5;
u32 disp_int_cont6; u32 disp_int_cont6;
u32 d1grph_int;
u32 d2grph_int;
u32 d3grph_int;
u32 d4grph_int;
u32 d5grph_int;
u32 d6grph_int;
}; };
union radeon_irq_stat_regs { union radeon_irq_stat_regs {
......
...@@ -284,6 +284,10 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) ...@@ -284,6 +284,10 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
u32 update_pending; u32 update_pending;
int vpos, hpos; int vpos, hpos;
/* can happen during initialization */
if (radeon_crtc == NULL)
return;
spin_lock_irqsave(&rdev->ddev->event_lock, flags); spin_lock_irqsave(&rdev->ddev->event_lock, flags);
work = radeon_crtc->unpin_work; work = radeon_crtc->unpin_work;
if (work == NULL || if (work == NULL ||
...@@ -826,14 +830,14 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den, ...@@ -826,14 +830,14 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
/* make sure nominator is large enough */ /* make sure nominator is large enough */
if (*nom < nom_min) { if (*nom < nom_min) {
tmp = (nom_min + *nom - 1) / *nom; tmp = DIV_ROUND_UP(nom_min, *nom);
*nom *= tmp; *nom *= tmp;
*den *= tmp; *den *= tmp;
} }
/* make sure the denominator is large enough */ /* make sure the denominator is large enough */
if (*den < den_min) { if (*den < den_min) {
tmp = (den_min + *den - 1) / *den; tmp = DIV_ROUND_UP(den_min, *den);
*nom *= tmp; *nom *= tmp;
*den *= tmp; *den *= tmp;
} }
...@@ -858,7 +862,7 @@ static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div, ...@@ -858,7 +862,7 @@ static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
unsigned *fb_div, unsigned *ref_div) unsigned *fb_div, unsigned *ref_div)
{ {
/* limit reference * post divider to a maximum */ /* limit reference * post divider to a maximum */
ref_div_max = min(210 / post_div, ref_div_max); ref_div_max = min(128 / post_div, ref_div_max);
/* get matching reference and feedback divider */ /* get matching reference and feedback divider */
*ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max); *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
...@@ -993,6 +997,16 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ...@@ -993,6 +997,16 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
/* this also makes sure that the reference divider is large enough */ /* this also makes sure that the reference divider is large enough */
avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min); avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
/* avoid high jitter with small fractional dividers */
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60);
if (fb_div < fb_div_min) {
unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
fb_div *= tmp;
ref_div *= tmp;
}
}
/* and finally save the result */ /* and finally save the result */
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
*fb_div_p = fb_div / 10; *fb_div_p = fb_div / 10;
......
...@@ -465,6 +465,10 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, ...@@ -465,6 +465,10 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
cmd = radeon_get_ib_value(p, p->idx) >> 1; cmd = radeon_get_ib_value(p, p->idx) >> 1;
if (cmd < 0x4) { if (cmd < 0x4) {
if (end <= start) {
DRM_ERROR("invalid reloc offset %X!\n", offset);
return -EINVAL;
}
if ((end - start) < buf_sizes[cmd]) { if ((end - start) < buf_sizes[cmd]) {
DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
(unsigned)(end - start), buf_sizes[cmd]); (unsigned)(end - start), buf_sizes[cmd]);
......
...@@ -86,6 +86,7 @@ int rv770_copy_dma(struct radeon_device *rdev, ...@@ -86,6 +86,7 @@ int rv770_copy_dma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
......
...@@ -5780,7 +5780,6 @@ int si_irq_set(struct radeon_device *rdev) ...@@ -5780,7 +5780,6 @@ int si_irq_set(struct radeon_device *rdev)
u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0; u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0;
u32 grbm_int_cntl = 0; u32 grbm_int_cntl = 0;
u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
u32 dma_cntl, dma_cntl1; u32 dma_cntl, dma_cntl1;
u32 thermal_int = 0; u32 thermal_int = 0;
...@@ -5919,16 +5918,22 @@ int si_irq_set(struct radeon_device *rdev) ...@@ -5919,16 +5918,22 @@ int si_irq_set(struct radeon_device *rdev)
} }
if (rdev->num_crtc >= 2) { if (rdev->num_crtc >= 2) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
} }
if (rdev->num_crtc >= 4) { if (rdev->num_crtc >= 4) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
} }
if (rdev->num_crtc >= 6) { if (rdev->num_crtc >= 6) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); GRPH_PFLIP_INT_MASK);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
GRPH_PFLIP_INT_MASK);
} }
if (!ASIC_IS_NODCE(rdev)) { if (!ASIC_IS_NODCE(rdev)) {
...@@ -6292,6 +6297,15 @@ int si_irq_process(struct radeon_device *rdev) ...@@ -6292,6 +6297,15 @@ int si_irq_process(struct radeon_device *rdev)
break; break;
} }
break; break;
case 8: /* D1 page flip */
case 10: /* D2 page flip */
case 12: /* D3 page flip */
case 14: /* D4 page flip */
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */ case 42: /* HPD hotplug */
switch (src_data) { switch (src_data) {
case 0: case 0:
......
...@@ -213,6 +213,7 @@ int si_copy_dma(struct radeon_device *rdev, ...@@ -213,6 +213,7 @@ int si_copy_dma(struct radeon_device *rdev,
r = radeon_fence_emit(rdev, fence, ring->idx); r = radeon_fence_emit(rdev, fence, ring->idx);
if (r) { if (r) {
radeon_ring_unlock_undo(rdev, ring); radeon_ring_unlock_undo(rdev, ring);
radeon_semaphore_free(rdev, &sem, NULL);
return r; return r;
} }
......
...@@ -83,6 +83,9 @@ int uvd_v1_0_init(struct radeon_device *rdev) ...@@ -83,6 +83,9 @@ int uvd_v1_0_init(struct radeon_device *rdev)
int r; int r;
/* raise clocks while booting up the VCPU */ /* raise clocks while booting up the VCPU */
if (rdev->family < CHIP_RV740)
radeon_set_uvd_clocks(rdev, 10000, 10000);
else
radeon_set_uvd_clocks(rdev, 53300, 40000); radeon_set_uvd_clocks(rdev, 53300, 40000);
r = uvd_v1_0_start(rdev); r = uvd_v1_0_start(rdev);
...@@ -407,6 +410,9 @@ int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) ...@@ -407,6 +410,9 @@ int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
struct radeon_fence *fence = NULL; struct radeon_fence *fence = NULL;
int r; int r;
if (rdev->family < CHIP_RV740)
r = radeon_set_uvd_clocks(rdev, 10000, 10000);
else
r = radeon_set_uvd_clocks(rdev, 53300, 40000); r = radeon_set_uvd_clocks(rdev, 53300, 40000);
if (r) { if (r) {
DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r); DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment