Commit 3f838fc5 authored by Dave Airlie's avatar Dave Airlie

Merge remote branch 'korg/drm-radeon-next' into drm-linus

This merges all the radeon changes that weren't reliant on core-next.
parents 3ff99164 22dd5013
...@@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
...@@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
if (ASIC_IS_DCE3(rdev)) if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, 1); atombios_enable_crtc_memreq(crtc, 1);
atombios_blank_crtc(crtc, 0); atombios_blank_crtc(crtc, 0);
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
radeon_crtc_load_lut(crtc);
break; break;
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
atombios_blank_crtc(crtc, 1); atombios_blank_crtc(crtc, 1);
if (ASIC_IS_DCE3(rdev)) if (ASIC_IS_DCE3(rdev))
atombios_enable_crtc_memreq(crtc, 0); atombios_enable_crtc_memreq(crtc, 0);
atombios_enable_crtc(crtc, 0); atombios_enable_crtc(crtc, 0);
break; break;
} }
if (mode != DRM_MODE_DPMS_OFF) {
radeon_crtc_load_lut(crtc);
}
} }
static void static void
...@@ -457,9 +457,8 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -457,9 +457,8 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (encoder->encoder_type != if (encoder->encoder_type !=
DRM_MODE_ENCODER_DAC) DRM_MODE_ENCODER_DAC)
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
if (!ASIC_IS_AVIVO(rdev) if (encoder->encoder_type ==
&& (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
DRM_MODE_ENCODER_LVDS))
pll_flags |= RADEON_PLL_USE_REF_DIV; pll_flags |= RADEON_PLL_USE_REF_DIV;
} }
radeon_encoder = to_radeon_encoder(encoder); radeon_encoder = to_radeon_encoder(encoder);
...@@ -574,21 +573,34 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -574,21 +573,34 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_framebuffer *radeon_fb; struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct drm_radeon_gem_object *obj_priv; struct radeon_bo *rbo;
uint64_t fb_location; uint64_t fb_location;
uint32_t fb_format, fb_pitch_pixels, tiling_flags; uint32_t fb_format, fb_pitch_pixels, tiling_flags;
int r;
if (!crtc->fb) /* no fb bound */
return -EINVAL; if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
return 0;
}
radeon_fb = to_radeon_framebuffer(crtc->fb); radeon_fb = to_radeon_framebuffer(crtc->fb);
/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj; obj = radeon_fb->obj;
obj_priv = obj->driver_private; rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) { if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
if (unlikely(r != 0)) {
radeon_bo_unreserve(rbo);
return -EINVAL; return -EINVAL;
} }
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
switch (crtc->fb->bits_per_pixel) { switch (crtc->fb->bits_per_pixel) {
case 8: case 8:
...@@ -618,11 +630,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -618,11 +630,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return -EINVAL; return -EINVAL;
} }
radeon_object_get_tiling_flags(obj->driver_private,
&tiling_flags, NULL);
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
if (tiling_flags & RADEON_TILING_MICRO) if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= AVIVO_D1GRPH_TILED; fb_format |= AVIVO_D1GRPH_TILED;
...@@ -674,7 +681,12 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -674,7 +681,12 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
if (old_fb && old_fb != crtc->fb) { if (old_fb && old_fb != crtc->fb) {
radeon_fb = to_radeon_framebuffer(old_fb); radeon_fb = to_radeon_framebuffer(old_fb);
radeon_gem_object_unpin(radeon_fb->obj); rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
} }
/* Bytes per pixel may have changed */ /* Bytes per pixel may have changed */
......
...@@ -94,6 +94,15 @@ int r100_pci_gart_init(struct radeon_device *rdev) ...@@ -94,6 +94,15 @@ int r100_pci_gart_init(struct radeon_device *rdev)
return radeon_gart_table_ram_alloc(rdev); return radeon_gart_table_ram_alloc(rdev);
} }
/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
void r100_enable_bm(struct radeon_device *rdev)
{
uint32_t tmp;
/* Enable bus mastering */
tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
WREG32(RADEON_BUS_CNTL, tmp);
}
int r100_pci_gart_enable(struct radeon_device *rdev) int r100_pci_gart_enable(struct radeon_device *rdev)
{ {
uint32_t tmp; uint32_t tmp;
...@@ -105,9 +114,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev) ...@@ -105,9 +114,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location); WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
WREG32(RADEON_AIC_HI_ADDR, tmp); WREG32(RADEON_AIC_HI_ADDR, tmp);
/* Enable bus mastering */
tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
WREG32(RADEON_BUS_CNTL, tmp);
/* set PCI GART page-table base address */ /* set PCI GART page-table base address */
WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
...@@ -255,24 +261,27 @@ int r100_wb_init(struct radeon_device *rdev) ...@@ -255,24 +261,27 @@ int r100_wb_init(struct radeon_device *rdev)
int r; int r;
if (rdev->wb.wb_obj == NULL) { if (rdev->wb.wb_obj == NULL) {
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
true, RADEON_GEM_DOMAIN_GTT,
RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
false, &rdev->wb.wb_obj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
return r; return r;
} }
r = radeon_object_pin(rdev->wb.wb_obj, r = radeon_bo_reserve(rdev->wb.wb_obj, false);
RADEON_GEM_DOMAIN_GTT, if (unlikely(r != 0))
&rdev->wb.gpu_addr); return r;
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
&rdev->wb.gpu_addr);
if (r) { if (r) {
DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
radeon_bo_unreserve(rdev->wb.wb_obj);
return r; return r;
} }
r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
radeon_bo_unreserve(rdev->wb.wb_obj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
return r; return r;
} }
} }
...@@ -290,11 +299,19 @@ void r100_wb_disable(struct radeon_device *rdev) ...@@ -290,11 +299,19 @@ void r100_wb_disable(struct radeon_device *rdev)
void r100_wb_fini(struct radeon_device *rdev) void r100_wb_fini(struct radeon_device *rdev)
{ {
int r;
r100_wb_disable(rdev); r100_wb_disable(rdev);
if (rdev->wb.wb_obj) { if (rdev->wb.wb_obj) {
radeon_object_kunmap(rdev->wb.wb_obj); r = radeon_bo_reserve(rdev->wb.wb_obj, false);
radeon_object_unpin(rdev->wb.wb_obj); if (unlikely(r != 0)) {
radeon_object_unref(&rdev->wb.wb_obj); dev_err(rdev->dev, "(%d) can't finish WB\n", r);
return;
}
radeon_bo_kunmap(rdev->wb.wb_obj);
radeon_bo_unpin(rdev->wb.wb_obj);
radeon_bo_unreserve(rdev->wb.wb_obj);
radeon_bo_unref(&rdev->wb.wb_obj);
rdev->wb.wb = NULL; rdev->wb.wb = NULL;
rdev->wb.wb_obj = NULL; rdev->wb.wb_obj = NULL;
} }
...@@ -1288,17 +1305,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ...@@ -1288,17 +1305,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt, struct radeon_cs_packet *pkt,
struct radeon_object *robj) struct radeon_bo *robj)
{ {
unsigned idx; unsigned idx;
u32 value; u32 value;
idx = pkt->idx + 1; idx = pkt->idx + 1;
value = radeon_get_ib_value(p, idx + 2); value = radeon_get_ib_value(p, idx + 2);
if ((value + 1) > radeon_object_size(robj)) { if ((value + 1) > radeon_bo_size(robj)) {
DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
"(need %u have %lu) !\n", "(need %u have %lu) !\n",
value + 1, value + 1,
radeon_object_size(robj)); radeon_bo_size(robj));
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
...@@ -1583,6 +1600,14 @@ void r100_gpu_init(struct radeon_device *rdev) ...@@ -1583,6 +1600,14 @@ void r100_gpu_init(struct radeon_device *rdev)
r100_hdp_reset(rdev); r100_hdp_reset(rdev);
} }
void r100_hdp_flush(struct radeon_device *rdev)
{
u32 tmp;
tmp = RREG32(RADEON_HOST_PATH_CNTL);
tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE;
WREG32(RADEON_HOST_PATH_CNTL, tmp);
}
void r100_hdp_reset(struct radeon_device *rdev) void r100_hdp_reset(struct radeon_device *rdev)
{ {
uint32_t tmp; uint32_t tmp;
...@@ -1650,6 +1675,17 @@ int r100_gpu_reset(struct radeon_device *rdev) ...@@ -1650,6 +1675,17 @@ int r100_gpu_reset(struct radeon_device *rdev)
return 0; return 0;
} }
void r100_set_common_regs(struct radeon_device *rdev)
{
/* set these so they don't interfere with anything */
WREG32(RADEON_OV0_SCALE_CNTL, 0);
WREG32(RADEON_SUBPIC_CNTL, 0);
WREG32(RADEON_VIPH_CONTROL, 0);
WREG32(RADEON_I2C_CNTL_1, 0);
WREG32(RADEON_DVI_I2C_CNTL_1, 0);
WREG32(RADEON_CAP0_TRIG_CNTL, 0);
WREG32(RADEON_CAP1_TRIG_CNTL, 0);
}
/* /*
* VRAM info * VRAM info
...@@ -2594,7 +2630,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev, ...@@ -2594,7 +2630,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
struct r100_cs_track *track, unsigned idx) struct r100_cs_track *track, unsigned idx)
{ {
unsigned face, w, h; unsigned face, w, h;
struct radeon_object *cube_robj; struct radeon_bo *cube_robj;
unsigned long size; unsigned long size;
for (face = 0; face < 5; face++) { for (face = 0; face < 5; face++) {
...@@ -2607,9 +2643,9 @@ static int r100_cs_track_cube(struct radeon_device *rdev, ...@@ -2607,9 +2643,9 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
size += track->textures[idx].cube_info[face].offset; size += track->textures[idx].cube_info[face].offset;
if (size > radeon_object_size(cube_robj)) { if (size > radeon_bo_size(cube_robj)) {
DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
size, radeon_object_size(cube_robj)); size, radeon_bo_size(cube_robj));
r100_cs_track_texture_print(&track->textures[idx]); r100_cs_track_texture_print(&track->textures[idx]);
return -1; return -1;
} }
...@@ -2620,7 +2656,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev, ...@@ -2620,7 +2656,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
static int r100_cs_track_texture_check(struct radeon_device *rdev, static int r100_cs_track_texture_check(struct radeon_device *rdev,
struct r100_cs_track *track) struct r100_cs_track *track)
{ {
struct radeon_object *robj; struct radeon_bo *robj;
unsigned long size; unsigned long size;
unsigned u, i, w, h; unsigned u, i, w, h;
int ret; int ret;
...@@ -2676,9 +2712,9 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, ...@@ -2676,9 +2712,9 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
"%u\n", track->textures[u].tex_coord_type, u); "%u\n", track->textures[u].tex_coord_type, u);
return -EINVAL; return -EINVAL;
} }
if (size > radeon_object_size(robj)) { if (size > radeon_bo_size(robj)) {
DRM_ERROR("Texture of unit %u needs %lu bytes but is " DRM_ERROR("Texture of unit %u needs %lu bytes but is "
"%lu\n", u, size, radeon_object_size(robj)); "%lu\n", u, size, radeon_bo_size(robj));
r100_cs_track_texture_print(&track->textures[u]); r100_cs_track_texture_print(&track->textures[u]);
return -EINVAL; return -EINVAL;
} }
...@@ -2700,10 +2736,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -2700,10 +2736,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
} }
size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
size += track->cb[i].offset; size += track->cb[i].offset;
if (size > radeon_object_size(track->cb[i].robj)) { if (size > radeon_bo_size(track->cb[i].robj)) {
DRM_ERROR("[drm] Buffer too small for color buffer %d " DRM_ERROR("[drm] Buffer too small for color buffer %d "
"(need %lu have %lu) !\n", i, size, "(need %lu have %lu) !\n", i, size,
radeon_object_size(track->cb[i].robj)); radeon_bo_size(track->cb[i].robj));
DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
i, track->cb[i].pitch, track->cb[i].cpp, i, track->cb[i].pitch, track->cb[i].cpp,
track->cb[i].offset, track->maxy); track->cb[i].offset, track->maxy);
...@@ -2717,10 +2753,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -2717,10 +2753,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
} }
size = track->zb.pitch * track->zb.cpp * track->maxy; size = track->zb.pitch * track->zb.cpp * track->maxy;
size += track->zb.offset; size += track->zb.offset;
if (size > radeon_object_size(track->zb.robj)) { if (size > radeon_bo_size(track->zb.robj)) {
DRM_ERROR("[drm] Buffer too small for z buffer " DRM_ERROR("[drm] Buffer too small for z buffer "
"(need %lu have %lu) !\n", size, "(need %lu have %lu) !\n", size,
radeon_object_size(track->zb.robj)); radeon_bo_size(track->zb.robj));
DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
track->zb.pitch, track->zb.cpp, track->zb.pitch, track->zb.cpp,
track->zb.offset, track->maxy); track->zb.offset, track->maxy);
...@@ -2738,11 +2774,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -2738,11 +2774,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
"bound\n", prim_walk, i); "bound\n", prim_walk, i);
return -EINVAL; return -EINVAL;
} }
if (size > radeon_object_size(track->arrays[i].robj)) { if (size > radeon_bo_size(track->arrays[i].robj)) {
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " dev_err(rdev->dev, "(PW %u) Vertex array %u "
"have %lu dwords\n", prim_walk, i, "need %lu dwords have %lu dwords\n",
size >> 2, prim_walk, i, size >> 2,
radeon_object_size(track->arrays[i].robj) >> 2); radeon_bo_size(track->arrays[i].robj)
>> 2);
DRM_ERROR("Max indices %u\n", track->max_indx); DRM_ERROR("Max indices %u\n", track->max_indx);
return -EINVAL; return -EINVAL;
} }
...@@ -2756,10 +2793,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -2756,10 +2793,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
"bound\n", prim_walk, i); "bound\n", prim_walk, i);
return -EINVAL; return -EINVAL;
} }
if (size > radeon_object_size(track->arrays[i].robj)) { if (size > radeon_bo_size(track->arrays[i].robj)) {
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " dev_err(rdev->dev, "(PW %u) Vertex array %u "
"have %lu dwords\n", prim_walk, i, size >> 2, "need %lu dwords have %lu dwords\n",
radeon_object_size(track->arrays[i].robj) >> 2); prim_walk, i, size >> 2,
radeon_bo_size(track->arrays[i].robj)
>> 2);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -3101,6 +3140,9 @@ static int r100_startup(struct radeon_device *rdev) ...@@ -3101,6 +3140,9 @@ static int r100_startup(struct radeon_device *rdev)
{ {
int r; int r;
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r100_mc_program(rdev); r100_mc_program(rdev);
/* Resume clock */ /* Resume clock */
r100_clock_startup(rdev); r100_clock_startup(rdev);
...@@ -3108,13 +3150,13 @@ static int r100_startup(struct radeon_device *rdev) ...@@ -3108,13 +3150,13 @@ static int r100_startup(struct radeon_device *rdev)
r100_gpu_init(rdev); r100_gpu_init(rdev);
/* Initialize GART (initialize after TTM so we can allocate /* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */ * memory through TTM but finalize after TTM) */
r100_enable_bm(rdev);
if (rdev->flags & RADEON_IS_PCI) { if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_enable(rdev); r = r100_pci_gart_enable(rdev);
if (r) if (r)
return r; return r;
} }
/* Enable IRQ */ /* Enable IRQ */
rdev->irq.sw_int = true;
r100_irq_set(rdev); r100_irq_set(rdev);
/* 1M ring buffer */ /* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024); r = r100_cp_init(rdev, 1024 * 1024);
...@@ -3174,7 +3216,7 @@ void r100_fini(struct radeon_device *rdev) ...@@ -3174,7 +3216,7 @@ void r100_fini(struct radeon_device *rdev)
r100_pci_gart_fini(rdev); r100_pci_gart_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev); radeon_bo_fini(rdev);
radeon_atombios_fini(rdev); radeon_atombios_fini(rdev);
kfree(rdev->bios); kfree(rdev->bios);
rdev->bios = NULL; rdev->bios = NULL;
...@@ -3242,10 +3284,8 @@ int r100_init(struct radeon_device *rdev) ...@@ -3242,10 +3284,8 @@ int r100_init(struct radeon_device *rdev)
RREG32(R_0007C0_CP_STAT)); RREG32(R_0007C0_CP_STAT));
} }
/* check if cards are posted or not */ /* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) { if (radeon_boot_test_post_card(rdev) == false)
DRM_INFO("GPU not posted. posting now...\n"); return -EINVAL;
radeon_combios_asic_init(rdev->ddev);
}
/* Set asic errata */ /* Set asic errata */
r100_errata(rdev); r100_errata(rdev);
/* Initialize clocks */ /* Initialize clocks */
...@@ -3264,7 +3304,7 @@ int r100_init(struct radeon_device *rdev) ...@@ -3264,7 +3304,7 @@ int r100_init(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
/* Memory manager */ /* Memory manager */
r = radeon_object_init(rdev); r = radeon_bo_init(rdev);
if (r) if (r)
return r; return r;
if (rdev->flags & RADEON_IS_PCI) { if (rdev->flags & RADEON_IS_PCI) {
......
...@@ -10,26 +10,26 @@ ...@@ -10,26 +10,26 @@
* CS functions * CS functions
*/ */
struct r100_cs_track_cb { struct r100_cs_track_cb {
struct radeon_object *robj; struct radeon_bo *robj;
unsigned pitch; unsigned pitch;
unsigned cpp; unsigned cpp;
unsigned offset; unsigned offset;
}; };
struct r100_cs_track_array { struct r100_cs_track_array {
struct radeon_object *robj; struct radeon_bo *robj;
unsigned esize; unsigned esize;
}; };
struct r100_cs_cube_info { struct r100_cs_cube_info {
struct radeon_object *robj; struct radeon_bo *robj;
unsigned offset; unsigned offset;
unsigned width; unsigned width;
unsigned height; unsigned height;
}; };
struct r100_cs_track_texture { struct r100_cs_track_texture {
struct radeon_object *robj; struct radeon_bo *robj;
struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
unsigned pitch; unsigned pitch;
unsigned width; unsigned width;
......
...@@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) ...@@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
void rv370_pcie_gart_disable(struct radeon_device *rdev) void rv370_pcie_gart_disable(struct radeon_device *rdev)
{ {
uint32_t tmp; u32 tmp;
int r;
tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
if (rdev->gart.table.vram.robj) { if (rdev->gart.table.vram.robj) {
radeon_object_kunmap(rdev->gart.table.vram.robj); r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
radeon_object_unpin(rdev->gart.table.vram.robj); if (likely(r == 0)) {
radeon_bo_kunmap(rdev->gart.table.vram.robj);
radeon_bo_unpin(rdev->gart.table.vram.robj);
radeon_bo_unreserve(rdev->gart.table.vram.robj);
}
} }
} }
...@@ -1181,6 +1186,9 @@ static int r300_startup(struct radeon_device *rdev) ...@@ -1181,6 +1186,9 @@ static int r300_startup(struct radeon_device *rdev)
{ {
int r; int r;
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r300_mc_program(rdev); r300_mc_program(rdev);
/* Resume clock */ /* Resume clock */
r300_clock_startup(rdev); r300_clock_startup(rdev);
...@@ -1193,13 +1201,18 @@ static int r300_startup(struct radeon_device *rdev) ...@@ -1193,13 +1201,18 @@ static int r300_startup(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
} }
if (rdev->family == CHIP_R300 ||
rdev->family == CHIP_R350 ||
rdev->family == CHIP_RV350)
r100_enable_bm(rdev);
if (rdev->flags & RADEON_IS_PCI) { if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_enable(rdev); r = r100_pci_gart_enable(rdev);
if (r) if (r)
return r; return r;
} }
/* Enable IRQ */ /* Enable IRQ */
rdev->irq.sw_int = true;
r100_irq_set(rdev); r100_irq_set(rdev);
/* 1M ring buffer */ /* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024); r = r100_cp_init(rdev, 1024 * 1024);
...@@ -1265,7 +1278,7 @@ void r300_fini(struct radeon_device *rdev) ...@@ -1265,7 +1278,7 @@ void r300_fini(struct radeon_device *rdev)
r100_pci_gart_fini(rdev); r100_pci_gart_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev); radeon_bo_fini(rdev);
radeon_atombios_fini(rdev); radeon_atombios_fini(rdev);
kfree(rdev->bios); kfree(rdev->bios);
rdev->bios = NULL; rdev->bios = NULL;
...@@ -1303,10 +1316,8 @@ int r300_init(struct radeon_device *rdev) ...@@ -1303,10 +1316,8 @@ int r300_init(struct radeon_device *rdev)
RREG32(R_0007C0_CP_STAT)); RREG32(R_0007C0_CP_STAT));
} }
/* check if cards are posted or not */ /* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) { if (radeon_boot_test_post_card(rdev) == false)
DRM_INFO("GPU not posted. posting now...\n"); return -EINVAL;
radeon_combios_asic_init(rdev->ddev);
}
/* Set asic errata */ /* Set asic errata */
r300_errata(rdev); r300_errata(rdev);
/* Initialize clocks */ /* Initialize clocks */
...@@ -1325,7 +1336,7 @@ int r300_init(struct radeon_device *rdev) ...@@ -1325,7 +1336,7 @@ int r300_init(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
/* Memory manager */ /* Memory manager */
r = radeon_object_init(rdev); r = radeon_bo_init(rdev);
if (r) if (r)
return r; return r;
if (rdev->flags & RADEON_IS_PCIE) { if (rdev->flags & RADEON_IS_PCIE) {
......
...@@ -169,6 +169,9 @@ static int r420_startup(struct radeon_device *rdev) ...@@ -169,6 +169,9 @@ static int r420_startup(struct radeon_device *rdev)
{ {
int r; int r;
/* set common regs */
r100_set_common_regs(rdev);
/* program mc */
r300_mc_program(rdev); r300_mc_program(rdev);
/* Resume clock */ /* Resume clock */
r420_clock_resume(rdev); r420_clock_resume(rdev);
...@@ -186,7 +189,6 @@ static int r420_startup(struct radeon_device *rdev) ...@@ -186,7 +189,6 @@ static int r420_startup(struct radeon_device *rdev)
} }
r420_pipes_init(rdev); r420_pipes_init(rdev);
/* Enable IRQ */ /* Enable IRQ */
rdev->irq.sw_int = true;
r100_irq_set(rdev); r100_irq_set(rdev);
/* 1M ring buffer */ /* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024); r = r100_cp_init(rdev, 1024 * 1024);
...@@ -258,7 +260,7 @@ void r420_fini(struct radeon_device *rdev) ...@@ -258,7 +260,7 @@ void r420_fini(struct radeon_device *rdev)
radeon_agp_fini(rdev); radeon_agp_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev); radeon_bo_fini(rdev);
if (rdev->is_atom_bios) { if (rdev->is_atom_bios) {
radeon_atombios_fini(rdev); radeon_atombios_fini(rdev);
} else { } else {
...@@ -301,14 +303,9 @@ int r420_init(struct radeon_device *rdev) ...@@ -301,14 +303,9 @@ int r420_init(struct radeon_device *rdev)
RREG32(R_0007C0_CP_STAT)); RREG32(R_0007C0_CP_STAT));
} }
/* check if cards are posted or not */ /* check if cards are posted or not */
if (!radeon_card_posted(rdev) && rdev->bios) { if (radeon_boot_test_post_card(rdev) == false)
DRM_INFO("GPU not posted. posting now...\n"); return -EINVAL;
if (rdev->is_atom_bios) {
atom_asic_init(rdev->mode_info.atom_context);
} else {
radeon_combios_asic_init(rdev->ddev);
}
}
/* Initialize clocks */ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev); radeon_get_clock_info(rdev->ddev);
/* Initialize power management */ /* Initialize power management */
...@@ -331,10 +328,13 @@ int r420_init(struct radeon_device *rdev) ...@@ -331,10 +328,13 @@ int r420_init(struct radeon_device *rdev)
return r; return r;
} }
/* Memory manager */ /* Memory manager */
r = radeon_object_init(rdev); r = radeon_bo_init(rdev);
if (r) { if (r) {
return r; return r;
} }
if (rdev->family == CHIP_R420)
r100_enable_bm(rdev);
if (rdev->flags & RADEON_IS_PCIE) { if (rdev->flags & RADEON_IS_PCIE) {
r = rv370_pcie_gart_init(rdev); r = rv370_pcie_gart_init(rdev);
if (r) if (r)
......
...@@ -185,7 +185,6 @@ static int r520_startup(struct radeon_device *rdev) ...@@ -185,7 +185,6 @@ static int r520_startup(struct radeon_device *rdev)
return r; return r;
} }
/* Enable IRQ */ /* Enable IRQ */
rdev->irq.sw_int = true;
rs600_irq_set(rdev); rs600_irq_set(rdev);
/* 1M ring buffer */ /* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024); r = r100_cp_init(rdev, 1024 * 1024);
...@@ -254,6 +253,9 @@ int r520_init(struct radeon_device *rdev) ...@@ -254,6 +253,9 @@ int r520_init(struct radeon_device *rdev)
RREG32(R_0007C0_CP_STAT)); RREG32(R_0007C0_CP_STAT));
} }
/* check if cards are posted or not */ /* check if cards are posted or not */
if (radeon_boot_test_post_card(rdev) == false)
return -EINVAL;
if (!radeon_card_posted(rdev) && rdev->bios) { if (!radeon_card_posted(rdev) && rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n"); DRM_INFO("GPU not posted. posting now...\n");
atom_asic_init(rdev->mode_info.atom_context); atom_asic_init(rdev->mode_info.atom_context);
...@@ -277,7 +279,7 @@ int r520_init(struct radeon_device *rdev) ...@@ -277,7 +279,7 @@ int r520_init(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
/* Memory manager */ /* Memory manager */
r = radeon_object_init(rdev); r = radeon_bo_init(rdev);
if (r) if (r)
return r; return r;
r = rv370_pcie_gart_init(rdev); r = rv370_pcie_gart_init(rdev);
......
This diff is collapsed.
...@@ -473,9 +473,8 @@ int r600_blit_init(struct radeon_device *rdev) ...@@ -473,9 +473,8 @@ int r600_blit_init(struct radeon_device *rdev)
obj_size += r6xx_ps_size * 4; obj_size += r6xx_ps_size * 4;
obj_size = ALIGN(obj_size, 256); obj_size = ALIGN(obj_size, 256);
r = radeon_object_create(rdev, NULL, obj_size, r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
true, RADEON_GEM_DOMAIN_VRAM, &rdev->r600_blit.shader_obj);
false, &rdev->r600_blit.shader_obj);
if (r) { if (r) {
DRM_ERROR("r600 failed to allocate shader\n"); DRM_ERROR("r600 failed to allocate shader\n");
return r; return r;
...@@ -485,12 +484,14 @@ int r600_blit_init(struct radeon_device *rdev) ...@@ -485,12 +484,14 @@ int r600_blit_init(struct radeon_device *rdev)
obj_size, obj_size,
rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr); r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr);
if (r) { if (r) {
DRM_ERROR("failed to map blit object %d\n", r); DRM_ERROR("failed to map blit object %d\n", r);
return r; return r;
} }
if (rdev->family >= CHIP_RV770) if (rdev->family >= CHIP_RV770)
memcpy_toio(ptr + rdev->r600_blit.state_offset, memcpy_toio(ptr + rdev->r600_blit.state_offset,
r7xx_default_state, rdev->r600_blit.state_len * 4); r7xx_default_state, rdev->r600_blit.state_len * 4);
...@@ -500,19 +501,26 @@ int r600_blit_init(struct radeon_device *rdev) ...@@ -500,19 +501,26 @@ int r600_blit_init(struct radeon_device *rdev)
if (num_packet2s) if (num_packet2s)
memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
packet2s, num_packet2s * 4); packet2s, num_packet2s * 4);
memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
radeon_bo_kunmap(rdev->r600_blit.shader_obj);
radeon_object_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj);
return 0; return 0;
} }
void r600_blit_fini(struct radeon_device *rdev) void r600_blit_fini(struct radeon_device *rdev)
{ {
radeon_object_unpin(rdev->r600_blit.shader_obj); int r;
radeon_object_unref(&rdev->r600_blit.shader_obj);
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
if (unlikely(r != 0)) {
dev_err(rdev->dev, "(%d) can't finish r600 blit\n", r);
goto out_unref;
}
radeon_bo_unpin(rdev->r600_blit.shader_obj);
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
out_unref:
radeon_bo_unref(&rdev->r600_blit.shader_obj);
} }
int r600_vb_ib_get(struct radeon_device *rdev) int r600_vb_ib_get(struct radeon_device *rdev)
...@@ -569,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) ...@@ -569,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
ring_size = num_loops * dwords_per_loop; ring_size = num_loops * dwords_per_loop;
/* set default + shaders */ /* set default + shaders */
ring_size += 40; /* shaders + def state */ ring_size += 40; /* shaders + def state */
ring_size += 3; /* fence emit for VB IB */ ring_size += 5; /* fence emit for VB IB */
ring_size += 5; /* done copy */ ring_size += 5; /* done copy */
ring_size += 3; /* fence emit for done copy */ ring_size += 5; /* fence emit for done copy */
r = radeon_ring_lock(rdev, ring_size); r = radeon_ring_lock(rdev, ring_size);
WARN_ON(r); WARN_ON(r);
......
This diff is collapsed.
This diff is collapsed.
...@@ -76,6 +76,7 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg); ...@@ -76,6 +76,7 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
void r100_bandwidth_update(struct radeon_device *rdev); void r100_bandwidth_update(struct radeon_device *rdev);
void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int r100_ring_test(struct radeon_device *rdev); int r100_ring_test(struct radeon_device *rdev);
void r100_hdp_flush(struct radeon_device *rdev);
static struct radeon_asic r100_asic = { static struct radeon_asic r100_asic = {
.init = &r100_init, .init = &r100_init,
...@@ -107,6 +108,7 @@ static struct radeon_asic r100_asic = { ...@@ -107,6 +108,7 @@ static struct radeon_asic r100_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update, .bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -162,6 +164,7 @@ static struct radeon_asic r300_asic = { ...@@ -162,6 +164,7 @@ static struct radeon_asic r300_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update, .bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
/* /*
...@@ -201,6 +204,7 @@ static struct radeon_asic r420_asic = { ...@@ -201,6 +204,7 @@ static struct radeon_asic r420_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update, .bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -245,6 +249,7 @@ static struct radeon_asic rs400_asic = { ...@@ -245,6 +249,7 @@ static struct radeon_asic rs400_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &r100_bandwidth_update, .bandwidth_update = &r100_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -291,6 +296,7 @@ static struct radeon_asic rs600_asic = { ...@@ -291,6 +296,7 @@ static struct radeon_asic rs600_asic = {
.set_pcie_lanes = NULL, .set_pcie_lanes = NULL,
.set_clock_gating = &radeon_atom_set_clock_gating, .set_clock_gating = &radeon_atom_set_clock_gating,
.bandwidth_update = &rs600_bandwidth_update, .bandwidth_update = &rs600_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -334,6 +340,7 @@ static struct radeon_asic rs690_asic = { ...@@ -334,6 +340,7 @@ static struct radeon_asic rs690_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rs690_bandwidth_update, .bandwidth_update = &rs690_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -381,6 +388,7 @@ static struct radeon_asic rv515_asic = { ...@@ -381,6 +388,7 @@ static struct radeon_asic rv515_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update, .bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
...@@ -419,6 +427,7 @@ static struct radeon_asic r520_asic = { ...@@ -419,6 +427,7 @@ static struct radeon_asic r520_asic = {
.set_surface_reg = r100_set_surface_reg, .set_surface_reg = r100_set_surface_reg,
.clear_surface_reg = r100_clear_surface_reg, .clear_surface_reg = r100_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update, .bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r100_hdp_flush,
}; };
/* /*
...@@ -455,6 +464,7 @@ int r600_ring_test(struct radeon_device *rdev); ...@@ -455,6 +464,7 @@ int r600_ring_test(struct radeon_device *rdev);
int r600_copy_blit(struct radeon_device *rdev, int r600_copy_blit(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset, uint64_t src_offset, uint64_t dst_offset,
unsigned num_pages, struct radeon_fence *fence); unsigned num_pages, struct radeon_fence *fence);
void r600_hdp_flush(struct radeon_device *rdev);
static struct radeon_asic r600_asic = { static struct radeon_asic r600_asic = {
.init = &r600_init, .init = &r600_init,
...@@ -470,6 +480,7 @@ static struct radeon_asic r600_asic = { ...@@ -470,6 +480,7 @@ static struct radeon_asic r600_asic = {
.ring_ib_execute = &r600_ring_ib_execute, .ring_ib_execute = &r600_ring_ib_execute,
.irq_set = &r600_irq_set, .irq_set = &r600_irq_set,
.irq_process = &r600_irq_process, .irq_process = &r600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
.fence_ring_emit = &r600_fence_ring_emit, .fence_ring_emit = &r600_fence_ring_emit,
.cs_parse = &r600_cs_parse, .cs_parse = &r600_cs_parse,
.copy_blit = &r600_copy_blit, .copy_blit = &r600_copy_blit,
...@@ -484,6 +495,7 @@ static struct radeon_asic r600_asic = { ...@@ -484,6 +495,7 @@ static struct radeon_asic r600_asic = {
.set_surface_reg = r600_set_surface_reg, .set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg, .clear_surface_reg = r600_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update, .bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r600_hdp_flush,
}; };
/* /*
...@@ -509,6 +521,7 @@ static struct radeon_asic rv770_asic = { ...@@ -509,6 +521,7 @@ static struct radeon_asic rv770_asic = {
.ring_ib_execute = &r600_ring_ib_execute, .ring_ib_execute = &r600_ring_ib_execute,
.irq_set = &r600_irq_set, .irq_set = &r600_irq_set,
.irq_process = &r600_irq_process, .irq_process = &r600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
.fence_ring_emit = &r600_fence_ring_emit, .fence_ring_emit = &r600_fence_ring_emit,
.cs_parse = &r600_cs_parse, .cs_parse = &r600_cs_parse,
.copy_blit = &r600_copy_blit, .copy_blit = &r600_copy_blit,
...@@ -523,6 +536,7 @@ static struct radeon_asic rv770_asic = { ...@@ -523,6 +536,7 @@ static struct radeon_asic rv770_asic = {
.set_surface_reg = r600_set_surface_reg, .set_surface_reg = r600_set_surface_reg,
.clear_surface_reg = r600_clear_surface_reg, .clear_surface_reg = r600_clear_surface_reg,
.bandwidth_update = &rv515_bandwidth_update, .bandwidth_update = &rv515_bandwidth_update,
.hdp_flush = &r600_hdp_flush,
}; };
#endif #endif
...@@ -82,18 +82,18 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device ...@@ -82,18 +82,18 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device
i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; i2c.en_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; i2c.en_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; i2c.y_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; i2c.y_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
i2c.put_clk_mask = (1 << gpio.ucClkEnShift); i2c.en_clk_mask = (1 << gpio.ucClkEnShift);
i2c.put_data_mask = (1 << gpio.ucDataEnShift); i2c.en_data_mask = (1 << gpio.ucDataEnShift);
i2c.get_clk_mask = (1 << gpio.ucClkY_Shift); i2c.y_clk_mask = (1 << gpio.ucClkY_Shift);
i2c.get_data_mask = (1 << gpio.ucDataY_Shift); i2c.y_data_mask = (1 << gpio.ucDataY_Shift);
i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
i2c.a_data_mask = (1 << gpio.ucDataA_Shift); i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
i2c.valid = true; i2c.valid = true;
...@@ -135,6 +135,23 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, ...@@ -135,6 +135,23 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
} }
} }
/* HIS X1300 is DVI+VGA, not DVI+DVI */
if ((dev->pdev->device == 0x7146) &&
(dev->pdev->subsystem_vendor == 0x17af) &&
(dev->pdev->subsystem_device == 0x2058)) {
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
return false;
}
/* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
if ((dev->pdev->device == 0x7142) &&
(dev->pdev->subsystem_vendor == 0x1458) &&
(dev->pdev->subsystem_device == 0x2134)) {
if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
return false;
}
/* Funky macbooks */ /* Funky macbooks */
if ((dev->pdev->device == 0x71C5) && if ((dev->pdev->device == 0x71C5) &&
(dev->pdev->subsystem_vendor == 0x106b) && (dev->pdev->subsystem_vendor == 0x106b) &&
...@@ -172,6 +189,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, ...@@ -172,6 +189,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
} }
} }
/* Acer laptop reports DVI-D as DVI-I */
if ((dev->pdev->device == 0x95c4) &&
(dev->pdev->subsystem_vendor == 0x1025) &&
(dev->pdev->subsystem_device == 0x013c)) {
if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
(supported_device == ATOM_DEVICE_DFP1_SUPPORT))
*connector_type = DRM_MODE_CONNECTOR_DVID;
}
return true; return true;
} }
...@@ -901,7 +927,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct ...@@ -901,7 +927,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_mode_info *mode_info = &rdev->mode_info; struct radeon_mode_info *mode_info = &rdev->mode_info;
int index = GetIndexIntoMasterTable(DATA, LVDS_Info); int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
uint16_t data_offset; uint16_t data_offset, misc;
union lvds_info *lvds_info; union lvds_info *lvds_info;
uint8_t frev, crev; uint8_t frev, crev;
struct radeon_encoder_atom_dig *lvds = NULL; struct radeon_encoder_atom_dig *lvds = NULL;
...@@ -940,6 +966,19 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct ...@@ -940,6 +966,19 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
lvds->panel_pwr_delay = lvds->panel_pwr_delay =
le16_to_cpu(lvds_info->info.usOffDelayInMs); le16_to_cpu(lvds_info->info.usOffDelayInMs);
lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
if (misc & ATOM_VSYNC_POLARITY)
lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
if (misc & ATOM_HSYNC_POLARITY)
lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
if (misc & ATOM_COMPOSITESYNC)
lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
if (misc & ATOM_INTERLACE)
lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
if (misc & ATOM_DOUBLE_CLOCK_MODE)
lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
/* set crtc values */ /* set crtc values */
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
unsigned sdomain, unsigned ddomain) unsigned sdomain, unsigned ddomain)
{ {
struct radeon_object *dobj = NULL; struct radeon_bo *dobj = NULL;
struct radeon_object *sobj = NULL; struct radeon_bo *sobj = NULL;
struct radeon_fence *fence = NULL; struct radeon_fence *fence = NULL;
uint64_t saddr, daddr; uint64_t saddr, daddr;
unsigned long start_jiffies; unsigned long start_jiffies;
...@@ -41,19 +41,27 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, ...@@ -41,19 +41,27 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
size = bsize; size = bsize;
n = 1024; n = 1024;
r = radeon_object_create(rdev, NULL, size, true, sdomain, false, &sobj); r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_pin(sobj, sdomain, &saddr); r = radeon_bo_reserve(sobj, false);
if (unlikely(r != 0))
goto out_cleanup;
r = radeon_bo_pin(sobj, sdomain, &saddr);
radeon_bo_unreserve(sobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_create(rdev, NULL, size, true, ddomain, false, &dobj); r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_pin(dobj, ddomain, &daddr); r = radeon_bo_reserve(dobj, false);
if (unlikely(r != 0))
goto out_cleanup;
r = radeon_bo_pin(dobj, ddomain, &daddr);
radeon_bo_unreserve(dobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
...@@ -109,12 +117,20 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, ...@@ -109,12 +117,20 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
} }
out_cleanup: out_cleanup:
if (sobj) { if (sobj) {
radeon_object_unpin(sobj); r = radeon_bo_reserve(sobj, false);
radeon_object_unref(&sobj); if (likely(r == 0)) {
radeon_bo_unpin(sobj);
radeon_bo_unreserve(sobj);
}
radeon_bo_unref(&sobj);
} }
if (dobj) { if (dobj) {
radeon_object_unpin(dobj); r = radeon_bo_reserve(dobj, false);
radeon_object_unref(&dobj); if (likely(r == 0)) {
radeon_bo_unpin(dobj);
radeon_bo_unreserve(dobj);
}
radeon_bo_unref(&dobj);
} }
if (fence) { if (fence) {
radeon_fence_unref(&fence); radeon_fence_unref(&fence);
......
...@@ -44,6 +44,10 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) ...@@ -44,6 +44,10 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
ref_div = ref_div =
RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
if (ref_div == 0)
return 0;
sclk = fb_div / ref_div; sclk = fb_div / ref_div;
post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
...@@ -70,6 +74,10 @@ static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) ...@@ -70,6 +74,10 @@ static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
ref_div = ref_div =
RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
if (ref_div == 0)
return 0;
mclk = fb_div / ref_div; mclk = fb_div / ref_div;
post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
...@@ -98,8 +106,19 @@ void radeon_get_clock_info(struct drm_device *dev) ...@@ -98,8 +106,19 @@ void radeon_get_clock_info(struct drm_device *dev)
ret = radeon_combios_get_clock_info(dev); ret = radeon_combios_get_clock_info(dev);
if (ret) { if (ret) {
if (p1pll->reference_div < 2) if (p1pll->reference_div < 2) {
p1pll->reference_div = 12; if (!ASIC_IS_AVIVO(rdev)) {
u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
if (ASIC_IS_R300(rdev))
p1pll->reference_div =
(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
else
p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
if (p1pll->reference_div < 2)
p1pll->reference_div = 12;
} else
p1pll->reference_div = 12;
}
if (p2pll->reference_div < 2) if (p2pll->reference_div < 2)
p2pll->reference_div = 12; p2pll->reference_div = 12;
if (rdev->family < CHIP_RS600) { if (rdev->family < CHIP_RS600) {
......
This diff is collapsed.
...@@ -445,10 +445,10 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec ...@@ -445,10 +445,10 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec
ret = connector_status_connected; ret = connector_status_connected;
else { else {
if (radeon_connector->ddc_bus) { if (radeon_connector->ddc_bus) {
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->edid = drm_get_edid(&radeon_connector->base,
&radeon_connector->ddc_bus->adapter); &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (radeon_connector->edid) if (radeon_connector->edid)
ret = connector_status_connected; ret = connector_status_connected;
} }
...@@ -553,17 +553,17 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect ...@@ -553,17 +553,17 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
if (!encoder) if (!encoder)
ret = connector_status_disconnected; ret = connector_status_disconnected;
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
dret = radeon_ddc_probe(radeon_connector); dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (dret) { if (dret) {
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
radeon_connector->edid = NULL; radeon_connector->edid = NULL;
} }
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
...@@ -708,17 +708,17 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect ...@@ -708,17 +708,17 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
enum drm_connector_status ret = connector_status_disconnected; enum drm_connector_status ret = connector_status_disconnected;
bool dret; bool dret;
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
dret = radeon_ddc_probe(radeon_connector); dret = radeon_ddc_probe(radeon_connector);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (dret) { if (dret) {
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
radeon_connector->edid = NULL; radeon_connector->edid = NULL;
} }
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
...@@ -735,6 +735,39 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect ...@@ -735,6 +735,39 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
ret = connector_status_disconnected; ret = connector_status_disconnected;
} else } else
ret = connector_status_connected; ret = connector_status_connected;
/* multiple connectors on the same encoder with the same ddc line
* This tends to be HDMI and DVI on the same encoder with the
* same ddc line. If the edid says HDMI, consider the HDMI port
* connected and the DVI port disconnected. If the edid doesn't
* say HDMI, vice versa.
*/
if (radeon_connector->shared_ddc && connector_status_connected) {
struct drm_device *dev = connector->dev;
struct drm_connector *list_connector;
struct radeon_connector *list_radeon_connector;
list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
if (connector == list_connector)
continue;
list_radeon_connector = to_radeon_connector(list_connector);
if (radeon_connector->devices == list_radeon_connector->devices) {
if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
ret = connector_status_disconnected;
}
} else {
if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
(connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
ret = connector_status_disconnected;
}
}
}
}
}
} }
} }
...@@ -1020,6 +1053,9 @@ radeon_add_atom_connector(struct drm_device *dev, ...@@ -1020,6 +1053,9 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_connector_attach_property(&radeon_connector->base, drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property, rdev->mode_info.load_detect_property,
1); 1);
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.tv_std_property,
1);
} }
break; break;
case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_LVDS:
...@@ -1160,6 +1196,9 @@ radeon_add_legacy_connector(struct drm_device *dev, ...@@ -1160,6 +1196,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
drm_connector_attach_property(&radeon_connector->base, drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property, rdev->mode_info.load_detect_property,
1); 1);
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.tv_std_property,
1);
} }
break; break;
case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_LVDS:
......
...@@ -76,17 +76,17 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) ...@@ -76,17 +76,17 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
} }
p->relocs_ptr[i] = &p->relocs[i]; p->relocs_ptr[i] = &p->relocs[i];
p->relocs[i].robj = p->relocs[i].gobj->driver_private; p->relocs[i].robj = p->relocs[i].gobj->driver_private;
p->relocs[i].lobj.robj = p->relocs[i].robj; p->relocs[i].lobj.bo = p->relocs[i].robj;
p->relocs[i].lobj.rdomain = r->read_domains; p->relocs[i].lobj.rdomain = r->read_domains;
p->relocs[i].lobj.wdomain = r->write_domain; p->relocs[i].lobj.wdomain = r->write_domain;
p->relocs[i].handle = r->handle; p->relocs[i].handle = r->handle;
p->relocs[i].flags = r->flags; p->relocs[i].flags = r->flags;
INIT_LIST_HEAD(&p->relocs[i].lobj.list); INIT_LIST_HEAD(&p->relocs[i].lobj.list);
radeon_object_list_add_object(&p->relocs[i].lobj, radeon_bo_list_add_object(&p->relocs[i].lobj,
&p->validated); &p->validated);
} }
} }
return radeon_object_list_validate(&p->validated, p->ib->fence); return radeon_bo_list_validate(&p->validated, p->ib->fence);
} }
int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
...@@ -190,9 +190,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) ...@@ -190,9 +190,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
unsigned i; unsigned i;
if (error) { if (error) {
radeon_object_list_unvalidate(&parser->validated); radeon_bo_list_unvalidate(&parser->validated,
parser->ib->fence);
} else { } else {
radeon_object_list_clean(&parser->validated); radeon_bo_list_unreserve(&parser->validated);
} }
for (i = 0; i < parser->nrelocs; i++) { for (i = 0; i < parser->nrelocs; i++) {
if (parser->relocs[i].gobj) { if (parser->relocs[i].gobj) {
......
...@@ -208,6 +208,24 @@ bool radeon_card_posted(struct radeon_device *rdev) ...@@ -208,6 +208,24 @@ bool radeon_card_posted(struct radeon_device *rdev)
} }
bool radeon_boot_test_post_card(struct radeon_device *rdev)
{
if (radeon_card_posted(rdev))
return true;
if (rdev->bios) {
DRM_INFO("GPU not posted. posting now...\n");
if (rdev->is_atom_bios)
atom_asic_init(rdev->mode_info.atom_context);
else
radeon_combios_asic_init(rdev->ddev);
return true;
} else {
dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
return false;
}
}
int radeon_dummy_page_init(struct radeon_device *rdev) int radeon_dummy_page_init(struct radeon_device *rdev)
{ {
rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
...@@ -544,6 +562,9 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -544,6 +562,9 @@ int radeon_device_init(struct radeon_device *rdev,
mutex_init(&rdev->cs_mutex); mutex_init(&rdev->cs_mutex);
mutex_init(&rdev->ib_pool.mutex); mutex_init(&rdev->ib_pool.mutex);
mutex_init(&rdev->cp.mutex); mutex_init(&rdev->cp.mutex);
if (rdev->family >= CHIP_R600)
spin_lock_init(&rdev->ih.lock);
mutex_init(&rdev->gem.mutex);
rwlock_init(&rdev->fence_drv.lock); rwlock_init(&rdev->fence_drv.lock);
INIT_LIST_HEAD(&rdev->gem.objects); INIT_LIST_HEAD(&rdev->gem.objects);
...@@ -553,7 +574,7 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -553,7 +574,7 @@ int radeon_device_init(struct radeon_device *rdev,
return r; return r;
} }
if (radeon_agpmode == -1) { if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
radeon_agp_disable(rdev); radeon_agp_disable(rdev);
} }
...@@ -633,6 +654,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) ...@@ -633,6 +654,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
{ {
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct drm_crtc *crtc; struct drm_crtc *crtc;
int r;
if (dev == NULL || rdev == NULL) { if (dev == NULL || rdev == NULL) {
return -ENODEV; return -ENODEV;
...@@ -643,18 +665,22 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) ...@@ -643,18 +665,22 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
/* unpin the front buffers */ /* unpin the front buffers */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
struct radeon_object *robj; struct radeon_bo *robj;
if (rfb == NULL || rfb->obj == NULL) { if (rfb == NULL || rfb->obj == NULL) {
continue; continue;
} }
robj = rfb->obj->driver_private; robj = rfb->obj->driver_private;
if (robj != rdev->fbdev_robj) { if (robj != rdev->fbdev_rbo) {
radeon_object_unpin(robj); r = radeon_bo_reserve(robj, false);
if (unlikely(r == 0)) {
radeon_bo_unpin(robj);
radeon_bo_unreserve(robj);
}
} }
} }
/* evict vram memory */ /* evict vram memory */
radeon_object_evict_vram(rdev); radeon_bo_evict_vram(rdev);
/* wait for gpu to finish processing current batch */ /* wait for gpu to finish processing current batch */
radeon_fence_wait_last(rdev); radeon_fence_wait_last(rdev);
...@@ -662,7 +688,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) ...@@ -662,7 +688,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
radeon_suspend(rdev); radeon_suspend(rdev);
/* evict remaining vram memory */ /* evict remaining vram memory */
radeon_object_evict_vram(rdev); radeon_bo_evict_vram(rdev);
pci_save_state(dev->pdev); pci_save_state(dev->pdev);
if (state.event == PM_EVENT_SUSPEND) { if (state.event == PM_EVENT_SUSPEND) {
......
...@@ -270,10 +270,10 @@ static void radeon_print_display_setup(struct drm_device *dev) ...@@ -270,10 +270,10 @@ static void radeon_print_display_setup(struct drm_device *dev)
radeon_connector->ddc_bus->rec.mask_data_reg, radeon_connector->ddc_bus->rec.mask_data_reg,
radeon_connector->ddc_bus->rec.a_clk_reg, radeon_connector->ddc_bus->rec.a_clk_reg,
radeon_connector->ddc_bus->rec.a_data_reg, radeon_connector->ddc_bus->rec.a_data_reg,
radeon_connector->ddc_bus->rec.put_clk_reg, radeon_connector->ddc_bus->rec.en_clk_reg,
radeon_connector->ddc_bus->rec.put_data_reg, radeon_connector->ddc_bus->rec.en_data_reg,
radeon_connector->ddc_bus->rec.get_clk_reg, radeon_connector->ddc_bus->rec.y_clk_reg,
radeon_connector->ddc_bus->rec.get_data_reg); radeon_connector->ddc_bus->rec.y_data_reg);
DRM_INFO(" Encoders:\n"); DRM_INFO(" Encoders:\n");
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
radeon_encoder = to_radeon_encoder(encoder); radeon_encoder = to_radeon_encoder(encoder);
...@@ -324,6 +324,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) ...@@ -324,6 +324,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
ret = radeon_get_legacy_connector_info_from_table(dev); ret = radeon_get_legacy_connector_info_from_table(dev);
} }
if (ret) { if (ret) {
radeon_setup_encoder_clones(dev);
radeon_print_display_setup(dev); radeon_print_display_setup(dev);
list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
radeon_ddc_dump(drm_connector); radeon_ddc_dump(drm_connector);
...@@ -339,9 +340,9 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) ...@@ -339,9 +340,9 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
if (!radeon_connector->ddc_bus) if (!radeon_connector->ddc_bus)
return -1; return -1;
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
} }
if (radeon_connector->edid) { if (radeon_connector->edid) {
...@@ -361,9 +362,9 @@ static int radeon_ddc_dump(struct drm_connector *connector) ...@@ -361,9 +362,9 @@ static int radeon_ddc_dump(struct drm_connector *connector)
if (!radeon_connector->ddc_bus) if (!radeon_connector->ddc_bus)
return -1; return -1;
radeon_i2c_do_lock(radeon_connector, 1); radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
if (edid) { if (edid) {
kfree(edid); kfree(edid);
} }
...@@ -750,9 +751,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -750,9 +751,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
if (encoder->crtc != crtc) if (encoder->crtc != crtc)
continue; continue;
if (first) { if (first) {
radeon_crtc->rmx_type = radeon_encoder->rmx_type; /* set scaling */
if (radeon_encoder->rmx_type == RMX_OFF)
radeon_crtc->rmx_type = RMX_OFF;
else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
mode->vdisplay < radeon_encoder->native_mode.vdisplay)
radeon_crtc->rmx_type = radeon_encoder->rmx_type;
else
radeon_crtc->rmx_type = RMX_OFF;
/* copy native mode */
memcpy(&radeon_crtc->native_mode, memcpy(&radeon_crtc->native_mode,
&radeon_encoder->native_mode, &radeon_encoder->native_mode,
sizeof(struct drm_display_mode)); sizeof(struct drm_display_mode));
first = false; first = false;
} else { } else {
......
...@@ -1104,7 +1104,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); ...@@ -1104,7 +1104,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
# define R600_IT_WAIT_REG_MEM 0x00003C00 # define R600_IT_WAIT_REG_MEM 0x00003C00
# define R600_IT_MEM_WRITE 0x00003D00 # define R600_IT_MEM_WRITE 0x00003D00
# define R600_IT_INDIRECT_BUFFER 0x00003200 # define R600_IT_INDIRECT_BUFFER 0x00003200
# define R600_IT_CP_INTERRUPT 0x00004000
# define R600_IT_SURFACE_SYNC 0x00004300 # define R600_IT_SURFACE_SYNC 0x00004300
# define R600_CB0_DEST_BASE_ENA (1 << 6) # define R600_CB0_DEST_BASE_ENA (1 << 6)
# define R600_TC_ACTION_ENA (1 << 23) # define R600_TC_ACTION_ENA (1 << 23)
......
...@@ -35,6 +35,51 @@ extern int atom_debug; ...@@ -35,6 +35,51 @@ extern int atom_debug;
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
struct drm_display_mode *mode); struct drm_display_mode *mode);
static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *clone_encoder;
uint32_t index_mask = 0;
int count;
/* DIG routing gets problematic */
if (rdev->family >= CHIP_R600)
return index_mask;
/* LVDS/TV are too wacky */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
return index_mask;
/* DVO requires 2x ppll clocks depending on tmds chip */
if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
return index_mask;
count = -1;
list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
count++;
if (clone_encoder == encoder)
continue;
if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
continue;
if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
continue;
else
index_mask |= (1 << count);
}
return index_mask;
}
void radeon_setup_encoder_clones(struct drm_device *dev)
{
struct drm_encoder *encoder;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder->possible_clones = radeon_encoder_clones(encoder);
}
}
uint32_t uint32_t
radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
{ {
...@@ -163,29 +208,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) ...@@ -163,29 +208,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL; return NULL;
} }
/* used for both atom and legacy */
void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
if (mode->hdisplay < native_mode->hdisplay ||
mode->vdisplay < native_mode->vdisplay) {
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
if (!ASIC_IS_AVIVO(rdev)) {
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
}
adjusted_mode->base.id = mode_id;
}
}
static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
...@@ -198,14 +220,24 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, ...@@ -198,14 +220,24 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
radeon_encoder_set_active_device(encoder); radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0); drm_mode_set_crtcinfo(adjusted_mode, 0);
if (radeon_encoder->rmx_type != RMX_OFF)
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
/* hw bug */ /* hw bug */
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
/* get the native mode for LVDS */
if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
if (!ASIC_IS_AVIVO(rdev)) {
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
}
adjusted_mode->base.id = mode_id;
}
/* get the native mode for TV */
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
if (tv_dac) { if (tv_dac) {
...@@ -392,7 +424,7 @@ union lvds_encoder_control { ...@@ -392,7 +424,7 @@ union lvds_encoder_control {
LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
}; };
static void void
atombios_digital_setup(struct drm_encoder *encoder, int action) atombios_digital_setup(struct drm_encoder *encoder, int action)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -918,12 +950,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -918,12 +950,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
if (is_dig) { if (is_dig) {
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT);
break; break;
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT);
break; break;
} }
} else { } else {
...@@ -1354,7 +1386,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su ...@@ -1354,7 +1386,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
encoder->possible_crtcs = 0x1; encoder->possible_crtcs = 0x1;
else else
encoder->possible_crtcs = 0x3; encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
radeon_encoder->enc_priv = NULL; radeon_encoder->enc_priv = NULL;
......
...@@ -140,7 +140,7 @@ int radeonfb_create(struct drm_device *dev, ...@@ -140,7 +140,7 @@ int radeonfb_create(struct drm_device *dev,
struct radeon_framebuffer *rfb; struct radeon_framebuffer *rfb;
struct drm_mode_fb_cmd mode_cmd; struct drm_mode_fb_cmd mode_cmd;
struct drm_gem_object *gobj = NULL; struct drm_gem_object *gobj = NULL;
struct radeon_object *robj = NULL; struct radeon_bo *rbo = NULL;
struct device *device = &rdev->pdev->dev; struct device *device = &rdev->pdev->dev;
int size, aligned_size, ret; int size, aligned_size, ret;
u64 fb_gpuaddr; u64 fb_gpuaddr;
...@@ -168,14 +168,14 @@ int radeonfb_create(struct drm_device *dev, ...@@ -168,14 +168,14 @@ int radeonfb_create(struct drm_device *dev,
ret = radeon_gem_object_create(rdev, aligned_size, 0, ret = radeon_gem_object_create(rdev, aligned_size, 0,
RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_VRAM,
false, ttm_bo_type_kernel, false, ttm_bo_type_kernel,
false, &gobj); &gobj);
if (ret) { if (ret) {
printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
surface_width, surface_height); surface_width, surface_height);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
robj = gobj->driver_private; rbo = gobj->driver_private;
if (fb_tiled) if (fb_tiled)
tiling_flags = RADEON_TILING_MACRO; tiling_flags = RADEON_TILING_MACRO;
...@@ -192,8 +192,13 @@ int radeonfb_create(struct drm_device *dev, ...@@ -192,8 +192,13 @@ int radeonfb_create(struct drm_device *dev,
} }
#endif #endif
if (tiling_flags) if (tiling_flags) {
radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch); ret = radeon_bo_set_tiling_flags(rbo,
tiling_flags | RADEON_TILING_SURFACE,
mode_cmd.pitch);
if (ret)
dev_err(rdev->dev, "FB failed to set tiling flags\n");
}
mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->ddev->struct_mutex);
fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
if (fb == NULL) { if (fb == NULL) {
...@@ -201,10 +206,19 @@ int radeonfb_create(struct drm_device *dev, ...@@ -201,10 +206,19 @@ int radeonfb_create(struct drm_device *dev,
ret = -ENOMEM; ret = -ENOMEM;
goto out_unref; goto out_unref;
} }
ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); ret = radeon_bo_reserve(rbo, false);
if (unlikely(ret != 0))
goto out_unref;
ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
if (ret) {
radeon_bo_unreserve(rbo);
goto out_unref;
}
if (fb_tiled)
radeon_bo_check_tiling(rbo, 0, 0);
ret = radeon_bo_kmap(rbo, &fbptr);
radeon_bo_unreserve(rbo);
if (ret) { if (ret) {
printk(KERN_ERR "failed to pin framebuffer\n");
ret = -ENOMEM;
goto out_unref; goto out_unref;
} }
...@@ -213,7 +227,7 @@ int radeonfb_create(struct drm_device *dev, ...@@ -213,7 +227,7 @@ int radeonfb_create(struct drm_device *dev,
*fb_p = fb; *fb_p = fb;
rfb = to_radeon_framebuffer(fb); rfb = to_radeon_framebuffer(fb);
rdev->fbdev_rfb = rfb; rdev->fbdev_rfb = rfb;
rdev->fbdev_robj = robj; rdev->fbdev_rbo = rbo;
info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
if (info == NULL) { if (info == NULL) {
...@@ -234,15 +248,7 @@ int radeonfb_create(struct drm_device *dev, ...@@ -234,15 +248,7 @@ int radeonfb_create(struct drm_device *dev,
if (ret) if (ret)
goto out_unref; goto out_unref;
if (fb_tiled) memset_io(fbptr, 0xff, aligned_size);
radeon_object_check_tiling(robj, 0, 0);
ret = radeon_object_kmap(robj, &fbptr);
if (ret) {
goto out_unref;
}
memset_io(fbptr, 0, aligned_size);
strcpy(info->fix.id, "radeondrmfb"); strcpy(info->fix.id, "radeondrmfb");
...@@ -288,8 +294,12 @@ int radeonfb_create(struct drm_device *dev, ...@@ -288,8 +294,12 @@ int radeonfb_create(struct drm_device *dev,
return 0; return 0;
out_unref: out_unref:
if (robj) { if (rbo) {
radeon_object_kunmap(robj); ret = radeon_bo_reserve(rbo, false);
if (likely(ret == 0)) {
radeon_bo_kunmap(rbo);
radeon_bo_unreserve(rbo);
}
} }
if (fb && ret) { if (fb && ret) {
list_del(&fb->filp_head); list_del(&fb->filp_head);
...@@ -321,14 +331,22 @@ int radeon_parse_options(char *options) ...@@ -321,14 +331,22 @@ int radeon_parse_options(char *options)
int radeonfb_probe(struct drm_device *dev) int radeonfb_probe(struct drm_device *dev)
{ {
return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create); struct radeon_device *rdev = dev->dev_private;
int bpp_sel = 32;
/* select 8 bpp console on RN50 or 16MB cards */
if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
bpp_sel = 8;
return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create);
} }
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
{ {
struct fb_info *info; struct fb_info *info;
struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb); struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
struct radeon_object *robj; struct radeon_bo *rbo;
int r;
if (!fb) { if (!fb) {
return -EINVAL; return -EINVAL;
...@@ -336,10 +354,14 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) ...@@ -336,10 +354,14 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
info = fb->fbdev; info = fb->fbdev;
if (info) { if (info) {
struct radeon_fb_device *rfbdev = info->par; struct radeon_fb_device *rfbdev = info->par;
robj = rfb->obj->driver_private; rbo = rfb->obj->driver_private;
unregister_framebuffer(info); unregister_framebuffer(info);
radeon_object_kunmap(robj); r = radeon_bo_reserve(rbo, false);
radeon_object_unpin(robj); if (likely(r == 0)) {
radeon_bo_kunmap(rbo);
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}
drm_fb_helper_free(&rfbdev->helper); drm_fb_helper_free(&rfbdev->helper);
framebuffer_release(info); framebuffer_release(info);
} }
......
...@@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence) ...@@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
return signaled; return signaled;
} }
int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy)
{
struct radeon_device *rdev;
int ret = 0;
rdev = fence->rdev;
__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
while (1) {
if (radeon_fence_signaled(fence))
break;
if (time_after_eq(jiffies, fence->timeout)) {
ret = -EBUSY;
break;
}
if (lazy)
schedule_timeout(1);
if (intr && signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
__set_current_state(TASK_RUNNING);
return ret;
}
int radeon_fence_wait(struct radeon_fence *fence, bool intr) int radeon_fence_wait(struct radeon_fence *fence, bool intr)
{ {
struct radeon_device *rdev; struct radeon_device *rdev;
...@@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) ...@@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
return 0; return 0;
} }
if (rdev->family >= CHIP_R600) {
r = r600_fence_wait(fence, intr, 0);
if (r == -ERESTARTSYS)
return -EBUSY;
return r;
}
retry: retry:
cur_jiffies = jiffies; cur_jiffies = jiffies;
timeout = HZ / 100; timeout = HZ / 100;
...@@ -231,14 +193,18 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) ...@@ -231,14 +193,18 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
} }
if (intr) { if (intr) {
radeon_irq_kms_sw_irq_get(rdev);
r = wait_event_interruptible_timeout(rdev->fence_drv.queue, r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
radeon_fence_signaled(fence), timeout); radeon_fence_signaled(fence), timeout);
radeon_irq_kms_sw_irq_put(rdev);
if (unlikely(r == -ERESTARTSYS)) { if (unlikely(r == -ERESTARTSYS)) {
return -EBUSY; return -EBUSY;
} }
} else { } else {
radeon_irq_kms_sw_irq_get(rdev);
r = wait_event_timeout(rdev->fence_drv.queue, r = wait_event_timeout(rdev->fence_drv.queue,
radeon_fence_signaled(fence), timeout); radeon_fence_signaled(fence), timeout);
radeon_irq_kms_sw_irq_put(rdev);
} }
if (unlikely(!radeon_fence_signaled(fence))) { if (unlikely(!radeon_fence_signaled(fence))) {
if (unlikely(r == 0)) { if (unlikely(r == 0)) {
......
...@@ -78,11 +78,9 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) ...@@ -78,11 +78,9 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
int r; int r;
if (rdev->gart.table.vram.robj == NULL) { if (rdev->gart.table.vram.robj == NULL) {
r = radeon_object_create(rdev, NULL, r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
rdev->gart.table_size, true, RADEON_GEM_DOMAIN_VRAM,
true, &rdev->gart.table.vram.robj);
RADEON_GEM_DOMAIN_VRAM,
false, &rdev->gart.table.vram.robj);
if (r) { if (r) {
return r; return r;
} }
...@@ -95,32 +93,38 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) ...@@ -95,32 +93,38 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev)
uint64_t gpu_addr; uint64_t gpu_addr;
int r; int r;
r = radeon_object_pin(rdev->gart.table.vram.robj, r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
RADEON_GEM_DOMAIN_VRAM, &gpu_addr); if (unlikely(r != 0))
if (r) {
radeon_object_unref(&rdev->gart.table.vram.robj);
return r; return r;
} r = radeon_bo_pin(rdev->gart.table.vram.robj,
r = radeon_object_kmap(rdev->gart.table.vram.robj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
(void **)&rdev->gart.table.vram.ptr);
if (r) { if (r) {
radeon_object_unpin(rdev->gart.table.vram.robj); radeon_bo_unreserve(rdev->gart.table.vram.robj);
radeon_object_unref(&rdev->gart.table.vram.robj);
DRM_ERROR("radeon: failed to map gart vram table.\n");
return r; return r;
} }
r = radeon_bo_kmap(rdev->gart.table.vram.robj,
(void **)&rdev->gart.table.vram.ptr);
if (r)
radeon_bo_unpin(rdev->gart.table.vram.robj);
radeon_bo_unreserve(rdev->gart.table.vram.robj);
rdev->gart.table_addr = gpu_addr; rdev->gart.table_addr = gpu_addr;
return 0; return r;
} }
void radeon_gart_table_vram_free(struct radeon_device *rdev) void radeon_gart_table_vram_free(struct radeon_device *rdev)
{ {
int r;
if (rdev->gart.table.vram.robj == NULL) { if (rdev->gart.table.vram.robj == NULL) {
return; return;
} }
radeon_object_kunmap(rdev->gart.table.vram.robj); r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
radeon_object_unpin(rdev->gart.table.vram.robj); if (likely(r == 0)) {
radeon_object_unref(&rdev->gart.table.vram.robj); radeon_bo_kunmap(rdev->gart.table.vram.robj);
radeon_bo_unpin(rdev->gart.table.vram.robj);
radeon_bo_unreserve(rdev->gart.table.vram.robj);
}
radeon_bo_unref(&rdev->gart.table.vram.robj);
} }
......
...@@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_gem_object *obj) ...@@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_gem_object *obj)
void radeon_gem_object_free(struct drm_gem_object *gobj) void radeon_gem_object_free(struct drm_gem_object *gobj)
{ {
struct radeon_object *robj = gobj->driver_private; struct radeon_bo *robj = gobj->driver_private;
gobj->driver_private = NULL; gobj->driver_private = NULL;
if (robj) { if (robj) {
radeon_object_unref(&robj); radeon_bo_unref(&robj);
} }
} }
int radeon_gem_object_create(struct radeon_device *rdev, int size, int radeon_gem_object_create(struct radeon_device *rdev, int size,
int alignment, int initial_domain, int alignment, int initial_domain,
bool discardable, bool kernel, bool discardable, bool kernel,
bool interruptible, struct drm_gem_object **obj)
struct drm_gem_object **obj)
{ {
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r; int r;
*obj = NULL; *obj = NULL;
...@@ -65,8 +64,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, ...@@ -65,8 +64,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
if (alignment < PAGE_SIZE) { if (alignment < PAGE_SIZE) {
alignment = PAGE_SIZE; alignment = PAGE_SIZE;
} }
r = radeon_object_create(rdev, gobj, size, kernel, initial_domain, r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
interruptible, &robj);
if (r) { if (r) {
DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
size, initial_domain, alignment); size, initial_domain, alignment);
...@@ -83,33 +81,33 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, ...@@ -83,33 +81,33 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
uint64_t *gpu_addr) uint64_t *gpu_addr)
{ {
struct radeon_object *robj = obj->driver_private; struct radeon_bo *robj = obj->driver_private;
uint32_t flags; int r;
switch (pin_domain) { r = radeon_bo_reserve(robj, false);
case RADEON_GEM_DOMAIN_VRAM: if (unlikely(r != 0))
flags = TTM_PL_FLAG_VRAM; return r;
break; r = radeon_bo_pin(robj, pin_domain, gpu_addr);
case RADEON_GEM_DOMAIN_GTT: radeon_bo_unreserve(robj);
flags = TTM_PL_FLAG_TT; return r;
break;
default:
flags = TTM_PL_FLAG_SYSTEM;
break;
}
return radeon_object_pin(robj, flags, gpu_addr);
} }
void radeon_gem_object_unpin(struct drm_gem_object *obj) void radeon_gem_object_unpin(struct drm_gem_object *obj)
{ {
struct radeon_object *robj = obj->driver_private; struct radeon_bo *robj = obj->driver_private;
radeon_object_unpin(robj); int r;
r = radeon_bo_reserve(robj, false);
if (likely(r == 0)) {
radeon_bo_unpin(robj);
radeon_bo_unreserve(robj);
}
} }
int radeon_gem_set_domain(struct drm_gem_object *gobj, int radeon_gem_set_domain(struct drm_gem_object *gobj,
uint32_t rdomain, uint32_t wdomain) uint32_t rdomain, uint32_t wdomain)
{ {
struct radeon_object *robj; struct radeon_bo *robj;
uint32_t domain; uint32_t domain;
int r; int r;
...@@ -127,11 +125,12 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, ...@@ -127,11 +125,12 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj,
} }
if (domain == RADEON_GEM_DOMAIN_CPU) { if (domain == RADEON_GEM_DOMAIN_CPU) {
/* Asking for cpu access wait for object idle */ /* Asking for cpu access wait for object idle */
r = radeon_object_wait(robj); r = radeon_bo_wait(robj, NULL, false);
if (r) { if (r) {
printk(KERN_ERR "Failed to wait for object !\n"); printk(KERN_ERR "Failed to wait for object !\n");
return r; return r;
} }
radeon_hdp_flush(robj->rdev);
} }
return 0; return 0;
} }
...@@ -144,7 +143,7 @@ int radeon_gem_init(struct radeon_device *rdev) ...@@ -144,7 +143,7 @@ int radeon_gem_init(struct radeon_device *rdev)
void radeon_gem_fini(struct radeon_device *rdev) void radeon_gem_fini(struct radeon_device *rdev)
{ {
radeon_object_force_delete(rdev); radeon_bo_force_delete(rdev);
} }
...@@ -158,9 +157,13 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, ...@@ -158,9 +157,13 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
struct drm_radeon_gem_info *args = data; struct drm_radeon_gem_info *args = data;
args->vram_size = rdev->mc.real_vram_size; args->vram_size = rdev->mc.real_vram_size;
/* FIXME: report somethings that makes sense */ args->vram_visible = rdev->mc.real_vram_size;
args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024); if (rdev->stollen_vga_memory)
args->gart_size = rdev->mc.gtt_size; args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
if (rdev->fbdev_rbo)
args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo);
args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
RADEON_IB_POOL_SIZE*64*1024;
return 0; return 0;
} }
...@@ -192,8 +195,8 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, ...@@ -192,8 +195,8 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
/* create a gem object to contain this object in */ /* create a gem object to contain this object in */
args->size = roundup(args->size, PAGE_SIZE); args->size = roundup(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, args->alignment, r = radeon_gem_object_create(rdev, args->size, args->alignment,
args->initial_domain, false, args->initial_domain, false,
false, true, &gobj); false, &gobj);
if (r) { if (r) {
return r; return r;
} }
...@@ -218,7 +221,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, ...@@ -218,7 +221,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
* just validate the BO into a certain domain */ * just validate the BO into a certain domain */
struct drm_radeon_gem_set_domain *args = data; struct drm_radeon_gem_set_domain *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r; int r;
/* for now if someone requests domain CPU - /* for now if someone requests domain CPU -
...@@ -244,19 +247,18 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, ...@@ -244,19 +247,18 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_radeon_gem_mmap *args = data; struct drm_radeon_gem_mmap *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r;
gobj = drm_gem_object_lookup(dev, filp, args->handle); gobj = drm_gem_object_lookup(dev, filp, args->handle);
if (gobj == NULL) { if (gobj == NULL) {
return -EINVAL; return -EINVAL;
} }
robj = gobj->driver_private; robj = gobj->driver_private;
r = radeon_object_mmap(robj, &args->addr_ptr); args->addr_ptr = radeon_bo_mmap_offset(robj);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return r; return 0;
} }
int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
...@@ -264,7 +266,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, ...@@ -264,7 +266,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_radeon_gem_busy *args = data; struct drm_radeon_gem_busy *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r; int r;
uint32_t cur_placement; uint32_t cur_placement;
...@@ -273,7 +275,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, ...@@ -273,7 +275,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
return -EINVAL; return -EINVAL;
} }
robj = gobj->driver_private; robj = gobj->driver_private;
r = radeon_object_busy_domain(robj, &cur_placement); r = radeon_bo_wait(robj, &cur_placement, true);
switch (cur_placement) { switch (cur_placement) {
case TTM_PL_VRAM: case TTM_PL_VRAM:
args->domain = RADEON_GEM_DOMAIN_VRAM; args->domain = RADEON_GEM_DOMAIN_VRAM;
...@@ -297,7 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, ...@@ -297,7 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_radeon_gem_wait_idle *args = data; struct drm_radeon_gem_wait_idle *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r; int r;
gobj = drm_gem_object_lookup(dev, filp, args->handle); gobj = drm_gem_object_lookup(dev, filp, args->handle);
...@@ -305,10 +307,11 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, ...@@ -305,10 +307,11 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
return -EINVAL; return -EINVAL;
} }
robj = gobj->driver_private; robj = gobj->driver_private;
r = radeon_object_wait(robj); r = radeon_bo_wait(robj, NULL, false);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
radeon_hdp_flush(robj->rdev);
return r; return r;
} }
...@@ -317,7 +320,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, ...@@ -317,7 +320,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_radeon_gem_set_tiling *args = data; struct drm_radeon_gem_set_tiling *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *robj;
int r = 0; int r = 0;
DRM_DEBUG("%d \n", args->handle); DRM_DEBUG("%d \n", args->handle);
...@@ -325,7 +328,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, ...@@ -325,7 +328,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
if (gobj == NULL) if (gobj == NULL)
return -EINVAL; return -EINVAL;
robj = gobj->driver_private; robj = gobj->driver_private;
radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch); r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
...@@ -337,16 +340,19 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, ...@@ -337,16 +340,19 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_radeon_gem_get_tiling *args = data; struct drm_radeon_gem_get_tiling *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_object *robj; struct radeon_bo *rbo;
int r = 0; int r = 0;
DRM_DEBUG("\n"); DRM_DEBUG("\n");
gobj = drm_gem_object_lookup(dev, filp, args->handle); gobj = drm_gem_object_lookup(dev, filp, args->handle);
if (gobj == NULL) if (gobj == NULL)
return -EINVAL; return -EINVAL;
robj = gobj->driver_private; rbo = gobj->driver_private;
radeon_object_get_tiling_flags(robj, &args->tiling_flags, r = radeon_bo_reserve(rbo, false);
&args->pitch); if (unlikely(r != 0))
return r;
radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
radeon_bo_unreserve(rbo);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -59,11 +59,11 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) ...@@ -59,11 +59,11 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
} }
void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state) void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
{ {
struct radeon_device *rdev = radeon_connector->base.dev->dev_private; struct radeon_device *rdev = i2c->dev->dev_private;
struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t temp; uint32_t temp;
struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
/* RV410 appears to have a bug where the hw i2c in reset /* RV410 appears to have a bug where the hw i2c in reset
* holds the i2c port in a bad state - switch hw i2c away before * holds the i2c port in a bad state - switch hw i2c away before
...@@ -78,16 +78,16 @@ void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_stat ...@@ -78,16 +78,16 @@ void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_stat
R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
} }
} }
if (lock_state) {
temp = RREG32(rec->a_clk_reg);
temp &= ~(rec->a_clk_mask);
WREG32(rec->a_clk_reg, temp);
temp = RREG32(rec->a_data_reg);
temp &= ~(rec->a_data_mask);
WREG32(rec->a_data_reg, temp);
}
/* clear the output pin values */
temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
WREG32(rec->a_clk_reg, temp);
temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
WREG32(rec->a_data_reg, temp);
/* mask the gpio pins for software use */
temp = RREG32(rec->mask_clk_reg); temp = RREG32(rec->mask_clk_reg);
if (lock_state) if (lock_state)
temp |= rec->mask_clk_mask; temp |= rec->mask_clk_mask;
...@@ -112,8 +112,9 @@ static int get_clock(void *i2c_priv) ...@@ -112,8 +112,9 @@ static int get_clock(void *i2c_priv)
struct radeon_i2c_bus_rec *rec = &i2c->rec; struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val; uint32_t val;
val = RREG32(rec->get_clk_reg); /* read the value off the pin */
val &= rec->get_clk_mask; val = RREG32(rec->y_clk_reg);
val &= rec->y_clk_mask;
return (val != 0); return (val != 0);
} }
...@@ -126,8 +127,10 @@ static int get_data(void *i2c_priv) ...@@ -126,8 +127,10 @@ static int get_data(void *i2c_priv)
struct radeon_i2c_bus_rec *rec = &i2c->rec; struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val; uint32_t val;
val = RREG32(rec->get_data_reg); /* read the value off the pin */
val &= rec->get_data_mask; val = RREG32(rec->y_data_reg);
val &= rec->y_data_mask;
return (val != 0); return (val != 0);
} }
...@@ -138,9 +141,10 @@ static void set_clock(void *i2c_priv, int clock) ...@@ -138,9 +141,10 @@ static void set_clock(void *i2c_priv, int clock)
struct radeon_i2c_bus_rec *rec = &i2c->rec; struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val; uint32_t val;
val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask); /* set pin direction */
val |= clock ? 0 : rec->put_clk_mask; val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
WREG32(rec->put_clk_reg, val); val |= clock ? 0 : rec->en_clk_mask;
WREG32(rec->en_clk_reg, val);
} }
static void set_data(void *i2c_priv, int data) static void set_data(void *i2c_priv, int data)
...@@ -150,14 +154,15 @@ static void set_data(void *i2c_priv, int data) ...@@ -150,14 +154,15 @@ static void set_data(void *i2c_priv, int data)
struct radeon_i2c_bus_rec *rec = &i2c->rec; struct radeon_i2c_bus_rec *rec = &i2c->rec;
uint32_t val; uint32_t val;
val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask); /* set pin direction */
val |= data ? 0 : rec->put_data_mask; val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
WREG32(rec->put_data_reg, val); val |= data ? 0 : rec->en_data_mask;
WREG32(rec->en_data_reg, val);
} }
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec, struct radeon_i2c_bus_rec *rec,
const char *name) const char *name)
{ {
struct radeon_i2c_chan *i2c; struct radeon_i2c_chan *i2c;
int ret; int ret;
...@@ -207,3 +212,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) ...@@ -207,3 +212,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
{ {
return NULL; return NULL;
} }
void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val)
{
u8 out_buf[2];
u8 in_buf[2];
struct i2c_msg msgs[] = {
{
.addr = slave_addr,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = slave_addr,
.flags = I2C_M_RD,
.len = 1,
.buf = in_buf,
}
};
out_buf[0] = addr;
out_buf[1] = 0;
if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
*val = in_buf[0];
DRM_DEBUG("val = 0x%02x\n", *val);
} else {
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
addr, *val);
}
}
void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 val)
{
uint8_t out_buf[2];
struct i2c_msg msg = {
.addr = slave_addr,
.flags = 0,
.len = 2,
.buf = out_buf,
};
out_buf[0] = addr;
out_buf[1] = val;
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
addr, val);
}
...@@ -87,17 +87,25 @@ int radeon_irq_kms_init(struct radeon_device *rdev) ...@@ -87,17 +87,25 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_SINGLE_CRTC) if (rdev->flags & RADEON_SINGLE_CRTC)
num_crtc = 1; num_crtc = 1;
spin_lock_init(&rdev->irq.sw_lock);
r = drm_vblank_init(rdev->ddev, num_crtc); r = drm_vblank_init(rdev->ddev, num_crtc);
if (r) { if (r) {
return r; return r;
} }
/* enable msi */ /* enable msi */
rdev->msi_enabled = 0; rdev->msi_enabled = 0;
if (rdev->family >= CHIP_RV380) { /* MSIs don't seem to work on my rs780;
* not sure about rs880 or other rs780s.
* Needs more investigation.
*/
if ((rdev->family >= CHIP_RV380) &&
(rdev->family != CHIP_RS780) &&
(rdev->family != CHIP_RS880)) {
int ret = pci_enable_msi(rdev->pdev); int ret = pci_enable_msi(rdev->pdev);
if (!ret) if (!ret) {
rdev->msi_enabled = 1; rdev->msi_enabled = 1;
DRM_INFO("radeon: using MSI.\n");
}
} }
drm_irq_install(rdev->ddev); drm_irq_install(rdev->ddev);
rdev->irq.installed = true; rdev->irq.installed = true;
...@@ -114,3 +122,29 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) ...@@ -114,3 +122,29 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
pci_disable_msi(rdev->pdev); pci_disable_msi(rdev->pdev);
} }
} }
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
{
unsigned long irqflags;
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) {
rdev->irq.sw_int = true;
radeon_irq_set(rdev);
}
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
}
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev)
{
unsigned long irqflags;
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0);
if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) {
rdev->irq.sw_int = false;
radeon_irq_set(rdev);
}
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
}
...@@ -30,6 +30,18 @@ ...@@ -30,6 +30,18 @@
#include "radeon.h" #include "radeon.h"
#include "atom.h" #include "atom.h"
static void radeon_overscan_setup(struct drm_crtc *crtc,
struct drm_display_mode *mode)
{
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0);
WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0);
WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0);
}
static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
...@@ -292,8 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -292,8 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
uint32_t mask; uint32_t mask;
if (radeon_crtc->crtc_id) if (radeon_crtc->crtc_id)
mask = (RADEON_CRTC2_EN | mask = (RADEON_CRTC2_DISP_DIS |
RADEON_CRTC2_DISP_DIS |
RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_VSYNC_DIS |
RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_HSYNC_DIS |
RADEON_CRTC2_DISP_REQ_EN_B); RADEON_CRTC2_DISP_REQ_EN_B);
...@@ -305,7 +316,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -305,7 +316,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
if (radeon_crtc->crtc_id) if (radeon_crtc->crtc_id)
WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
else { else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B)); RADEON_CRTC_DISP_REQ_EN_B));
...@@ -319,7 +330,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -319,7 +330,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
if (radeon_crtc->crtc_id) if (radeon_crtc->crtc_id)
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
else { else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B)); RADEON_CRTC_DISP_REQ_EN_B));
...@@ -400,14 +411,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -400,14 +411,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_framebuffer *radeon_fb; struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct radeon_bo *rbo;
uint64_t base; uint64_t base;
uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
uint32_t crtc_pitch, pitch_pixels; uint32_t crtc_pitch, pitch_pixels;
uint32_t tiling_flags; uint32_t tiling_flags;
int format; int format;
uint32_t gen_cntl_reg, gen_cntl_val; uint32_t gen_cntl_reg, gen_cntl_val;
int r;
DRM_DEBUG("\n"); DRM_DEBUG("\n");
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
return 0;
}
radeon_fb = to_radeon_framebuffer(crtc->fb); radeon_fb = to_radeon_framebuffer(crtc->fb);
...@@ -431,10 +449,22 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -431,10 +449,22 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return false; return false;
} }
/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj; obj = radeon_fb->obj;
if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) { rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base);
if (unlikely(r != 0)) {
radeon_bo_unreserve(rbo);
return -EINVAL; return -EINVAL;
} }
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
if (tiling_flags & RADEON_TILING_MICRO)
DRM_ERROR("trying to scanout microtiled buffer\n");
/* if scanout was in GTT this really wouldn't work */ /* if scanout was in GTT this really wouldn't work */
/* crtc offset is from display base addr not FB location */ /* crtc offset is from display base addr not FB location */
radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location; radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
...@@ -449,10 +479,6 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -449,10 +479,6 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
(crtc->fb->bits_per_pixel * 8)); (crtc->fb->bits_per_pixel * 8));
crtc_pitch |= crtc_pitch << 16; crtc_pitch |= crtc_pitch << 16;
radeon_object_get_tiling_flags(obj->driver_private,
&tiling_flags, NULL);
if (tiling_flags & RADEON_TILING_MICRO)
DRM_ERROR("trying to scanout microtiled buffer\n");
if (tiling_flags & RADEON_TILING_MACRO) { if (tiling_flags & RADEON_TILING_MACRO) {
if (ASIC_IS_R300(rdev)) if (ASIC_IS_R300(rdev))
...@@ -530,7 +556,12 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -530,7 +556,12 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
if (old_fb && old_fb != crtc->fb) { if (old_fb && old_fb != crtc->fb) {
radeon_fb = to_radeon_framebuffer(old_fb); radeon_fb = to_radeon_framebuffer(old_fb);
radeon_gem_object_unpin(radeon_fb->obj); rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
} }
/* Bytes per pixel may have changed */ /* Bytes per pixel may have changed */
...@@ -642,12 +673,8 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod ...@@ -642,12 +673,8 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
uint32_t crtc2_gen_cntl; uint32_t crtc2_gen_cntl;
uint32_t disp2_merge_cntl; uint32_t disp2_merge_cntl;
/* check to see if TV DAC is enabled for another crtc and keep it enabled */ /* if TV DAC is enabled for another crtc and keep it enabled */
if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON) crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
else
crtc2_gen_cntl = 0;
crtc2_gen_cntl |= ((format << 8) crtc2_gen_cntl |= ((format << 8)
| RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_VSYNC_DIS
| RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_HSYNC_DIS
...@@ -676,7 +703,8 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod ...@@ -676,7 +703,8 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
uint32_t crtc_ext_cntl; uint32_t crtc_ext_cntl;
uint32_t disp_merge_cntl; uint32_t disp_merge_cntl;
crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000;
crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN
| (format << 8) | (format << 8)
| RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_DISP_REQ_EN_B
| ((mode->flags & DRM_MODE_FLAG_DBLSCAN) | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
...@@ -779,15 +807,17 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -779,15 +807,17 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); if (!rdev->is_atom_bios) {
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
if (lvds) { struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
if (lvds->use_bios_dividers) { if (lvds) {
pll_ref_div = lvds->panel_ref_divider; if (lvds->use_bios_dividers) {
pll_fb_post_div = (lvds->panel_fb_divider | pll_ref_div = lvds->panel_ref_divider;
(lvds->panel_post_divider << 16)); pll_fb_post_div = (lvds->panel_fb_divider |
htotal_cntl = 0; (lvds->panel_post_divider << 16));
use_bios_divs = true; htotal_cntl = 0;
use_bios_divs = true;
}
} }
} }
pll_flags |= RADEON_PLL_USE_REF_DIV; pll_flags |= RADEON_PLL_USE_REF_DIV;
...@@ -1027,6 +1057,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1027,6 +1057,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
radeon_crtc_set_base(crtc, x, y, old_fb); radeon_crtc_set_base(crtc, x, y, old_fb);
radeon_set_crtc_timing(crtc, adjusted_mode); radeon_set_crtc_timing(crtc, adjusted_mode);
radeon_set_pll(crtc, adjusted_mode); radeon_set_pll(crtc, adjusted_mode);
radeon_overscan_setup(crtc, adjusted_mode);
if (radeon_crtc->crtc_id == 0) { if (radeon_crtc->crtc_id == 0) {
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
} else { } else {
...@@ -1042,12 +1073,29 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1042,12 +1073,29 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
static void radeon_crtc_prepare(struct drm_crtc *crtc) static void radeon_crtc_prepare(struct drm_crtc *crtc)
{ {
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); struct drm_device *dev = crtc->dev;
struct drm_crtc *crtci;
/*
* The hardware wedges sometimes if you reconfigure one CRTC
* whilst another is running (see fdo bug #24611).
*/
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head)
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF);
} }
static void radeon_crtc_commit(struct drm_crtc *crtc) static void radeon_crtc_commit(struct drm_crtc *crtc)
{ {
radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON); struct drm_device *dev = crtc->dev;
struct drm_crtc *crtci;
/*
* Reenable the CRTCs that should be running.
*/
list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) {
if (crtci->enabled)
radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
}
} }
static const struct drm_crtc_helper_funcs legacy_helper_funcs = { static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
......
...@@ -136,7 +136,14 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, ...@@ -136,7 +136,14 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
if ((!rdev->is_atom_bios)) { if (rdev->is_atom_bios) {
/* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl
* need to call that on resume to set up the reg properly.
*/
radeon_encoder->pixel_clock = adjusted_mode->clock;
atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
} else {
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
if (lvds) { if (lvds) {
DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
...@@ -147,8 +154,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, ...@@ -147,8 +154,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
(lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
} else } else
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
} else }
lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
lvds_gen_cntl &= ~(RADEON_LVDS_ON | lvds_gen_cntl &= ~(RADEON_LVDS_ON |
RADEON_LVDS_BLON | RADEON_LVDS_BLON |
...@@ -184,9 +190,9 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, ...@@ -184,9 +190,9 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
} }
static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder, static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
...@@ -194,15 +200,22 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -194,15 +200,22 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
radeon_encoder_set_active_device(encoder); radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0); drm_mode_set_crtcinfo(adjusted_mode, 0);
if (radeon_encoder->rmx_type != RMX_OFF) /* get the native mode for LVDS */
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
int mode_id = adjusted_mode->base.id;
*adjusted_mode = *native_mode;
adjusted_mode->hdisplay = mode->hdisplay;
adjusted_mode->vdisplay = mode->vdisplay;
adjusted_mode->base.id = mode_id;
}
return true; return true;
} }
static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
.dpms = radeon_legacy_lvds_dpms, .dpms = radeon_legacy_lvds_dpms,
.mode_fixup = radeon_legacy_lvds_mode_fixup, .mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_lvds_prepare, .prepare = radeon_legacy_lvds_prepare,
.mode_set = radeon_legacy_lvds_mode_set, .mode_set = radeon_legacy_lvds_mode_set,
.commit = radeon_legacy_lvds_commit, .commit = radeon_legacy_lvds_commit,
...@@ -214,17 +227,6 @@ static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { ...@@ -214,17 +227,6 @@ static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_enc_destroy,
}; };
static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -410,7 +412,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc ...@@ -410,7 +412,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
.dpms = radeon_legacy_primary_dac_dpms, .dpms = radeon_legacy_primary_dac_dpms,
.mode_fixup = radeon_legacy_primary_dac_mode_fixup, .mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_primary_dac_prepare, .prepare = radeon_legacy_primary_dac_prepare,
.mode_set = radeon_legacy_primary_dac_mode_set, .mode_set = radeon_legacy_primary_dac_mode_set,
.commit = radeon_legacy_primary_dac_commit, .commit = radeon_legacy_primary_dac_commit,
...@@ -423,16 +425,6 @@ static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { ...@@ -423,16 +425,6 @@ static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_enc_destroy,
}; };
static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -584,7 +576,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, ...@@ -584,7 +576,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
.dpms = radeon_legacy_tmds_int_dpms, .dpms = radeon_legacy_tmds_int_dpms,
.mode_fixup = radeon_legacy_tmds_int_mode_fixup, .mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tmds_int_prepare, .prepare = radeon_legacy_tmds_int_prepare,
.mode_set = radeon_legacy_tmds_int_mode_set, .mode_set = radeon_legacy_tmds_int_mode_set,
.commit = radeon_legacy_tmds_int_commit, .commit = radeon_legacy_tmds_int_commit,
...@@ -596,17 +588,6 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { ...@@ -596,17 +588,6 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_enc_destroy,
}; };
static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -697,6 +678,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ...@@ -697,6 +678,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
/*if (mode->clock > 165000) /*if (mode->clock > 165000)
fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
} }
if (!radeon_combios_external_tmds_setup(encoder))
radeon_external_tmds_setup(encoder);
} }
if (radeon_crtc->crtc_id == 0) { if (radeon_crtc->crtc_id == 0) {
...@@ -724,9 +707,22 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, ...@@ -724,9 +707,22 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
} }
static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
if (tmds) {
if (tmds->i2c_bus)
radeon_i2c_destroy(tmds->i2c_bus);
}
kfree(radeon_encoder->enc_priv);
drm_encoder_cleanup(encoder);
kfree(radeon_encoder);
}
static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
.dpms = radeon_legacy_tmds_ext_dpms, .dpms = radeon_legacy_tmds_ext_dpms,
.mode_fixup = radeon_legacy_tmds_ext_mode_fixup, .mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tmds_ext_prepare, .prepare = radeon_legacy_tmds_ext_prepare,
.mode_set = radeon_legacy_tmds_ext_mode_set, .mode_set = radeon_legacy_tmds_ext_mode_set,
.commit = radeon_legacy_tmds_ext_commit, .commit = radeon_legacy_tmds_ext_commit,
...@@ -735,20 +731,9 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs ...@@ -735,20 +731,9 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs
static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
.destroy = radeon_enc_destroy, .destroy = radeon_ext_tmds_enc_destroy,
}; };
static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* set the active encoder to connector routing */
radeon_encoder_set_active_device(encoder);
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true;
}
static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -1265,7 +1250,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder ...@@ -1265,7 +1250,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
.dpms = radeon_legacy_tv_dac_dpms, .dpms = radeon_legacy_tv_dac_dpms,
.mode_fixup = radeon_legacy_tv_dac_mode_fixup, .mode_fixup = radeon_legacy_mode_fixup,
.prepare = radeon_legacy_tv_dac_prepare, .prepare = radeon_legacy_tv_dac_prepare,
.mode_set = radeon_legacy_tv_dac_mode_set, .mode_set = radeon_legacy_tv_dac_mode_set,
.commit = radeon_legacy_tv_dac_commit, .commit = radeon_legacy_tv_dac_commit,
...@@ -1302,6 +1287,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon ...@@ -1302,6 +1287,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon
return tmds; return tmds;
} }
static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder_ext_tmds *tmds = NULL;
bool ret;
if (rdev->is_atom_bios)
return NULL;
tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL);
if (!tmds)
return NULL;
ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds);
if (ret == false)
radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds);
return tmds;
}
void void
radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{ {
...@@ -1329,7 +1337,6 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t ...@@ -1329,7 +1337,6 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
encoder->possible_crtcs = 0x1; encoder->possible_crtcs = 0x1;
else else
encoder->possible_crtcs = 0x3; encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
radeon_encoder->enc_priv = NULL; radeon_encoder->enc_priv = NULL;
...@@ -1373,7 +1380,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t ...@@ -1373,7 +1380,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
if (!rdev->is_atom_bios) if (!rdev->is_atom_bios)
radeon_combios_get_ext_tmds_info(radeon_encoder); radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
break; break;
} }
} }
...@@ -89,24 +89,38 @@ enum radeon_tv_std { ...@@ -89,24 +89,38 @@ enum radeon_tv_std {
TV_STD_PAL_CN, TV_STD_PAL_CN,
}; };
/* radeon gpio-based i2c
* 1. "mask" reg and bits
* grabs the gpio pins for software use
* 0=not held 1=held
* 2. "a" reg and bits
* output pin value
* 0=low 1=high
* 3. "en" reg and bits
* sets the pin direction
* 0=input 1=output
* 4. "y" reg and bits
* input pin value
* 0=low 1=high
*/
struct radeon_i2c_bus_rec { struct radeon_i2c_bus_rec {
bool valid; bool valid;
uint32_t mask_clk_reg; uint32_t mask_clk_reg;
uint32_t mask_data_reg; uint32_t mask_data_reg;
uint32_t a_clk_reg; uint32_t a_clk_reg;
uint32_t a_data_reg; uint32_t a_data_reg;
uint32_t put_clk_reg; uint32_t en_clk_reg;
uint32_t put_data_reg; uint32_t en_data_reg;
uint32_t get_clk_reg; uint32_t y_clk_reg;
uint32_t get_data_reg; uint32_t y_data_reg;
uint32_t mask_clk_mask; uint32_t mask_clk_mask;
uint32_t mask_data_mask; uint32_t mask_data_mask;
uint32_t put_clk_mask;
uint32_t put_data_mask;
uint32_t get_clk_mask;
uint32_t get_data_mask;
uint32_t a_clk_mask; uint32_t a_clk_mask;
uint32_t a_data_mask; uint32_t a_data_mask;
uint32_t en_clk_mask;
uint32_t en_data_mask;
uint32_t y_clk_mask;
uint32_t y_data_mask;
}; };
struct radeon_tmds_pll { struct radeon_tmds_pll {
...@@ -170,6 +184,11 @@ enum radeon_connector_table { ...@@ -170,6 +184,11 @@ enum radeon_connector_table {
CT_EMAC, CT_EMAC,
}; };
enum radeon_dvo_chip {
DVO_SIL164,
DVO_SIL1178,
};
struct radeon_mode_info { struct radeon_mode_info {
struct atom_context *atom_context; struct atom_context *atom_context;
struct card_info *atom_card_info; struct card_info *atom_card_info;
...@@ -261,6 +280,13 @@ struct radeon_encoder_int_tmds { ...@@ -261,6 +280,13 @@ struct radeon_encoder_int_tmds {
struct radeon_tmds_pll tmds_pll[4]; struct radeon_tmds_pll tmds_pll[4];
}; };
struct radeon_encoder_ext_tmds {
/* tmds over dvo */
struct radeon_i2c_chan *i2c_bus;
uint8_t slave_addr;
enum radeon_dvo_chip dvo_chip;
};
/* spread spectrum */ /* spread spectrum */
struct radeon_atom_ss { struct radeon_atom_ss {
uint16_t percentage; uint16_t percentage;
...@@ -329,6 +355,14 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, ...@@ -329,6 +355,14 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec, struct radeon_i2c_bus_rec *rec,
const char *name); const char *name);
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
u8 *val);
extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
u8 slave_addr,
u8 addr,
u8 val);
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
...@@ -343,12 +377,15 @@ extern void radeon_compute_pll(struct radeon_pll *pll, ...@@ -343,12 +377,15 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
uint32_t *post_div_p, uint32_t *post_div_p,
int flags); int flags);
extern void radeon_setup_encoder_clones(struct drm_device *dev);
struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
extern int atombios_get_encoder_mode(struct drm_encoder *encoder); extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
...@@ -378,12 +415,16 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev); ...@@ -378,12 +415,16 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
extern bool radeon_combios_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev);
extern struct radeon_encoder_atom_dig * extern struct radeon_encoder_atom_dig *
radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_int_tmds *tmds); struct radeon_encoder_int_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
struct radeon_encoder_ext_tmds *tmds);
extern struct radeon_encoder_primary_dac * extern struct radeon_encoder_primary_dac *
radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_tv_dac * extern struct radeon_encoder_tv_dac *
...@@ -395,6 +436,8 @@ extern struct radeon_encoder_tv_dac * ...@@ -395,6 +436,8 @@ extern struct radeon_encoder_tv_dac *
radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
extern struct radeon_encoder_primary_dac * extern struct radeon_encoder_primary_dac *
radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_external_tmds_setup(struct drm_encoder *encoder);
extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
...@@ -426,16 +469,13 @@ void radeon_atombios_init_crtc(struct drm_device *dev, ...@@ -426,16 +469,13 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
struct radeon_crtc *radeon_crtc); struct radeon_crtc *radeon_crtc);
void radeon_legacy_init_crtc(struct drm_device *dev, void radeon_legacy_init_crtc(struct drm_device *dev,
struct radeon_crtc *radeon_crtc); struct radeon_crtc *radeon_crtc);
void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state); extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
void radeon_get_clock_info(struct drm_device *dev); void radeon_get_clock_info(struct drm_device *dev);
extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev); extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev);
extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev); extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev);
void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void radeon_enc_destroy(struct drm_encoder *encoder); void radeon_enc_destroy(struct drm_encoder *encoder);
void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
void radeon_combios_asic_init(struct drm_device *dev); void radeon_combios_asic_init(struct drm_device *dev);
......
This diff is collapsed.
...@@ -28,19 +28,152 @@ ...@@ -28,19 +28,152 @@
#ifndef __RADEON_OBJECT_H__ #ifndef __RADEON_OBJECT_H__
#define __RADEON_OBJECT_H__ #define __RADEON_OBJECT_H__
#include <ttm/ttm_bo_api.h> #include <drm/radeon_drm.h>
#include <ttm/ttm_bo_driver.h> #include "radeon.h"
#include <ttm/ttm_placement.h>
#include <ttm/ttm_module.h>
/* /**
* TTM. * radeon_mem_type_to_domain - return domain corresponding to mem_type
* @mem_type: ttm memory type
*
* Returns corresponding domain of the ttm mem_type
*/
static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
{
switch (mem_type) {
case TTM_PL_VRAM:
return RADEON_GEM_DOMAIN_VRAM;
case TTM_PL_TT:
return RADEON_GEM_DOMAIN_GTT;
case TTM_PL_SYSTEM:
return RADEON_GEM_DOMAIN_CPU;
default:
break;
}
return 0;
}
/**
* radeon_bo_reserve - reserve bo
* @bo: bo structure
* @no_wait: don't sleep while trying to reserve (return -EBUSY)
*
* Returns:
* -EBUSY: buffer is busy and @no_wait is true
* -ERESTART: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space.
*/
static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
{
int r;
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) {
if (r == -ERESTART)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
return r;
}
return 0;
}
static inline void radeon_bo_unreserve(struct radeon_bo *bo)
{
ttm_bo_unreserve(&bo->tbo);
}
/**
* radeon_bo_gpu_offset - return GPU offset of bo
* @bo: radeon object for which we query the offset
*
* Returns current GPU offset of the object.
*
* Note: object should either be pinned or reserved when calling this
* function, it might be usefull to add check for this for debugging.
*/
static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
{
return bo->tbo.offset;
}
static inline unsigned long radeon_bo_size(struct radeon_bo *bo)
{
return bo->tbo.num_pages << PAGE_SHIFT;
}
static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
{
return !!atomic_read(&bo->tbo.reserved);
}
/**
* radeon_bo_mmap_offset - return mmap offset of bo
* @bo: radeon object for which we query the offset
*
* Returns mmap offset of the object.
*
* Note: addr_space_offset is constant after ttm bo init thus isn't protected
* by any lock.
*/ */
struct radeon_mman { static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
struct ttm_bo_global_ref bo_global_ref; {
struct ttm_global_reference mem_global_ref; return bo->tbo.addr_space_offset;
bool mem_global_referenced; }
struct ttm_bo_device bdev;
}; static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
bool no_wait)
{
int r;
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) {
if (r == -ERESTART)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
return r;
}
spin_lock(&bo->tbo.lock);
if (mem_type)
*mem_type = bo->tbo.mem.mem_type;
if (bo->tbo.sync_obj)
r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
spin_unlock(&bo->tbo.lock);
ttm_bo_unreserve(&bo->tbo);
if (unlikely(r == -ERESTART))
goto retry;
return r;
}
extern int radeon_bo_create(struct radeon_device *rdev,
struct drm_gem_object *gobj, unsigned long size,
bool kernel, u32 domain,
struct radeon_bo **bo_ptr);
extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
extern void radeon_bo_kunmap(struct radeon_bo *bo);
extern void radeon_bo_unref(struct radeon_bo **bo);
extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
extern int radeon_bo_unpin(struct radeon_bo *bo);
extern int radeon_bo_evict_vram(struct radeon_device *rdev);
extern void radeon_bo_force_delete(struct radeon_device *rdev);
extern int radeon_bo_init(struct radeon_device *rdev);
extern void radeon_bo_fini(struct radeon_device *rdev);
extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
struct list_head *head);
extern int radeon_bo_list_reserve(struct list_head *head);
extern void radeon_bo_list_unreserve(struct list_head *head);
extern int radeon_bo_list_validate(struct list_head *head, void *fence);
extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence);
extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
struct vm_area_struct *vma);
extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
u32 tiling_flags, u32 pitch);
extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
u32 *tiling_flags, u32 *pitch);
extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
bool force_drop);
extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem);
extern void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
#endif #endif
...@@ -27,7 +27,7 @@ int radeon_debugfs_pm_init(struct radeon_device *rdev); ...@@ -27,7 +27,7 @@ int radeon_debugfs_pm_init(struct radeon_device *rdev);
int radeon_pm_init(struct radeon_device *rdev) int radeon_pm_init(struct radeon_device *rdev)
{ {
if (radeon_debugfs_pm_init(rdev)) { if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for CP !\n"); DRM_ERROR("Failed to register debugfs file for PM!\n");
} }
return 0; return 0;
...@@ -44,8 +44,8 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) ...@@ -44,8 +44,8 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev)); seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev)); seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
return 0; return 0;
} }
......
...@@ -1051,20 +1051,25 @@ ...@@ -1051,20 +1051,25 @@
/* Multimedia I2C bus */ /* Multimedia I2C bus */
#define RADEON_I2C_CNTL_0 0x0090 #define RADEON_I2C_CNTL_0 0x0090
#define RADEON_I2C_DONE (1<<0) #define RADEON_I2C_DONE (1 << 0)
#define RADEON_I2C_NACK (1<<1) #define RADEON_I2C_NACK (1 << 1)
#define RADEON_I2C_HALT (1<<2) #define RADEON_I2C_HALT (1 << 2)
#define RADEON_I2C_SOFT_RST (1<<5) #define RADEON_I2C_SOFT_RST (1 << 5)
#define RADEON_I2C_DRIVE_EN (1<<6) #define RADEON_I2C_DRIVE_EN (1 << 6)
#define RADEON_I2C_DRIVE_SEL (1<<7) #define RADEON_I2C_DRIVE_SEL (1 << 7)
#define RADEON_I2C_START (1<<8) #define RADEON_I2C_START (1 << 8)
#define RADEON_I2C_STOP (1<<9) #define RADEON_I2C_STOP (1 << 9)
#define RADEON_I2C_RECEIVE (1<<10) #define RADEON_I2C_RECEIVE (1 << 10)
#define RADEON_I2C_ABORT (1<<11) #define RADEON_I2C_ABORT (1 << 11)
#define RADEON_I2C_GO (1<<12) #define RADEON_I2C_GO (1 << 12)
#define RADEON_I2C_PRESCALE_SHIFT 16
#define RADEON_I2C_CNTL_1 0x0094 #define RADEON_I2C_CNTL_1 0x0094
#define RADEON_I2C_SEL (1<<16) #define RADEON_I2C_DATA_COUNT_SHIFT 0
#define RADEON_I2C_EN (1<<17) #define RADEON_I2C_ADDR_COUNT_SHIFT 4
#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8
#define RADEON_I2C_SEL (1 << 16)
#define RADEON_I2C_EN (1 << 17)
#define RADEON_I2C_TIME_LIMIT_SHIFT 24
#define RADEON_I2C_DATA 0x0098 #define RADEON_I2C_DATA 0x0098
#define RADEON_DVI_I2C_CNTL_0 0x02e0 #define RADEON_DVI_I2C_CNTL_0 0x02e0
...@@ -1072,7 +1077,7 @@ ...@@ -1072,7 +1077,7 @@
# define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */ # define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */
# define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */ # define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */
# define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */ # define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */
#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */ #define RADEON_DVI_I2C_CNTL_1 0x02e4
#define RADEON_DVI_I2C_DATA 0x02e8 #define RADEON_DVI_I2C_DATA 0x02e8
#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ #define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */
...@@ -1143,14 +1148,15 @@ ...@@ -1143,14 +1148,15 @@
# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15)
#define RADEON_LCD_GPIO_MASK 0x01a0 #define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#define RADEON_GPIOPAD_EN 0x01a0 #define RADEON_GPIOPAD_EN 0x01a0
#define RADEON_GPIOPAD_Y 0x01a4
#define RADEON_LCD_GPIO_MASK 0x01a0
#define RADEON_LCD_GPIO_Y_REG 0x01a4 #define RADEON_LCD_GPIO_Y_REG 0x01a4
#define RADEON_MDGPIO_A_REG 0x01ac #define RADEON_MDGPIO_A_REG 0x01ac
#define RADEON_MDGPIO_EN_REG 0x01b0 #define RADEON_MDGPIO_EN_REG 0x01b0
#define RADEON_MDGPIO_MASK 0x0198 #define RADEON_MDGPIO_MASK 0x0198
#define RADEON_GPIOPAD_MASK 0x0198
#define RADEON_GPIOPAD_A 0x019c
#define RADEON_MDGPIO_Y_REG 0x01b4 #define RADEON_MDGPIO_Y_REG 0x01b4
#define RADEON_MEM_ADDR_CONFIG 0x0148 #define RADEON_MEM_ADDR_CONFIG 0x0148
#define RADEON_MEM_BASE 0x0f10 /* PCI */ #define RADEON_MEM_BASE 0x0f10 /* PCI */
...@@ -1360,6 +1366,9 @@ ...@@ -1360,6 +1366,9 @@
#define RADEON_OVR_CLR 0x0230 #define RADEON_OVR_CLR 0x0230
#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 #define RADEON_OVR_WID_LEFT_RIGHT 0x0234
#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 #define RADEON_OVR_WID_TOP_BOTTOM 0x0238
#define RADEON_OVR2_CLR 0x0330
#define RADEON_OVR2_WID_LEFT_RIGHT 0x0334
#define RADEON_OVR2_WID_TOP_BOTTOM 0x0338
/* first capture unit */ /* first capture unit */
......
...@@ -165,19 +165,24 @@ int radeon_ib_pool_init(struct radeon_device *rdev) ...@@ -165,19 +165,24 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
return 0; return 0;
/* Allocate 1M object buffer */ /* Allocate 1M object buffer */
INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
true, RADEON_GEM_DOMAIN_GTT, true, RADEON_GEM_DOMAIN_GTT,
false, &rdev->ib_pool.robj); &rdev->ib_pool.robj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to ib pool (%d).\n", r); DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
return r; return r;
} }
r = radeon_object_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr); r = radeon_bo_reserve(rdev->ib_pool.robj, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
if (r) { if (r) {
radeon_bo_unreserve(rdev->ib_pool.robj);
DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r); DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
return r; return r;
} }
r = radeon_object_kmap(rdev->ib_pool.robj, &ptr); r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
radeon_bo_unreserve(rdev->ib_pool.robj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to map ib poll (%d).\n", r); DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
return r; return r;
...@@ -203,14 +208,21 @@ int radeon_ib_pool_init(struct radeon_device *rdev) ...@@ -203,14 +208,21 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
void radeon_ib_pool_fini(struct radeon_device *rdev) void radeon_ib_pool_fini(struct radeon_device *rdev)
{ {
int r;
if (!rdev->ib_pool.ready) { if (!rdev->ib_pool.ready) {
return; return;
} }
mutex_lock(&rdev->ib_pool.mutex); mutex_lock(&rdev->ib_pool.mutex);
bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
if (rdev->ib_pool.robj) { if (rdev->ib_pool.robj) {
radeon_object_kunmap(rdev->ib_pool.robj); r = radeon_bo_reserve(rdev->ib_pool.robj, false);
radeon_object_unref(&rdev->ib_pool.robj); if (likely(r == 0)) {
radeon_bo_kunmap(rdev->ib_pool.robj);
radeon_bo_unpin(rdev->ib_pool.robj);
radeon_bo_unreserve(rdev->ib_pool.robj);
}
radeon_bo_unref(&rdev->ib_pool.robj);
rdev->ib_pool.robj = NULL; rdev->ib_pool.robj = NULL;
} }
mutex_unlock(&rdev->ib_pool.mutex); mutex_unlock(&rdev->ib_pool.mutex);
...@@ -288,29 +300,28 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) ...@@ -288,29 +300,28 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
rdev->cp.ring_size = ring_size; rdev->cp.ring_size = ring_size;
/* Allocate ring buffer */ /* Allocate ring buffer */
if (rdev->cp.ring_obj == NULL) { if (rdev->cp.ring_obj == NULL) {
r = radeon_object_create(rdev, NULL, rdev->cp.ring_size, r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
true, RADEON_GEM_DOMAIN_GTT,
RADEON_GEM_DOMAIN_GTT, &rdev->cp.ring_obj);
false,
&rdev->cp.ring_obj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r); dev_err(rdev->dev, "(%d) ring create failed\n", r);
mutex_unlock(&rdev->cp.mutex);
return r; return r;
} }
r = radeon_object_pin(rdev->cp.ring_obj, r = radeon_bo_reserve(rdev->cp.ring_obj, false);
RADEON_GEM_DOMAIN_GTT, if (unlikely(r != 0))
&rdev->cp.gpu_addr); return r;
r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT,
&rdev->cp.gpu_addr);
if (r) { if (r) {
DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r); radeon_bo_unreserve(rdev->cp.ring_obj);
mutex_unlock(&rdev->cp.mutex); dev_err(rdev->dev, "(%d) ring pin failed\n", r);
return r; return r;
} }
r = radeon_object_kmap(rdev->cp.ring_obj, r = radeon_bo_kmap(rdev->cp.ring_obj,
(void **)&rdev->cp.ring); (void **)&rdev->cp.ring);
radeon_bo_unreserve(rdev->cp.ring_obj);
if (r) { if (r) {
DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r); dev_err(rdev->dev, "(%d) ring map failed\n", r);
mutex_unlock(&rdev->cp.mutex);
return r; return r;
} }
} }
...@@ -321,11 +332,17 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) ...@@ -321,11 +332,17 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
void radeon_ring_fini(struct radeon_device *rdev) void radeon_ring_fini(struct radeon_device *rdev)
{ {
int r;
mutex_lock(&rdev->cp.mutex); mutex_lock(&rdev->cp.mutex);
if (rdev->cp.ring_obj) { if (rdev->cp.ring_obj) {
radeon_object_kunmap(rdev->cp.ring_obj); r = radeon_bo_reserve(rdev->cp.ring_obj, false);
radeon_object_unpin(rdev->cp.ring_obj); if (likely(r == 0)) {
radeon_object_unref(&rdev->cp.ring_obj); radeon_bo_kunmap(rdev->cp.ring_obj);
radeon_bo_unpin(rdev->cp.ring_obj);
radeon_bo_unreserve(rdev->cp.ring_obj);
}
radeon_bo_unref(&rdev->cp.ring_obj);
rdev->cp.ring = NULL; rdev->cp.ring = NULL;
rdev->cp.ring_obj = NULL; rdev->cp.ring_obj = NULL;
} }
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ /* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
void radeon_test_moves(struct radeon_device *rdev) void radeon_test_moves(struct radeon_device *rdev)
{ {
struct radeon_object *vram_obj = NULL; struct radeon_bo *vram_obj = NULL;
struct radeon_object **gtt_obj = NULL; struct radeon_bo **gtt_obj = NULL;
struct radeon_fence *fence = NULL; struct radeon_fence *fence = NULL;
uint64_t gtt_addr, vram_addr; uint64_t gtt_addr, vram_addr;
unsigned i, n, size; unsigned i, n, size;
...@@ -52,38 +52,42 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -52,38 +52,42 @@ void radeon_test_moves(struct radeon_device *rdev)
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM, r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
false, &vram_obj); &vram_obj);
if (r) { if (r) {
DRM_ERROR("Failed to create VRAM object\n"); DRM_ERROR("Failed to create VRAM object\n");
goto out_cleanup; goto out_cleanup;
} }
r = radeon_bo_reserve(vram_obj, false);
r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); if (unlikely(r != 0))
goto out_cleanup;
r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
if (r) { if (r) {
DRM_ERROR("Failed to pin VRAM object\n"); DRM_ERROR("Failed to pin VRAM object\n");
goto out_cleanup; goto out_cleanup;
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
void *gtt_map, *vram_map; void *gtt_map, *vram_map;
void **gtt_start, **gtt_end; void **gtt_start, **gtt_end;
void **vram_start, **vram_end; void **vram_start, **vram_end;
r = radeon_object_create(rdev, NULL, size, true, r = radeon_bo_create(rdev, NULL, size, true,
RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i); RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
if (r) { if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i); DRM_ERROR("Failed to create GTT object %d\n", i);
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr); r = radeon_bo_reserve(gtt_obj[i], false);
if (unlikely(r != 0))
goto out_cleanup;
r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr);
if (r) { if (r) {
DRM_ERROR("Failed to pin GTT object %d\n", i); DRM_ERROR("Failed to pin GTT object %d\n", i);
goto out_cleanup; goto out_cleanup;
} }
r = radeon_object_kmap(gtt_obj[i], &gtt_map); r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
if (r) { if (r) {
DRM_ERROR("Failed to map GTT object %d\n", i); DRM_ERROR("Failed to map GTT object %d\n", i);
goto out_cleanup; goto out_cleanup;
...@@ -94,7 +98,7 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -94,7 +98,7 @@ void radeon_test_moves(struct radeon_device *rdev)
gtt_start++) gtt_start++)
*gtt_start = gtt_start; *gtt_start = gtt_start;
radeon_object_kunmap(gtt_obj[i]); radeon_bo_kunmap(gtt_obj[i]);
r = radeon_fence_create(rdev, &fence); r = radeon_fence_create(rdev, &fence);
if (r) { if (r) {
...@@ -116,7 +120,7 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -116,7 +120,7 @@ void radeon_test_moves(struct radeon_device *rdev)
radeon_fence_unref(&fence); radeon_fence_unref(&fence);
r = radeon_object_kmap(vram_obj, &vram_map); r = radeon_bo_kmap(vram_obj, &vram_map);
if (r) { if (r) {
DRM_ERROR("Failed to map VRAM object after copy %d\n", i); DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
goto out_cleanup; goto out_cleanup;
...@@ -131,13 +135,13 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -131,13 +135,13 @@ void radeon_test_moves(struct radeon_device *rdev)
"expected 0x%p (GTT map 0x%p-0x%p)\n", "expected 0x%p (GTT map 0x%p-0x%p)\n",
i, *vram_start, gtt_start, gtt_map, i, *vram_start, gtt_start, gtt_map,
gtt_end); gtt_end);
radeon_object_kunmap(vram_obj); radeon_bo_kunmap(vram_obj);
goto out_cleanup; goto out_cleanup;
} }
*vram_start = vram_start; *vram_start = vram_start;
} }
radeon_object_kunmap(vram_obj); radeon_bo_kunmap(vram_obj);
r = radeon_fence_create(rdev, &fence); r = radeon_fence_create(rdev, &fence);
if (r) { if (r) {
...@@ -159,7 +163,7 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -159,7 +163,7 @@ void radeon_test_moves(struct radeon_device *rdev)
radeon_fence_unref(&fence); radeon_fence_unref(&fence);
r = radeon_object_kmap(gtt_obj[i], &gtt_map); r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
if (r) { if (r) {
DRM_ERROR("Failed to map GTT object after copy %d\n", i); DRM_ERROR("Failed to map GTT object after copy %d\n", i);
goto out_cleanup; goto out_cleanup;
...@@ -174,12 +178,12 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -174,12 +178,12 @@ void radeon_test_moves(struct radeon_device *rdev)
"expected 0x%p (VRAM map 0x%p-0x%p)\n", "expected 0x%p (VRAM map 0x%p-0x%p)\n",
i, *gtt_start, vram_start, vram_map, i, *gtt_start, vram_start, vram_map,
vram_end); vram_end);
radeon_object_kunmap(gtt_obj[i]); radeon_bo_kunmap(gtt_obj[i]);
goto out_cleanup; goto out_cleanup;
} }
} }
radeon_object_kunmap(gtt_obj[i]); radeon_bo_kunmap(gtt_obj[i]);
DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
gtt_addr - rdev->mc.gtt_location); gtt_addr - rdev->mc.gtt_location);
...@@ -187,14 +191,20 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -187,14 +191,20 @@ void radeon_test_moves(struct radeon_device *rdev)
out_cleanup: out_cleanup:
if (vram_obj) { if (vram_obj) {
radeon_object_unpin(vram_obj); if (radeon_bo_is_reserved(vram_obj)) {
radeon_object_unref(&vram_obj); radeon_bo_unpin(vram_obj);
radeon_bo_unreserve(vram_obj);
}
radeon_bo_unref(&vram_obj);
} }
if (gtt_obj) { if (gtt_obj) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (gtt_obj[i]) { if (gtt_obj[i]) {
radeon_object_unpin(gtt_obj[i]); if (radeon_bo_is_reserved(gtt_obj[i])) {
radeon_object_unref(&gtt_obj[i]); radeon_bo_unpin(gtt_obj[i]);
radeon_bo_unreserve(gtt_obj[i]);
}
radeon_bo_unref(&gtt_obj[i]);
} }
} }
kfree(gtt_obj); kfree(gtt_obj);
...@@ -206,4 +216,3 @@ void radeon_test_moves(struct radeon_device *rdev) ...@@ -206,4 +216,3 @@ void radeon_test_moves(struct radeon_device *rdev)
printk(KERN_WARNING "Error while testing BO move.\n"); printk(KERN_WARNING "Error while testing BO move.\n");
} }
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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