Merge remote branch 'korg/drm-radeon-next' into drm-linus
This merges all the radeon changes that weren't reliant on core-next.
This commit is contained in:
commit
3f838fc50c
@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, 1);
|
||||
atombios_blank_crtc(crtc, 0);
|
||||
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
||||
radeon_crtc_load_lut(crtc);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
|
||||
atombios_blank_crtc(crtc, 1);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, 0);
|
||||
atombios_enable_crtc(crtc, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode != DRM_MODE_DPMS_OFF) {
|
||||
radeon_crtc_load_lut(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -457,9 +457,8 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
if (encoder->encoder_type !=
|
||||
DRM_MODE_ENCODER_DAC)
|
||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
if (!ASIC_IS_AVIVO(rdev)
|
||||
&& (encoder->encoder_type ==
|
||||
DRM_MODE_ENCODER_LVDS))
|
||||
if (encoder->encoder_type ==
|
||||
DRM_MODE_ENCODER_LVDS)
|
||||
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||
}
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
@ -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_framebuffer *radeon_fb;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
struct radeon_bo *rbo;
|
||||
uint64_t fb_location;
|
||||
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
|
||||
int r;
|
||||
|
||||
if (!crtc->fb)
|
||||
return -EINVAL;
|
||||
/* no fb bound */
|
||||
if (!crtc->fb) {
|
||||
DRM_DEBUG("No FB bound\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
/* Pin framebuffer & get tilling informations */
|
||||
obj = radeon_fb->obj;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
|
||||
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, &fb_location);
|
||||
if (unlikely(r != 0)) {
|
||||
radeon_bo_unreserve(rbo);
|
||||
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) {
|
||||
case 8:
|
||||
@ -618,11 +630,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
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)
|
||||
fb_format |= AVIVO_D1GRPH_TILED;
|
||||
|
||||
@ -674,7 +681,12 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
|
||||
if (old_fb && old_fb != crtc->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 */
|
||||
|
@ -94,6 +94,15 @@ int r100_pci_gart_init(struct radeon_device *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)
|
||||
{
|
||||
uint32_t tmp;
|
||||
@ -105,9 +114,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
|
||||
WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
|
||||
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
|
||||
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 */
|
||||
WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
|
||||
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
|
||||
@ -255,24 +261,27 @@ int r100_wb_init(struct radeon_device *rdev)
|
||||
int r;
|
||||
|
||||
if (rdev->wb.wb_obj == NULL) {
|
||||
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
|
||||
true,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
false, &rdev->wb.wb_obj);
|
||||
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->wb.wb_obj);
|
||||
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;
|
||||
}
|
||||
r = radeon_object_pin(rdev->wb.wb_obj,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->wb.gpu_addr);
|
||||
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->wb.gpu_addr);
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
|
||||
dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -290,11 +299,19 @@ void r100_wb_disable(struct radeon_device *rdev)
|
||||
|
||||
void r100_wb_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r100_wb_disable(rdev);
|
||||
if (rdev->wb.wb_obj) {
|
||||
radeon_object_kunmap(rdev->wb.wb_obj);
|
||||
radeon_object_unpin(rdev->wb.wb_obj);
|
||||
radeon_object_unref(&rdev->wb.wb_obj);
|
||||
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
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_obj = NULL;
|
||||
}
|
||||
@ -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,
|
||||
struct radeon_cs_packet *pkt,
|
||||
struct radeon_object *robj)
|
||||
struct radeon_bo *robj)
|
||||
{
|
||||
unsigned idx;
|
||||
u32 value;
|
||||
idx = pkt->idx + 1;
|
||||
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 "
|
||||
"(need %u have %lu) !\n",
|
||||
value + 1,
|
||||
radeon_object_size(robj));
|
||||
radeon_bo_size(robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
@ -1583,6 +1600,14 @@ void r100_gpu_init(struct radeon_device *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)
|
||||
{
|
||||
uint32_t tmp;
|
||||
@ -1650,6 +1675,17 @@ int r100_gpu_reset(struct radeon_device *rdev)
|
||||
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
|
||||
@ -2594,7 +2630,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
|
||||
struct r100_cs_track *track, unsigned idx)
|
||||
{
|
||||
unsigned face, w, h;
|
||||
struct radeon_object *cube_robj;
|
||||
struct radeon_bo *cube_robj;
|
||||
unsigned long size;
|
||||
|
||||
for (face = 0; face < 5; face++) {
|
||||
@ -2607,9 +2643,9 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
|
||||
|
||||
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",
|
||||
size, radeon_object_size(cube_robj));
|
||||
size, radeon_bo_size(cube_robj));
|
||||
r100_cs_track_texture_print(&track->textures[idx]);
|
||||
return -1;
|
||||
}
|
||||
@ -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,
|
||||
struct r100_cs_track *track)
|
||||
{
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
unsigned long size;
|
||||
unsigned u, i, w, h;
|
||||
int ret;
|
||||
@ -2676,9 +2712,9 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
|
||||
"%u\n", track->textures[u].tex_coord_type, u);
|
||||
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 "
|
||||
"%lu\n", u, size, radeon_object_size(robj));
|
||||
"%lu\n", u, size, radeon_bo_size(robj));
|
||||
r100_cs_track_texture_print(&track->textures[u]);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -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].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 "
|
||||
"(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",
|
||||
i, track->cb[i].pitch, track->cb[i].cpp,
|
||||
track->cb[i].offset, track->maxy);
|
||||
@ -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.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 "
|
||||
"(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",
|
||||
track->zb.pitch, track->zb.cpp,
|
||||
track->zb.offset, track->maxy);
|
||||
@ -2738,11 +2774,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
|
||||
"bound\n", prim_walk, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (size > radeon_object_size(track->arrays[i].robj)) {
|
||||
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
|
||||
"have %lu dwords\n", prim_walk, i,
|
||||
size >> 2,
|
||||
radeon_object_size(track->arrays[i].robj) >> 2);
|
||||
if (size > radeon_bo_size(track->arrays[i].robj)) {
|
||||
dev_err(rdev->dev, "(PW %u) Vertex array %u "
|
||||
"need %lu dwords have %lu dwords\n",
|
||||
prim_walk, i, size >> 2,
|
||||
radeon_bo_size(track->arrays[i].robj)
|
||||
>> 2);
|
||||
DRM_ERROR("Max indices %u\n", track->max_indx);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -2756,10 +2793,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
|
||||
"bound\n", prim_walk, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (size > radeon_object_size(track->arrays[i].robj)) {
|
||||
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
|
||||
"have %lu dwords\n", prim_walk, i, size >> 2,
|
||||
radeon_object_size(track->arrays[i].robj) >> 2);
|
||||
if (size > radeon_bo_size(track->arrays[i].robj)) {
|
||||
dev_err(rdev->dev, "(PW %u) Vertex array %u "
|
||||
"need %lu dwords have %lu dwords\n",
|
||||
prim_walk, i, size >> 2,
|
||||
radeon_bo_size(track->arrays[i].robj)
|
||||
>> 2);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -3101,6 +3140,9 @@ static int r100_startup(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* set common regs */
|
||||
r100_set_common_regs(rdev);
|
||||
/* program mc */
|
||||
r100_mc_program(rdev);
|
||||
/* Resume clock */
|
||||
r100_clock_startup(rdev);
|
||||
@ -3108,13 +3150,13 @@ static int r100_startup(struct radeon_device *rdev)
|
||||
r100_gpu_init(rdev);
|
||||
/* Initialize GART (initialize after TTM so we can allocate
|
||||
* memory through TTM but finalize after TTM) */
|
||||
r100_enable_bm(rdev);
|
||||
if (rdev->flags & RADEON_IS_PCI) {
|
||||
r = r100_pci_gart_enable(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -3174,7 +3216,7 @@ void r100_fini(struct radeon_device *rdev)
|
||||
r100_pci_gart_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -3242,10 +3284,8 @@ int r100_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
radeon_combios_asic_init(rdev->ddev);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
/* Set asic errata */
|
||||
r100_errata(rdev);
|
||||
/* Initialize clocks */
|
||||
@ -3264,7 +3304,7 @@ int r100_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
if (rdev->flags & RADEON_IS_PCI) {
|
||||
|
@ -10,26 +10,26 @@
|
||||
* CS functions
|
||||
*/
|
||||
struct r100_cs_track_cb {
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
unsigned pitch;
|
||||
unsigned cpp;
|
||||
unsigned offset;
|
||||
};
|
||||
|
||||
struct r100_cs_track_array {
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
unsigned esize;
|
||||
};
|
||||
|
||||
struct r100_cs_cube_info {
|
||||
struct radeon_object *robj;
|
||||
unsigned offset;
|
||||
struct radeon_bo *robj;
|
||||
unsigned offset;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
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 */
|
||||
unsigned pitch;
|
||||
unsigned width;
|
||||
|
@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(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 |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
|
||||
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
|
||||
if (rdev->gart.table.vram.robj) {
|
||||
radeon_object_kunmap(rdev->gart.table.vram.robj);
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
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)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* set common regs */
|
||||
r100_set_common_regs(rdev);
|
||||
/* program mc */
|
||||
r300_mc_program(rdev);
|
||||
/* Resume clock */
|
||||
r300_clock_startup(rdev);
|
||||
@ -1193,13 +1201,18 @@ static int r300_startup(struct radeon_device *rdev)
|
||||
if (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) {
|
||||
r = r100_pci_gart_enable(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -1265,7 +1278,7 @@ void r300_fini(struct radeon_device *rdev)
|
||||
r100_pci_gart_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -1303,10 +1316,8 @@ int r300_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
radeon_combios_asic_init(rdev->ddev);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
/* Set asic errata */
|
||||
r300_errata(rdev);
|
||||
/* Initialize clocks */
|
||||
@ -1325,7 +1336,7 @@ int r300_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
if (rdev->flags & RADEON_IS_PCIE) {
|
||||
|
@ -169,6 +169,9 @@ static int r420_startup(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* set common regs */
|
||||
r100_set_common_regs(rdev);
|
||||
/* program mc */
|
||||
r300_mc_program(rdev);
|
||||
/* Resume clock */
|
||||
r420_clock_resume(rdev);
|
||||
@ -186,7 +189,6 @@ static int r420_startup(struct radeon_device *rdev)
|
||||
}
|
||||
r420_pipes_init(rdev);
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -258,7 +260,7 @@ void r420_fini(struct radeon_device *rdev)
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
if (rdev->is_atom_bios) {
|
||||
radeon_atombios_fini(rdev);
|
||||
} else {
|
||||
@ -301,14 +303,9 @@ int r420_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && 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);
|
||||
}
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Initialize power management */
|
||||
@ -331,10 +328,13 @@ int r420_init(struct radeon_device *rdev)
|
||||
return r;
|
||||
}
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
if (rdev->family == CHIP_R420)
|
||||
r100_enable_bm(rdev);
|
||||
|
||||
if (rdev->flags & RADEON_IS_PCIE) {
|
||||
r = rv370_pcie_gart_init(rdev);
|
||||
if (r)
|
||||
|
@ -185,7 +185,6 @@ static int r520_startup(struct radeon_device *rdev)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -254,6 +253,9 @@ int r520_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
@ -277,7 +279,7 @@ int r520_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rv370_pcie_gart_init(rdev);
|
||||
|
@ -38,8 +38,10 @@
|
||||
|
||||
#define PFP_UCODE_SIZE 576
|
||||
#define PM4_UCODE_SIZE 1792
|
||||
#define RLC_UCODE_SIZE 768
|
||||
#define R700_PFP_UCODE_SIZE 848
|
||||
#define R700_PM4_UCODE_SIZE 1360
|
||||
#define R700_RLC_UCODE_SIZE 1024
|
||||
|
||||
/* Firmware Names */
|
||||
MODULE_FIRMWARE("radeon/R600_pfp.bin");
|
||||
@ -62,6 +64,8 @@ MODULE_FIRMWARE("radeon/RV730_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/RV730_me.bin");
|
||||
MODULE_FIRMWARE("radeon/RV710_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/RV710_me.bin");
|
||||
MODULE_FIRMWARE("radeon/R600_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/R700_rlc.bin");
|
||||
|
||||
int r600_debugfs_mc_info_init(struct radeon_device *rdev);
|
||||
|
||||
@ -180,7 +184,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
|
||||
void r600_pcie_gart_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
int i;
|
||||
int i, r;
|
||||
|
||||
/* Disable all tables */
|
||||
for (i = 0; i < 7; i++)
|
||||
@ -208,8 +212,12 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
|
||||
WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
|
||||
if (rdev->gart.table.vram.robj) {
|
||||
radeon_object_kunmap(rdev->gart.table.vram.robj);
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,6 +1109,10 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
|
||||
(void)RREG32(PCIE_PORT_DATA);
|
||||
}
|
||||
|
||||
void r600_hdp_flush(struct radeon_device *rdev)
|
||||
{
|
||||
WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
|
||||
}
|
||||
|
||||
/*
|
||||
* CP & Ring
|
||||
@ -1110,11 +1122,12 @@ void r600_cp_stop(struct radeon_device *rdev)
|
||||
WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
|
||||
}
|
||||
|
||||
int r600_cp_init_microcode(struct radeon_device *rdev)
|
||||
int r600_init_microcode(struct radeon_device *rdev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
const char *chip_name;
|
||||
size_t pfp_req_size, me_req_size;
|
||||
const char *rlc_chip_name;
|
||||
size_t pfp_req_size, me_req_size, rlc_req_size;
|
||||
char fw_name[30];
|
||||
int err;
|
||||
|
||||
@ -1128,30 +1141,62 @@ int r600_cp_init_microcode(struct radeon_device *rdev)
|
||||
}
|
||||
|
||||
switch (rdev->family) {
|
||||
case CHIP_R600: chip_name = "R600"; break;
|
||||
case CHIP_RV610: chip_name = "RV610"; break;
|
||||
case CHIP_RV630: chip_name = "RV630"; break;
|
||||
case CHIP_RV620: chip_name = "RV620"; break;
|
||||
case CHIP_RV635: chip_name = "RV635"; break;
|
||||
case CHIP_RV670: chip_name = "RV670"; break;
|
||||
case CHIP_R600:
|
||||
chip_name = "R600";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV610:
|
||||
chip_name = "RV610";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV630:
|
||||
chip_name = "RV630";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV620:
|
||||
chip_name = "RV620";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV635:
|
||||
chip_name = "RV635";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV670:
|
||||
chip_name = "RV670";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RS780:
|
||||
case CHIP_RS880: chip_name = "RS780"; break;
|
||||
case CHIP_RV770: chip_name = "RV770"; break;
|
||||
case CHIP_RS880:
|
||||
chip_name = "RS780";
|
||||
rlc_chip_name = "R600";
|
||||
break;
|
||||
case CHIP_RV770:
|
||||
chip_name = "RV770";
|
||||
rlc_chip_name = "R700";
|
||||
break;
|
||||
case CHIP_RV730:
|
||||
case CHIP_RV740: chip_name = "RV730"; break;
|
||||
case CHIP_RV710: chip_name = "RV710"; break;
|
||||
case CHIP_RV740:
|
||||
chip_name = "RV730";
|
||||
rlc_chip_name = "R700";
|
||||
break;
|
||||
case CHIP_RV710:
|
||||
chip_name = "RV710";
|
||||
rlc_chip_name = "R700";
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
pfp_req_size = R700_PFP_UCODE_SIZE * 4;
|
||||
me_req_size = R700_PM4_UCODE_SIZE * 4;
|
||||
rlc_req_size = R700_RLC_UCODE_SIZE * 4;
|
||||
} else {
|
||||
pfp_req_size = PFP_UCODE_SIZE * 4;
|
||||
me_req_size = PM4_UCODE_SIZE * 12;
|
||||
rlc_req_size = RLC_UCODE_SIZE * 4;
|
||||
}
|
||||
|
||||
DRM_INFO("Loading %s CP Microcode\n", chip_name);
|
||||
DRM_INFO("Loading %s Microcode\n", chip_name);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
|
||||
err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
|
||||
@ -1175,6 +1220,18 @@ int r600_cp_init_microcode(struct radeon_device *rdev)
|
||||
rdev->me_fw->size, fw_name);
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
|
||||
err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
if (rdev->rlc_fw->size != rlc_req_size) {
|
||||
printk(KERN_ERR
|
||||
"r600_rlc: Bogus length %zu in firmware \"%s\"\n",
|
||||
rdev->rlc_fw->size, fw_name);
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
@ -1187,6 +1244,8 @@ out:
|
||||
rdev->pfp_fw = NULL;
|
||||
release_firmware(rdev->me_fw);
|
||||
rdev->me_fw = NULL;
|
||||
release_firmware(rdev->rlc_fw);
|
||||
rdev->rlc_fw = NULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@ -1381,10 +1440,16 @@ int r600_ring_test(struct radeon_device *rdev)
|
||||
|
||||
void r600_wb_disable(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
WREG32(SCRATCH_UMSK, 0);
|
||||
if (rdev->wb.wb_obj) {
|
||||
radeon_object_kunmap(rdev->wb.wb_obj);
|
||||
radeon_object_unpin(rdev->wb.wb_obj);
|
||||
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return;
|
||||
radeon_bo_kunmap(rdev->wb.wb_obj);
|
||||
radeon_bo_unpin(rdev->wb.wb_obj);
|
||||
radeon_bo_unreserve(rdev->wb.wb_obj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1392,7 +1457,7 @@ void r600_wb_fini(struct radeon_device *rdev)
|
||||
{
|
||||
r600_wb_disable(rdev);
|
||||
if (rdev->wb.wb_obj) {
|
||||
radeon_object_unref(&rdev->wb.wb_obj);
|
||||
radeon_bo_unref(&rdev->wb.wb_obj);
|
||||
rdev->wb.wb = NULL;
|
||||
rdev->wb.wb_obj = NULL;
|
||||
}
|
||||
@ -1403,22 +1468,29 @@ int r600_wb_enable(struct radeon_device *rdev)
|
||||
int r;
|
||||
|
||||
if (rdev->wb.wb_obj == NULL) {
|
||||
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
|
||||
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
|
||||
dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->wb.gpu_addr);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
|
||||
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
r600_wb_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
|
||||
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->wb.gpu_addr);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
|
||||
radeon_bo_unreserve(rdev->wb.wb_obj);
|
||||
dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r);
|
||||
r600_wb_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
|
||||
radeon_bo_unreserve(rdev->wb.wb_obj);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "(%d) map WB bo failed\n", r);
|
||||
r600_wb_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
@ -1433,10 +1505,14 @@ int r600_wb_enable(struct radeon_device *rdev)
|
||||
void r600_fence_ring_emit(struct radeon_device *rdev,
|
||||
struct radeon_fence *fence)
|
||||
{
|
||||
/* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */
|
||||
/* Emit fence sequence & fire IRQ */
|
||||
radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
|
||||
radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
|
||||
radeon_ring_write(rdev, fence->seq);
|
||||
/* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
|
||||
radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
|
||||
radeon_ring_write(rdev, RB_INT_STAT);
|
||||
}
|
||||
|
||||
int r600_copy_dma(struct radeon_device *rdev,
|
||||
@ -1459,18 +1535,6 @@ int r600_copy_blit(struct radeon_device *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_irq_process(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_irq_set(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_set_surface_reg(struct radeon_device *rdev, int reg,
|
||||
uint32_t tiling_flags, uint32_t pitch,
|
||||
uint32_t offset, uint32_t obj_size)
|
||||
@ -1516,13 +1580,26 @@ int r600_startup(struct radeon_device *rdev)
|
||||
}
|
||||
r600_gpu_init(rdev);
|
||||
|
||||
r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->r600_blit.shader_gpu_addr);
|
||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->r600_blit.shader_gpu_addr);
|
||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("failed to pin blit object %d\n", r);
|
||||
dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Enable IRQ */
|
||||
r = r600_irq_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: IH init failed (%d).\n", r);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r600_irq_set(rdev);
|
||||
|
||||
r = radeon_ring_init(rdev, rdev->cp.ring_size);
|
||||
if (r)
|
||||
return r;
|
||||
@ -1583,13 +1660,19 @@ int r600_resume(struct radeon_device *rdev)
|
||||
|
||||
int r600_suspend(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* FIXME: we should wait for ring to be empty */
|
||||
r600_cp_stop(rdev);
|
||||
rdev->cp.ready = false;
|
||||
r600_wb_disable(rdev);
|
||||
r600_pcie_gart_disable(rdev);
|
||||
/* unpin shaders bo */
|
||||
radeon_object_unpin(rdev->r600_blit.shader_obj);
|
||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
radeon_bo_unpin(rdev->r600_blit.shader_obj);
|
||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1627,7 +1710,11 @@ int r600_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Post card if necessary */
|
||||
if (!r600_card_posted(rdev) && rdev->bios) {
|
||||
if (!r600_card_posted(rdev)) {
|
||||
if (!rdev->bios) {
|
||||
dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
@ -1650,14 +1737,22 @@ int r600_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = radeon_irq_kms_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
rdev->cp.ring_obj = NULL;
|
||||
r600_ring_init(rdev, 1024 * 1024);
|
||||
|
||||
if (!rdev->me_fw || !rdev->pfp_fw) {
|
||||
r = r600_cp_init_microcode(rdev);
|
||||
rdev->ih.ring_obj = NULL;
|
||||
r600_ih_ring_init(rdev, 64 * 1024);
|
||||
|
||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||
r = r600_init_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load firmware!\n");
|
||||
return r;
|
||||
@ -1704,6 +1799,8 @@ void r600_fini(struct radeon_device *rdev)
|
||||
r600_suspend(rdev);
|
||||
|
||||
r600_blit_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_ring_fini(rdev);
|
||||
r600_wb_fini(rdev);
|
||||
r600_pcie_gart_fini(rdev);
|
||||
@ -1712,7 +1809,7 @@ void r600_fini(struct radeon_device *rdev)
|
||||
radeon_clocks_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_AGP)
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -1798,8 +1895,461 @@ int r600_ib_test(struct radeon_device *rdev)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts
|
||||
*
|
||||
* Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty
|
||||
* the same as the CP ring buffer, but in reverse. Rather than the CPU
|
||||
* writing to the ring and the GPU consuming, the GPU writes to the ring
|
||||
* and host consumes. As the host irq handler processes interrupts, it
|
||||
* increments the rptr. When the rptr catches up with the wptr, all the
|
||||
* current interrupts have been processed.
|
||||
*/
|
||||
|
||||
void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
{
|
||||
u32 rb_bufsz;
|
||||
|
||||
/* Align ring size */
|
||||
rb_bufsz = drm_order(ring_size / 4);
|
||||
ring_size = (1 << rb_bufsz) * 4;
|
||||
rdev->ih.ring_size = ring_size;
|
||||
rdev->ih.align_mask = 4 - 1;
|
||||
}
|
||||
|
||||
static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
|
||||
{
|
||||
int r;
|
||||
|
||||
rdev->ih.ring_size = ring_size;
|
||||
/* Allocate ring buffer */
|
||||
if (rdev->ih.ring_obj == NULL) {
|
||||
r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
|
||||
true,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->ih.ring_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_reserve(rdev->ih.ring_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->ih.ring_obj,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->ih.gpu_addr);
|
||||
if (r) {
|
||||
radeon_bo_unreserve(rdev->ih.ring_obj);
|
||||
DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_kmap(rdev->ih.ring_obj,
|
||||
(void **)&rdev->ih.ring);
|
||||
radeon_bo_unreserve(rdev->ih.ring_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
|
||||
rdev->ih.rptr = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r600_ih_ring_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
if (rdev->ih.ring_obj) {
|
||||
r = radeon_bo_reserve(rdev->ih.ring_obj, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_kunmap(rdev->ih.ring_obj);
|
||||
radeon_bo_unpin(rdev->ih.ring_obj);
|
||||
radeon_bo_unreserve(rdev->ih.ring_obj);
|
||||
}
|
||||
radeon_bo_unref(&rdev->ih.ring_obj);
|
||||
rdev->ih.ring = NULL;
|
||||
rdev->ih.ring_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void r600_rlc_stop(struct radeon_device *rdev)
|
||||
{
|
||||
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
/* r7xx asics need to soft reset RLC before halting */
|
||||
WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
|
||||
RREG32(SRBM_SOFT_RESET);
|
||||
udelay(15000);
|
||||
WREG32(SRBM_SOFT_RESET, 0);
|
||||
RREG32(SRBM_SOFT_RESET);
|
||||
}
|
||||
|
||||
WREG32(RLC_CNTL, 0);
|
||||
}
|
||||
|
||||
static void r600_rlc_start(struct radeon_device *rdev)
|
||||
{
|
||||
WREG32(RLC_CNTL, RLC_ENABLE);
|
||||
}
|
||||
|
||||
static int r600_rlc_init(struct radeon_device *rdev)
|
||||
{
|
||||
u32 i;
|
||||
const __be32 *fw_data;
|
||||
|
||||
if (!rdev->rlc_fw)
|
||||
return -EINVAL;
|
||||
|
||||
r600_rlc_stop(rdev);
|
||||
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_CNTL, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
|
||||
WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
|
||||
WREG32(RLC_MC_CNTL, 0);
|
||||
WREG32(RLC_UCODE_CNTL, 0);
|
||||
|
||||
fw_data = (const __be32 *)rdev->rlc_fw->data;
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
}
|
||||
WREG32(RLC_UCODE_ADDR, 0);
|
||||
|
||||
r600_rlc_start(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r600_enable_interrupts(struct radeon_device *rdev)
|
||||
{
|
||||
u32 ih_cntl = RREG32(IH_CNTL);
|
||||
u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
|
||||
|
||||
ih_cntl |= ENABLE_INTR;
|
||||
ih_rb_cntl |= IH_RB_ENABLE;
|
||||
WREG32(IH_CNTL, ih_cntl);
|
||||
WREG32(IH_RB_CNTL, ih_rb_cntl);
|
||||
rdev->ih.enabled = true;
|
||||
}
|
||||
|
||||
static void r600_disable_interrupts(struct radeon_device *rdev)
|
||||
{
|
||||
u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
|
||||
u32 ih_cntl = RREG32(IH_CNTL);
|
||||
|
||||
ih_rb_cntl &= ~IH_RB_ENABLE;
|
||||
ih_cntl &= ~ENABLE_INTR;
|
||||
WREG32(IH_RB_CNTL, ih_rb_cntl);
|
||||
WREG32(IH_CNTL, ih_cntl);
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32(IH_RB_RPTR, 0);
|
||||
WREG32(IH_RB_WPTR, 0);
|
||||
rdev->ih.enabled = false;
|
||||
rdev->ih.wptr = 0;
|
||||
rdev->ih.rptr = 0;
|
||||
}
|
||||
|
||||
int r600_irq_init(struct radeon_device *rdev)
|
||||
{
|
||||
int ret = 0;
|
||||
int rb_bufsz;
|
||||
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
||||
|
||||
/* allocate ring */
|
||||
ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* disable irqs */
|
||||
r600_disable_interrupts(rdev);
|
||||
|
||||
/* init rlc */
|
||||
ret = r600_rlc_init(rdev);
|
||||
if (ret) {
|
||||
r600_ih_ring_fini(rdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* setup interrupt control */
|
||||
/* set dummy read address to ring address */
|
||||
WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
|
||||
interrupt_cntl = RREG32(INTERRUPT_CNTL);
|
||||
/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
|
||||
* IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
|
||||
*/
|
||||
interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
|
||||
/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
|
||||
interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
|
||||
WREG32(INTERRUPT_CNTL, interrupt_cntl);
|
||||
|
||||
WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
|
||||
rb_bufsz = drm_order(rdev->ih.ring_size / 4);
|
||||
|
||||
ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
|
||||
IH_WPTR_OVERFLOW_CLEAR |
|
||||
(rb_bufsz << 1));
|
||||
/* WPTR writeback, not yet */
|
||||
/*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/
|
||||
WREG32(IH_RB_WPTR_ADDR_LO, 0);
|
||||
WREG32(IH_RB_WPTR_ADDR_HI, 0);
|
||||
|
||||
WREG32(IH_RB_CNTL, ih_rb_cntl);
|
||||
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32(IH_RB_RPTR, 0);
|
||||
WREG32(IH_RB_WPTR, 0);
|
||||
|
||||
/* Default settings for IH_CNTL (disabled at first) */
|
||||
ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10);
|
||||
/* RPTR_REARM only works if msi's are enabled */
|
||||
if (rdev->msi_enabled)
|
||||
ih_cntl |= RPTR_REARM;
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT);
|
||||
#endif
|
||||
WREG32(IH_CNTL, ih_cntl);
|
||||
|
||||
/* force the active interrupt state to all disabled */
|
||||
WREG32(CP_INT_CNTL, 0);
|
||||
WREG32(GRBM_INT_CNTL, 0);
|
||||
WREG32(DxMODE_INT_MASK, 0);
|
||||
|
||||
/* enable irqs */
|
||||
r600_enable_interrupts(rdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void r600_irq_fini(struct radeon_device *rdev)
|
||||
{
|
||||
r600_disable_interrupts(rdev);
|
||||
r600_rlc_stop(rdev);
|
||||
r600_ih_ring_fini(rdev);
|
||||
}
|
||||
|
||||
int r600_irq_set(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
|
||||
uint32_t mode_int = 0;
|
||||
|
||||
/* don't enable anything if the ih is disabled */
|
||||
if (!rdev->ih.enabled)
|
||||
return 0;
|
||||
|
||||
if (rdev->irq.sw_int) {
|
||||
DRM_DEBUG("r600_irq_set: sw int\n");
|
||||
cp_int_cntl |= RB_INT_ENABLE;
|
||||
}
|
||||
if (rdev->irq.crtc_vblank_int[0]) {
|
||||
DRM_DEBUG("r600_irq_set: vblank 0\n");
|
||||
mode_int |= D1MODE_VBLANK_INT_MASK;
|
||||
}
|
||||
if (rdev->irq.crtc_vblank_int[1]) {
|
||||
DRM_DEBUG("r600_irq_set: vblank 1\n");
|
||||
mode_int |= D2MODE_VBLANK_INT_MASK;
|
||||
}
|
||||
|
||||
WREG32(CP_INT_CNTL, cp_int_cntl);
|
||||
WREG32(DxMODE_INT_MASK, mode_int);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int)
|
||||
{
|
||||
|
||||
if (disp_int & LB_D1_VBLANK_INTERRUPT)
|
||||
WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
|
||||
if (disp_int & LB_D1_VLINE_INTERRUPT)
|
||||
WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
|
||||
if (disp_int & LB_D2_VBLANK_INTERRUPT)
|
||||
WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
|
||||
if (disp_int & LB_D2_VLINE_INTERRUPT)
|
||||
WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
|
||||
|
||||
}
|
||||
|
||||
void r600_irq_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 disp_int;
|
||||
|
||||
r600_disable_interrupts(rdev);
|
||||
/* Wait and acknowledge irq */
|
||||
mdelay(1);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
|
||||
else
|
||||
disp_int = RREG32(DISP_INTERRUPT_STATUS);
|
||||
r600_irq_ack(rdev, disp_int);
|
||||
}
|
||||
|
||||
static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
|
||||
{
|
||||
u32 wptr, tmp;
|
||||
|
||||
/* XXX use writeback */
|
||||
wptr = RREG32(IH_RB_WPTR);
|
||||
|
||||
if (wptr & RB_OVERFLOW) {
|
||||
WARN_ON(1);
|
||||
/* XXX deal with overflow */
|
||||
DRM_ERROR("IH RB overflow\n");
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
}
|
||||
wptr = wptr & WPTR_OFFSET_MASK;
|
||||
|
||||
return wptr;
|
||||
}
|
||||
|
||||
/* r600 IV Ring
|
||||
* Each IV ring entry is 128 bits:
|
||||
* [7:0] - interrupt source id
|
||||
* [31:8] - reserved
|
||||
* [59:32] - interrupt source data
|
||||
* [127:60] - reserved
|
||||
*
|
||||
* The basic interrupt vector entries
|
||||
* are decoded as follows:
|
||||
* src_id src_data description
|
||||
* 1 0 D1 Vblank
|
||||
* 1 1 D1 Vline
|
||||
* 5 0 D2 Vblank
|
||||
* 5 1 D2 Vline
|
||||
* 19 0 FP Hot plug detection A
|
||||
* 19 1 FP Hot plug detection B
|
||||
* 19 2 DAC A auto-detection
|
||||
* 19 3 DAC B auto-detection
|
||||
* 176 - CP_INT RB
|
||||
* 177 - CP_INT IB1
|
||||
* 178 - CP_INT IB2
|
||||
* 181 - EOP Interrupt
|
||||
* 233 - GUI Idle
|
||||
*
|
||||
* Note, these are based on r600 and may need to be
|
||||
* adjusted or added to on newer asics
|
||||
*/
|
||||
|
||||
int r600_irq_process(struct radeon_device *rdev)
|
||||
{
|
||||
u32 wptr = r600_get_ih_wptr(rdev);
|
||||
u32 rptr = rdev->ih.rptr;
|
||||
u32 src_id, src_data;
|
||||
u32 last_entry = rdev->ih.ring_size - 16;
|
||||
u32 ring_index, disp_int;
|
||||
unsigned long flags;
|
||||
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
|
||||
spin_lock_irqsave(&rdev->ih.lock, flags);
|
||||
|
||||
if (rptr == wptr) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (rdev->shutdown) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
restart_ih:
|
||||
/* display interrupts */
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
|
||||
else
|
||||
disp_int = RREG32(DISP_INTERRUPT_STATUS);
|
||||
r600_irq_ack(rdev, disp_int);
|
||||
|
||||
rdev->ih.wptr = wptr;
|
||||
while (rptr != wptr) {
|
||||
/* wptr/rptr are in bytes! */
|
||||
ring_index = rptr / 4;
|
||||
src_id = rdev->ih.ring[ring_index] & 0xff;
|
||||
src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
|
||||
|
||||
switch (src_id) {
|
||||
case 1: /* D1 vblank/vline */
|
||||
switch (src_data) {
|
||||
case 0: /* D1 vblank */
|
||||
if (disp_int & LB_D1_VBLANK_INTERRUPT) {
|
||||
drm_handle_vblank(rdev->ddev, 0);
|
||||
disp_int &= ~LB_D1_VBLANK_INTERRUPT;
|
||||
DRM_DEBUG("IH: D1 vblank\n");
|
||||
}
|
||||
break;
|
||||
case 1: /* D1 vline */
|
||||
if (disp_int & LB_D1_VLINE_INTERRUPT) {
|
||||
disp_int &= ~LB_D1_VLINE_INTERRUPT;
|
||||
DRM_DEBUG("IH: D1 vline\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5: /* D2 vblank/vline */
|
||||
switch (src_data) {
|
||||
case 0: /* D2 vblank */
|
||||
if (disp_int & LB_D2_VBLANK_INTERRUPT) {
|
||||
drm_handle_vblank(rdev->ddev, 1);
|
||||
disp_int &= ~LB_D2_VBLANK_INTERRUPT;
|
||||
DRM_DEBUG("IH: D2 vblank\n");
|
||||
}
|
||||
break;
|
||||
case 1: /* D1 vline */
|
||||
if (disp_int & LB_D2_VLINE_INTERRUPT) {
|
||||
disp_int &= ~LB_D2_VLINE_INTERRUPT;
|
||||
DRM_DEBUG("IH: D2 vline\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 176: /* CP_INT in ring buffer */
|
||||
case 177: /* CP_INT in IB1 */
|
||||
case 178: /* CP_INT in IB2 */
|
||||
DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
|
||||
radeon_fence_process(rdev);
|
||||
break;
|
||||
case 181: /* CP EOP event */
|
||||
DRM_DEBUG("IH: CP EOP\n");
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
|
||||
break;
|
||||
}
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
if (rptr == last_entry)
|
||||
rptr = 0;
|
||||
else
|
||||
rptr += 16;
|
||||
}
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
wptr = r600_get_ih_wptr(rdev);
|
||||
if (wptr != rdev->ih.wptr)
|
||||
goto restart_ih;
|
||||
rdev->ih.rptr = rptr;
|
||||
WREG32(IH_RB_RPTR, rdev->ih.rptr);
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugfs info
|
||||
@ -1811,21 +2361,21 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data)
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
uint32_t rdp, wdp;
|
||||
unsigned count, i, j;
|
||||
|
||||
radeon_ring_free_size(rdev);
|
||||
rdp = RREG32(CP_RB_RPTR);
|
||||
wdp = RREG32(CP_RB_WPTR);
|
||||
count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
|
||||
count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw;
|
||||
seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
|
||||
seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
|
||||
seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
|
||||
seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR));
|
||||
seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR));
|
||||
seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr);
|
||||
seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr);
|
||||
seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
|
||||
seq_printf(m, "%u dwords in ring\n", count);
|
||||
i = rdev->cp.rptr;
|
||||
for (j = 0; j <= count; j++) {
|
||||
i = (rdp + j) & rdev->cp.ptr_mask;
|
||||
seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
|
||||
i = (i + 1) & rdev->cp.ptr_mask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -473,9 +473,8 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||
obj_size += r6xx_ps_size * 4;
|
||||
obj_size = ALIGN(obj_size, 256);
|
||||
|
||||
r = radeon_object_create(rdev, NULL, obj_size,
|
||||
true, RADEON_GEM_DOMAIN_VRAM,
|
||||
false, &rdev->r600_blit.shader_obj);
|
||||
r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->r600_blit.shader_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("r600 failed to allocate shader\n");
|
||||
return r;
|
||||
@ -485,12 +484,14 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||
obj_size,
|
||||
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) {
|
||||
DRM_ERROR("failed to map blit object %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
memcpy_toio(ptr + rdev->r600_blit.state_offset,
|
||||
r7xx_default_state, rdev->r600_blit.state_len * 4);
|
||||
@ -500,19 +501,26 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||
if (num_packet2s)
|
||||
memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
|
||||
packet2s, num_packet2s * 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);
|
||||
|
||||
radeon_object_kunmap(rdev->r600_blit.shader_obj);
|
||||
radeon_bo_kunmap(rdev->r600_blit.shader_obj);
|
||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void r600_blit_fini(struct radeon_device *rdev)
|
||||
{
|
||||
radeon_object_unpin(rdev->r600_blit.shader_obj);
|
||||
radeon_object_unref(&rdev->r600_blit.shader_obj);
|
||||
int r;
|
||||
|
||||
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)
|
||||
@ -569,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
|
||||
ring_size = num_loops * dwords_per_loop;
|
||||
/* set default + shaders */
|
||||
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 += 3; /* fence emit for done copy */
|
||||
ring_size += 5; /* fence emit for done copy */
|
||||
r = radeon_ring_lock(rdev, ring_size);
|
||||
WARN_ON(r);
|
||||
|
||||
|
@ -456,7 +456,163 @@
|
||||
#define WAIT_2D_IDLECLEAN_bit (1 << 16)
|
||||
#define WAIT_3D_IDLECLEAN_bit (1 << 17)
|
||||
|
||||
#define IH_RB_CNTL 0x3e00
|
||||
# define IH_RB_ENABLE (1 << 0)
|
||||
# define IH_IB_SIZE(x) ((x) << 1) /* log2 */
|
||||
# define IH_RB_FULL_DRAIN_ENABLE (1 << 6)
|
||||
# define IH_WPTR_WRITEBACK_ENABLE (1 << 8)
|
||||
# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
|
||||
# define IH_WPTR_OVERFLOW_ENABLE (1 << 16)
|
||||
# define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
|
||||
#define IH_RB_BASE 0x3e04
|
||||
#define IH_RB_RPTR 0x3e08
|
||||
#define IH_RB_WPTR 0x3e0c
|
||||
# define RB_OVERFLOW (1 << 0)
|
||||
# define WPTR_OFFSET_MASK 0x3fffc
|
||||
#define IH_RB_WPTR_ADDR_HI 0x3e10
|
||||
#define IH_RB_WPTR_ADDR_LO 0x3e14
|
||||
#define IH_CNTL 0x3e18
|
||||
# define ENABLE_INTR (1 << 0)
|
||||
# define IH_MC_SWAP(x) ((x) << 2)
|
||||
# define IH_MC_SWAP_NONE 0
|
||||
# define IH_MC_SWAP_16BIT 1
|
||||
# define IH_MC_SWAP_32BIT 2
|
||||
# define IH_MC_SWAP_64BIT 3
|
||||
# define RPTR_REARM (1 << 4)
|
||||
# define MC_WRREQ_CREDIT(x) ((x) << 15)
|
||||
# define MC_WR_CLEAN_CNT(x) ((x) << 20)
|
||||
|
||||
#define RLC_CNTL 0x3f00
|
||||
# define RLC_ENABLE (1 << 0)
|
||||
#define RLC_HB_BASE 0x3f10
|
||||
#define RLC_HB_CNTL 0x3f0c
|
||||
#define RLC_HB_RPTR 0x3f20
|
||||
#define RLC_HB_WPTR 0x3f1c
|
||||
#define RLC_HB_WPTR_LSB_ADDR 0x3f14
|
||||
#define RLC_HB_WPTR_MSB_ADDR 0x3f18
|
||||
#define RLC_MC_CNTL 0x3f44
|
||||
#define RLC_UCODE_CNTL 0x3f48
|
||||
#define RLC_UCODE_ADDR 0x3f2c
|
||||
#define RLC_UCODE_DATA 0x3f30
|
||||
|
||||
#define SRBM_SOFT_RESET 0xe60
|
||||
# define SOFT_RESET_RLC (1 << 13)
|
||||
|
||||
#define CP_INT_CNTL 0xc124
|
||||
# define CNTX_BUSY_INT_ENABLE (1 << 19)
|
||||
# define CNTX_EMPTY_INT_ENABLE (1 << 20)
|
||||
# define SCRATCH_INT_ENABLE (1 << 25)
|
||||
# define TIME_STAMP_INT_ENABLE (1 << 26)
|
||||
# define IB2_INT_ENABLE (1 << 29)
|
||||
# define IB1_INT_ENABLE (1 << 30)
|
||||
# define RB_INT_ENABLE (1 << 31)
|
||||
#define CP_INT_STATUS 0xc128
|
||||
# define SCRATCH_INT_STAT (1 << 25)
|
||||
# define TIME_STAMP_INT_STAT (1 << 26)
|
||||
# define IB2_INT_STAT (1 << 29)
|
||||
# define IB1_INT_STAT (1 << 30)
|
||||
# define RB_INT_STAT (1 << 31)
|
||||
|
||||
#define GRBM_INT_CNTL 0x8060
|
||||
# define RDERR_INT_ENABLE (1 << 0)
|
||||
# define WAIT_COUNT_TIMEOUT_INT_ENABLE (1 << 1)
|
||||
# define GUI_IDLE_INT_ENABLE (1 << 19)
|
||||
|
||||
#define INTERRUPT_CNTL 0x5468
|
||||
# define IH_DUMMY_RD_OVERRIDE (1 << 0)
|
||||
# define IH_DUMMY_RD_EN (1 << 1)
|
||||
# define IH_REQ_NONSNOOP_EN (1 << 3)
|
||||
# define GEN_IH_INT_EN (1 << 8)
|
||||
#define INTERRUPT_CNTL2 0x546c
|
||||
|
||||
#define D1MODE_VBLANK_STATUS 0x6534
|
||||
#define D2MODE_VBLANK_STATUS 0x6d34
|
||||
# define DxMODE_VBLANK_OCCURRED (1 << 0)
|
||||
# define DxMODE_VBLANK_ACK (1 << 4)
|
||||
# define DxMODE_VBLANK_STAT (1 << 12)
|
||||
# define DxMODE_VBLANK_INTERRUPT (1 << 16)
|
||||
# define DxMODE_VBLANK_INTERRUPT_TYPE (1 << 17)
|
||||
#define D1MODE_VLINE_STATUS 0x653c
|
||||
#define D2MODE_VLINE_STATUS 0x6d3c
|
||||
# define DxMODE_VLINE_OCCURRED (1 << 0)
|
||||
# define DxMODE_VLINE_ACK (1 << 4)
|
||||
# define DxMODE_VLINE_STAT (1 << 12)
|
||||
# define DxMODE_VLINE_INTERRUPT (1 << 16)
|
||||
# define DxMODE_VLINE_INTERRUPT_TYPE (1 << 17)
|
||||
#define DxMODE_INT_MASK 0x6540
|
||||
# define D1MODE_VBLANK_INT_MASK (1 << 0)
|
||||
# define D1MODE_VLINE_INT_MASK (1 << 4)
|
||||
# define D2MODE_VBLANK_INT_MASK (1 << 8)
|
||||
# define D2MODE_VLINE_INT_MASK (1 << 12)
|
||||
#define DCE3_DISP_INTERRUPT_STATUS 0x7ddc
|
||||
# define DC_HPD1_INTERRUPT (1 << 18)
|
||||
# define DC_HPD2_INTERRUPT (1 << 19)
|
||||
#define DISP_INTERRUPT_STATUS 0x7edc
|
||||
# define LB_D1_VLINE_INTERRUPT (1 << 2)
|
||||
# define LB_D2_VLINE_INTERRUPT (1 << 3)
|
||||
# define LB_D1_VBLANK_INTERRUPT (1 << 4)
|
||||
# define LB_D2_VBLANK_INTERRUPT (1 << 5)
|
||||
# define DACA_AUTODETECT_INTERRUPT (1 << 16)
|
||||
# define DACB_AUTODETECT_INTERRUPT (1 << 17)
|
||||
# define DC_HOT_PLUG_DETECT1_INTERRUPT (1 << 18)
|
||||
# define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19)
|
||||
# define DC_I2C_SW_DONE_INTERRUPT (1 << 20)
|
||||
# define DC_I2C_HW_DONE_INTERRUPT (1 << 21)
|
||||
#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8
|
||||
# define DC_HPD4_INTERRUPT (1 << 14)
|
||||
# define DC_HPD4_RX_INTERRUPT (1 << 15)
|
||||
# define DC_HPD3_INTERRUPT (1 << 28)
|
||||
# define DC_HPD1_RX_INTERRUPT (1 << 29)
|
||||
# define DC_HPD2_RX_INTERRUPT (1 << 30)
|
||||
#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2 0x7dec
|
||||
# define DC_HPD3_RX_INTERRUPT (1 << 0)
|
||||
# define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 1)
|
||||
# define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 2)
|
||||
# define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 3)
|
||||
# define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 4)
|
||||
# define AUX1_SW_DONE_INTERRUPT (1 << 5)
|
||||
# define AUX1_LS_DONE_INTERRUPT (1 << 6)
|
||||
# define AUX2_SW_DONE_INTERRUPT (1 << 7)
|
||||
# define AUX2_LS_DONE_INTERRUPT (1 << 8)
|
||||
# define AUX3_SW_DONE_INTERRUPT (1 << 9)
|
||||
# define AUX3_LS_DONE_INTERRUPT (1 << 10)
|
||||
# define AUX4_SW_DONE_INTERRUPT (1 << 11)
|
||||
# define AUX4_LS_DONE_INTERRUPT (1 << 12)
|
||||
# define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 13)
|
||||
# define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 14)
|
||||
/* DCE 3.2 */
|
||||
# define AUX5_SW_DONE_INTERRUPT (1 << 15)
|
||||
# define AUX5_LS_DONE_INTERRUPT (1 << 16)
|
||||
# define AUX6_SW_DONE_INTERRUPT (1 << 17)
|
||||
# define AUX6_LS_DONE_INTERRUPT (1 << 18)
|
||||
# define DC_HPD5_INTERRUPT (1 << 19)
|
||||
# define DC_HPD5_RX_INTERRUPT (1 << 20)
|
||||
# define DC_HPD6_INTERRUPT (1 << 21)
|
||||
# define DC_HPD6_RX_INTERRUPT (1 << 22)
|
||||
|
||||
#define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038
|
||||
#define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138
|
||||
#define DACA_AUTODETECT_INT_CONTROL 0x7838
|
||||
#define DACB_AUTODETECT_INT_CONTROL 0x7a38
|
||||
# define DACx_AUTODETECT_ACK (1 << 0)
|
||||
# define DACx_AUTODETECT_INT_ENABLE (1 << 16)
|
||||
|
||||
#define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08
|
||||
#define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18
|
||||
#define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c
|
||||
# define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0)
|
||||
# define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8)
|
||||
# define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16)
|
||||
/* DCE 3.2 */
|
||||
#define DC_HPD1_INT_CONTROL 0x7d04
|
||||
#define DC_HPD2_INT_CONTROL 0x7d10
|
||||
#define DC_HPD3_INT_CONTROL 0x7d1c
|
||||
#define DC_HPD4_INT_CONTROL 0x7d28
|
||||
# define DC_HPDx_INT_ACK (1 << 0)
|
||||
# define DC_HPDx_INT_POLARITY (1 << 8)
|
||||
# define DC_HPDx_INT_EN (1 << 16)
|
||||
# define DC_HPDx_RX_INT_ACK (1 << 20)
|
||||
# define DC_HPDx_RX_INT_EN (1 << 24)
|
||||
|
||||
/*
|
||||
* PM4
|
||||
@ -500,7 +656,6 @@
|
||||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_INDIRECT_BUFFER 0x32
|
||||
#define PACKET3_CP_INTERRUPT 0x40
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
|
||||
# define PACKET3_TC_ACTION_ENA (1 << 23)
|
||||
@ -674,4 +829,5 @@
|
||||
#define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16)
|
||||
#define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17)
|
||||
|
||||
#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480
|
||||
#endif
|
||||
|
@ -28,8 +28,6 @@
|
||||
#ifndef __RADEON_H__
|
||||
#define __RADEON_H__
|
||||
|
||||
#include "radeon_object.h"
|
||||
|
||||
/* TODO: Here are things that needs to be done :
|
||||
* - surface allocator & initializer : (bit like scratch reg) should
|
||||
* initialize HDP_ stuff on RS600, R600, R700 hw, well anythings
|
||||
@ -67,6 +65,11 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
#include <ttm/ttm_bo_api.h>
|
||||
#include <ttm/ttm_bo_driver.h>
|
||||
#include <ttm/ttm_placement.h>
|
||||
#include <ttm/ttm_module.h>
|
||||
|
||||
#include "radeon_family.h"
|
||||
#include "radeon_mode.h"
|
||||
#include "radeon_reg.h"
|
||||
@ -186,76 +189,60 @@ void radeon_fence_unref(struct radeon_fence **fence);
|
||||
* Tiling registers
|
||||
*/
|
||||
struct radeon_surface_reg {
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *bo;
|
||||
};
|
||||
|
||||
#define RADEON_GEM_MAX_SURFACES 8
|
||||
|
||||
/*
|
||||
* Radeon buffer.
|
||||
* TTM.
|
||||
*/
|
||||
struct radeon_object;
|
||||
struct radeon_mman {
|
||||
struct ttm_bo_global_ref bo_global_ref;
|
||||
struct ttm_global_reference mem_global_ref;
|
||||
bool mem_global_referenced;
|
||||
struct ttm_bo_device bdev;
|
||||
};
|
||||
|
||||
struct radeon_object_list {
|
||||
struct radeon_bo {
|
||||
/* Protected by gem.mutex */
|
||||
struct list_head list;
|
||||
/* Protected by tbo.reserved */
|
||||
struct ttm_buffer_object tbo;
|
||||
struct ttm_bo_kmap_obj kmap;
|
||||
unsigned pin_count;
|
||||
void *kptr;
|
||||
u32 tiling_flags;
|
||||
u32 pitch;
|
||||
int surface_reg;
|
||||
/* Constant after initialization */
|
||||
struct radeon_device *rdev;
|
||||
struct drm_gem_object *gobj;
|
||||
};
|
||||
|
||||
struct radeon_bo_list {
|
||||
struct list_head list;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *bo;
|
||||
uint64_t gpu_offset;
|
||||
unsigned rdomain;
|
||||
unsigned wdomain;
|
||||
uint32_t tiling_flags;
|
||||
u32 tiling_flags;
|
||||
};
|
||||
|
||||
int radeon_object_init(struct radeon_device *rdev);
|
||||
void radeon_object_fini(struct radeon_device *rdev);
|
||||
int radeon_object_create(struct radeon_device *rdev,
|
||||
struct drm_gem_object *gobj,
|
||||
unsigned long size,
|
||||
bool kernel,
|
||||
uint32_t domain,
|
||||
bool interruptible,
|
||||
struct radeon_object **robj_ptr);
|
||||
int radeon_object_kmap(struct radeon_object *robj, void **ptr);
|
||||
void radeon_object_kunmap(struct radeon_object *robj);
|
||||
void radeon_object_unref(struct radeon_object **robj);
|
||||
int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
|
||||
uint64_t *gpu_addr);
|
||||
void radeon_object_unpin(struct radeon_object *robj);
|
||||
int radeon_object_wait(struct radeon_object *robj);
|
||||
int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement);
|
||||
int radeon_object_evict_vram(struct radeon_device *rdev);
|
||||
int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset);
|
||||
void radeon_object_force_delete(struct radeon_device *rdev);
|
||||
void radeon_object_list_add_object(struct radeon_object_list *lobj,
|
||||
struct list_head *head);
|
||||
int radeon_object_list_validate(struct list_head *head, void *fence);
|
||||
void radeon_object_list_unvalidate(struct list_head *head);
|
||||
void radeon_object_list_clean(struct list_head *head);
|
||||
int radeon_object_fbdev_mmap(struct radeon_object *robj,
|
||||
struct vm_area_struct *vma);
|
||||
unsigned long radeon_object_size(struct radeon_object *robj);
|
||||
void radeon_object_clear_surface_reg(struct radeon_object *robj);
|
||||
int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
|
||||
bool force_drop);
|
||||
void radeon_object_set_tiling_flags(struct radeon_object *robj,
|
||||
uint32_t tiling_flags, uint32_t pitch);
|
||||
void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch);
|
||||
void radeon_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
struct ttm_mem_reg *mem);
|
||||
void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
|
||||
/*
|
||||
* GEM objects.
|
||||
*/
|
||||
struct radeon_gem {
|
||||
struct mutex mutex;
|
||||
struct list_head objects;
|
||||
};
|
||||
|
||||
int radeon_gem_init(struct radeon_device *rdev);
|
||||
void radeon_gem_fini(struct radeon_device *rdev);
|
||||
int radeon_gem_object_create(struct radeon_device *rdev, int size,
|
||||
int alignment, int initial_domain,
|
||||
bool discardable, bool kernel,
|
||||
bool interruptible,
|
||||
struct drm_gem_object **obj);
|
||||
int alignment, int initial_domain,
|
||||
bool discardable, bool kernel,
|
||||
struct drm_gem_object **obj);
|
||||
int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
|
||||
uint64_t *gpu_addr);
|
||||
void radeon_gem_object_unpin(struct drm_gem_object *obj);
|
||||
@ -271,7 +258,7 @@ struct radeon_gart_table_ram {
|
||||
};
|
||||
|
||||
struct radeon_gart_table_vram {
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
volatile uint32_t *ptr;
|
||||
};
|
||||
|
||||
@ -352,11 +339,14 @@ struct radeon_irq {
|
||||
bool sw_int;
|
||||
/* FIXME: use a define max crtc rather than hardcode it */
|
||||
bool crtc_vblank_int[2];
|
||||
spinlock_t sw_lock;
|
||||
int sw_refcount;
|
||||
};
|
||||
|
||||
int radeon_irq_kms_init(struct radeon_device *rdev);
|
||||
void radeon_irq_kms_fini(struct radeon_device *rdev);
|
||||
|
||||
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev);
|
||||
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* CP & ring.
|
||||
@ -376,7 +366,7 @@ struct radeon_ib {
|
||||
*/
|
||||
struct radeon_ib_pool {
|
||||
struct mutex mutex;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
struct list_head scheduled_ibs;
|
||||
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
|
||||
bool ready;
|
||||
@ -384,7 +374,7 @@ struct radeon_ib_pool {
|
||||
};
|
||||
|
||||
struct radeon_cp {
|
||||
struct radeon_object *ring_obj;
|
||||
struct radeon_bo *ring_obj;
|
||||
volatile uint32_t *ring;
|
||||
unsigned rptr;
|
||||
unsigned wptr;
|
||||
@ -399,8 +389,25 @@ struct radeon_cp {
|
||||
bool ready;
|
||||
};
|
||||
|
||||
/*
|
||||
* R6xx+ IH ring
|
||||
*/
|
||||
struct r600_ih {
|
||||
struct radeon_bo *ring_obj;
|
||||
volatile uint32_t *ring;
|
||||
unsigned rptr;
|
||||
unsigned wptr;
|
||||
unsigned wptr_old;
|
||||
unsigned ring_size;
|
||||
uint64_t gpu_addr;
|
||||
uint32_t align_mask;
|
||||
uint32_t ptr_mask;
|
||||
spinlock_t lock;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct r600_blit {
|
||||
struct radeon_object *shader_obj;
|
||||
struct radeon_bo *shader_obj;
|
||||
u64 shader_gpu_addr;
|
||||
u32 vs_offset, ps_offset;
|
||||
u32 state_offset;
|
||||
@ -430,8 +437,8 @@ void radeon_ring_fini(struct radeon_device *rdev);
|
||||
*/
|
||||
struct radeon_cs_reloc {
|
||||
struct drm_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_object_list lobj;
|
||||
struct radeon_bo *robj;
|
||||
struct radeon_bo_list lobj;
|
||||
uint32_t handle;
|
||||
uint32_t flags;
|
||||
};
|
||||
@ -527,7 +534,7 @@ void radeon_agp_fini(struct radeon_device *rdev);
|
||||
* Writeback
|
||||
*/
|
||||
struct radeon_wb {
|
||||
struct radeon_object *wb_obj;
|
||||
struct radeon_bo *wb_obj;
|
||||
volatile uint32_t *wb;
|
||||
uint64_t gpu_addr;
|
||||
};
|
||||
@ -639,6 +646,7 @@ struct radeon_asic {
|
||||
uint32_t offset, uint32_t obj_size);
|
||||
int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
|
||||
void (*bandwidth_update)(struct radeon_device *rdev);
|
||||
void (*hdp_flush)(struct radeon_device *rdev);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -751,9 +759,9 @@ struct radeon_device {
|
||||
uint8_t *bios;
|
||||
bool is_atom_bios;
|
||||
uint16_t bios_header_start;
|
||||
struct radeon_object *stollen_vga_memory;
|
||||
struct radeon_bo *stollen_vga_memory;
|
||||
struct fb_info *fbdev_info;
|
||||
struct radeon_object *fbdev_robj;
|
||||
struct radeon_bo *fbdev_rbo;
|
||||
struct radeon_framebuffer *fbdev_rfb;
|
||||
/* Register mmio */
|
||||
resource_size_t rmmio_base;
|
||||
@ -791,8 +799,10 @@ struct radeon_device {
|
||||
struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
|
||||
const struct firmware *me_fw; /* all family ME firmware */
|
||||
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
|
||||
const struct firmware *rlc_fw; /* r6/700 RLC firmware */
|
||||
struct r600_blit r600_blit;
|
||||
int msi_enabled; /* msi enabled */
|
||||
struct r600_ih ih; /* r6/700 interrupt ring */
|
||||
};
|
||||
|
||||
int radeon_device_init(struct radeon_device *rdev,
|
||||
@ -829,6 +839,10 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cast helper
|
||||
*/
|
||||
#define to_radeon_fence(p) ((struct radeon_fence *)(p))
|
||||
|
||||
/*
|
||||
* Registers read & write functions.
|
||||
@ -965,18 +979,20 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
|
||||
#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
|
||||
#define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
|
||||
#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
|
||||
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
|
||||
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e))
|
||||
#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
|
||||
#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
|
||||
#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
|
||||
#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
|
||||
#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
|
||||
#define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev))
|
||||
|
||||
/* Common functions */
|
||||
extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
|
||||
extern int radeon_modeset_init(struct radeon_device *rdev);
|
||||
extern void radeon_modeset_fini(struct radeon_device *rdev);
|
||||
extern bool radeon_card_posted(struct radeon_device *rdev);
|
||||
extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
|
||||
extern int radeon_clocks_init(struct radeon_device *rdev);
|
||||
extern void radeon_clocks_fini(struct radeon_device *rdev);
|
||||
extern void radeon_scratch_init(struct radeon_device *rdev);
|
||||
@ -1021,7 +1037,7 @@ extern int r100_cp_reset(struct radeon_device *rdev);
|
||||
extern void r100_vga_render_disable(struct radeon_device *rdev);
|
||||
extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
struct radeon_object *robj);
|
||||
struct radeon_bo *robj);
|
||||
extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
const unsigned *auth, unsigned n,
|
||||
@ -1029,6 +1045,8 @@ extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
|
||||
extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx);
|
||||
extern void r100_enable_bm(struct radeon_device *rdev);
|
||||
extern void r100_set_common_regs(struct radeon_device *rdev);
|
||||
|
||||
/* rv200,rv250,rv280 */
|
||||
extern void r200_set_safe_registers(struct radeon_device *rdev);
|
||||
@ -1104,7 +1122,14 @@ extern void r600_wb_disable(struct radeon_device *rdev);
|
||||
extern void r600_scratch_init(struct radeon_device *rdev);
|
||||
extern int r600_blit_init(struct radeon_device *rdev);
|
||||
extern void r600_blit_fini(struct radeon_device *rdev);
|
||||
extern int r600_cp_init_microcode(struct radeon_device *rdev);
|
||||
extern int r600_init_microcode(struct radeon_device *rdev);
|
||||
extern int r600_gpu_reset(struct radeon_device *rdev);
|
||||
/* r600 irq */
|
||||
extern int r600_irq_init(struct radeon_device *rdev);
|
||||
extern void r600_irq_fini(struct radeon_device *rdev);
|
||||
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
|
||||
extern int r600_irq_set(struct radeon_device *rdev);
|
||||
|
||||
#include "radeon_object.h"
|
||||
|
||||
#endif
|
||||
|
@ -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_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
|
||||
int r100_ring_test(struct radeon_device *rdev);
|
||||
void r100_hdp_flush(struct radeon_device *rdev);
|
||||
|
||||
static struct radeon_asic r100_asic = {
|
||||
.init = &r100_init,
|
||||
@ -107,6 +108,7 @@ static struct radeon_asic r100_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &r100_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -162,6 +164,7 @@ static struct radeon_asic r300_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &r100_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -201,6 +204,7 @@ static struct radeon_asic r420_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &r100_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -245,6 +249,7 @@ static struct radeon_asic rs400_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &r100_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -291,6 +296,7 @@ static struct radeon_asic rs600_asic = {
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = &radeon_atom_set_clock_gating,
|
||||
.bandwidth_update = &rs600_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -334,6 +340,7 @@ static struct radeon_asic rs690_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &rs690_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -381,6 +388,7 @@ static struct radeon_asic rv515_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
|
||||
@ -419,6 +427,7 @@ static struct radeon_asic r520_asic = {
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
.hdp_flush = &r100_hdp_flush,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -455,6 +464,7 @@ int r600_ring_test(struct radeon_device *rdev);
|
||||
int r600_copy_blit(struct radeon_device *rdev,
|
||||
uint64_t src_offset, uint64_t dst_offset,
|
||||
unsigned num_pages, struct radeon_fence *fence);
|
||||
void r600_hdp_flush(struct radeon_device *rdev);
|
||||
|
||||
static struct radeon_asic r600_asic = {
|
||||
.init = &r600_init,
|
||||
@ -470,6 +480,7 @@ static struct radeon_asic r600_asic = {
|
||||
.ring_ib_execute = &r600_ring_ib_execute,
|
||||
.irq_set = &r600_irq_set,
|
||||
.irq_process = &r600_irq_process,
|
||||
.get_vblank_counter = &rs600_get_vblank_counter,
|
||||
.fence_ring_emit = &r600_fence_ring_emit,
|
||||
.cs_parse = &r600_cs_parse,
|
||||
.copy_blit = &r600_copy_blit,
|
||||
@ -484,6 +495,7 @@ static struct radeon_asic r600_asic = {
|
||||
.set_surface_reg = r600_set_surface_reg,
|
||||
.clear_surface_reg = r600_clear_surface_reg,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
.hdp_flush = &r600_hdp_flush,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -509,6 +521,7 @@ static struct radeon_asic rv770_asic = {
|
||||
.ring_ib_execute = &r600_ring_ib_execute,
|
||||
.irq_set = &r600_irq_set,
|
||||
.irq_process = &r600_irq_process,
|
||||
.get_vblank_counter = &rs600_get_vblank_counter,
|
||||
.fence_ring_emit = &r600_fence_ring_emit,
|
||||
.cs_parse = &r600_cs_parse,
|
||||
.copy_blit = &r600_copy_blit,
|
||||
@ -523,6 +536,7 @@ static struct radeon_asic rv770_asic = {
|
||||
.set_surface_reg = r600_set_surface_reg,
|
||||
.clear_surface_reg = r600_clear_surface_reg,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
.hdp_flush = &r600_hdp_flush,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
|
||||
i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
|
||||
i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
|
||||
i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
|
||||
i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
|
||||
i2c.en_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
|
||||
i2c.en_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
|
||||
i2c.y_clk_reg = le16_to_cpu(gpio.usClkY_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_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
|
||||
i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
|
||||
i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
|
||||
i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
|
||||
i2c.put_data_mask = (1 << gpio.ucDataEnShift);
|
||||
i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
|
||||
i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
|
||||
i2c.en_clk_mask = (1 << gpio.ucClkEnShift);
|
||||
i2c.en_data_mask = (1 << gpio.ucDataEnShift);
|
||||
i2c.y_clk_mask = (1 << gpio.ucClkY_Shift);
|
||||
i2c.y_data_mask = (1 << gpio.ucDataY_Shift);
|
||||
i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
|
||||
i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
|
||||
i2c.valid = true;
|
||||
@ -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 */
|
||||
if ((dev->pdev->device == 0x71C5) &&
|
||||
(dev->pdev->subsystem_vendor == 0x106b) &&
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -901,7 +927,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
|
||||
uint16_t data_offset;
|
||||
uint16_t data_offset, misc;
|
||||
union lvds_info *lvds_info;
|
||||
uint8_t frev, crev;
|
||||
struct radeon_encoder_atom_dig *lvds = NULL;
|
||||
@ -940,6 +966,19 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
|
||||
lvds->panel_pwr_delay =
|
||||
le16_to_cpu(lvds_info->info.usOffDelayInMs);
|
||||
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 */
|
||||
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
|
||||
|
||||
|
@ -29,8 +29,8 @@
|
||||
void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
|
||||
unsigned sdomain, unsigned ddomain)
|
||||
{
|
||||
struct radeon_object *dobj = NULL;
|
||||
struct radeon_object *sobj = NULL;
|
||||
struct radeon_bo *dobj = NULL;
|
||||
struct radeon_bo *sobj = NULL;
|
||||
struct radeon_fence *fence = NULL;
|
||||
uint64_t saddr, daddr;
|
||||
unsigned long start_jiffies;
|
||||
@ -41,19 +41,27 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
|
||||
|
||||
size = bsize;
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
@ -109,12 +117,20 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
|
||||
}
|
||||
out_cleanup:
|
||||
if (sobj) {
|
||||
radeon_object_unpin(sobj);
|
||||
radeon_object_unref(&sobj);
|
||||
r = radeon_bo_reserve(sobj, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_unpin(sobj);
|
||||
radeon_bo_unreserve(sobj);
|
||||
}
|
||||
radeon_bo_unref(&sobj);
|
||||
}
|
||||
if (dobj) {
|
||||
radeon_object_unpin(dobj);
|
||||
radeon_object_unref(&dobj);
|
||||
r = radeon_bo_reserve(dobj, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_unpin(dobj);
|
||||
radeon_bo_unreserve(dobj);
|
||||
}
|
||||
radeon_bo_unref(&dobj);
|
||||
}
|
||||
if (fence) {
|
||||
radeon_fence_unref(&fence);
|
||||
|
@ -44,6 +44,10 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
|
||||
|
||||
ref_div =
|
||||
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;
|
||||
|
||||
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)
|
||||
|
||||
ref_div =
|
||||
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;
|
||||
|
||||
post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
|
||||
@ -98,8 +106,19 @@ void radeon_get_clock_info(struct drm_device *dev)
|
||||
ret = radeon_combios_get_clock_info(dev);
|
||||
|
||||
if (ret) {
|
||||
if (p1pll->reference_div < 2)
|
||||
p1pll->reference_div = 12;
|
||||
if (p1pll->reference_div < 2) {
|
||||
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)
|
||||
p2pll->reference_div = 12;
|
||||
if (rdev->family < CHIP_RS600) {
|
||||
|
@ -450,29 +450,29 @@ struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
|
||||
i2c.mask_data_mask = RADEON_GPIO_EN_0;
|
||||
i2c.a_clk_mask = RADEON_GPIO_A_1;
|
||||
i2c.a_data_mask = RADEON_GPIO_A_0;
|
||||
i2c.put_clk_mask = RADEON_GPIO_EN_1;
|
||||
i2c.put_data_mask = RADEON_GPIO_EN_0;
|
||||
i2c.get_clk_mask = RADEON_GPIO_Y_1;
|
||||
i2c.get_data_mask = RADEON_GPIO_Y_0;
|
||||
i2c.en_clk_mask = RADEON_GPIO_EN_1;
|
||||
i2c.en_data_mask = RADEON_GPIO_EN_0;
|
||||
i2c.y_clk_mask = RADEON_GPIO_Y_1;
|
||||
i2c.y_data_mask = RADEON_GPIO_Y_0;
|
||||
if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
|
||||
(ddc_line == RADEON_MDGPIO_EN_REG)) {
|
||||
i2c.mask_clk_reg = ddc_line;
|
||||
i2c.mask_data_reg = ddc_line;
|
||||
i2c.a_clk_reg = ddc_line;
|
||||
i2c.a_data_reg = ddc_line;
|
||||
i2c.put_clk_reg = ddc_line;
|
||||
i2c.put_data_reg = ddc_line;
|
||||
i2c.get_clk_reg = ddc_line + 4;
|
||||
i2c.get_data_reg = ddc_line + 4;
|
||||
i2c.en_clk_reg = ddc_line;
|
||||
i2c.en_data_reg = ddc_line;
|
||||
i2c.y_clk_reg = ddc_line + 4;
|
||||
i2c.y_data_reg = ddc_line + 4;
|
||||
} else {
|
||||
i2c.mask_clk_reg = ddc_line;
|
||||
i2c.mask_data_reg = ddc_line;
|
||||
i2c.a_clk_reg = ddc_line;
|
||||
i2c.a_data_reg = ddc_line;
|
||||
i2c.put_clk_reg = ddc_line;
|
||||
i2c.put_data_reg = ddc_line;
|
||||
i2c.get_clk_reg = ddc_line;
|
||||
i2c.get_data_reg = ddc_line;
|
||||
i2c.en_clk_reg = ddc_line;
|
||||
i2c.en_data_reg = ddc_line;
|
||||
i2c.y_clk_reg = ddc_line;
|
||||
i2c.y_data_reg = ddc_line;
|
||||
}
|
||||
|
||||
if (ddc_line)
|
||||
@ -495,7 +495,7 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||
uint16_t sclk, mclk;
|
||||
|
||||
if (rdev->bios == NULL)
|
||||
return NULL;
|
||||
return false;
|
||||
|
||||
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
|
||||
if (pll_info) {
|
||||
@ -993,8 +993,8 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
|
||||
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
|
||||
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
|
||||
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
|
||||
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS400 */
|
||||
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */
|
||||
{ {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
|
||||
{ {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
|
||||
};
|
||||
|
||||
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
|
||||
@ -1028,7 +1028,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
|
||||
tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
|
||||
|
||||
if (tmds_info) {
|
||||
|
||||
ver = RBIOS8(tmds_info);
|
||||
DRM_INFO("DFP table revision: %d\n", ver);
|
||||
if (ver == 3) {
|
||||
@ -1063,45 +1062,132 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
|
||||
tmds->tmds_pll[i].value);
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
DRM_INFO("No TMDS info found in BIOS\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
|
||||
{
|
||||
struct radeon_encoder_int_tmds *tmds = NULL;
|
||||
bool ret;
|
||||
|
||||
tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
|
||||
|
||||
if (!tmds)
|
||||
return NULL;
|
||||
|
||||
ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
|
||||
if (ret == false)
|
||||
radeon_legacy_get_tmds_info_from_table(encoder, tmds);
|
||||
|
||||
return tmds;
|
||||
}
|
||||
|
||||
void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder)
|
||||
bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_ext_tmds *tmds)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
uint16_t ext_tmds_info;
|
||||
uint8_t ver;
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
|
||||
/* default for macs */
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
|
||||
/* XXX some macs have duallink chips */
|
||||
switch (rdev->mode_info.connector_table) {
|
||||
case CT_POWERBOOK_EXTERNAL:
|
||||
case CT_MINI_EXTERNAL:
|
||||
default:
|
||||
tmds->dvo_chip = DVO_SIL164;
|
||||
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_ext_tmds *tmds)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
uint16_t offset;
|
||||
uint8_t ver, id, blocks, clk, data;
|
||||
int i;
|
||||
enum radeon_combios_ddc gpio;
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
|
||||
if (rdev->bios == NULL)
|
||||
return;
|
||||
return false;
|
||||
|
||||
ext_tmds_info =
|
||||
combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
|
||||
if (ext_tmds_info) {
|
||||
ver = RBIOS8(ext_tmds_info);
|
||||
DRM_INFO("External TMDS Table revision: %d\n", ver);
|
||||
// TODO
|
||||
tmds->i2c_bus = NULL;
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
|
||||
if (offset) {
|
||||
ver = RBIOS8(offset);
|
||||
DRM_INFO("GPIO Table revision: %d\n", ver);
|
||||
blocks = RBIOS8(offset + 2);
|
||||
for (i = 0; i < blocks; i++) {
|
||||
id = RBIOS8(offset + 3 + (i * 5) + 0);
|
||||
if (id == 136) {
|
||||
clk = RBIOS8(offset + 3 + (i * 5) + 3);
|
||||
data = RBIOS8(offset + 3 + (i * 5) + 4);
|
||||
i2c_bus.valid = true;
|
||||
i2c_bus.mask_clk_mask = (1 << clk);
|
||||
i2c_bus.mask_data_mask = (1 << data);
|
||||
i2c_bus.a_clk_mask = (1 << clk);
|
||||
i2c_bus.a_data_mask = (1 << data);
|
||||
i2c_bus.en_clk_mask = (1 << clk);
|
||||
i2c_bus.en_data_mask = (1 << data);
|
||||
i2c_bus.y_clk_mask = (1 << clk);
|
||||
i2c_bus.y_data_mask = (1 << data);
|
||||
i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
|
||||
i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
|
||||
i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
|
||||
i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
|
||||
i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
|
||||
i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
|
||||
i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
|
||||
i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
tmds->dvo_chip = DVO_SIL164;
|
||||
tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
|
||||
if (offset) {
|
||||
ver = RBIOS8(offset);
|
||||
DRM_INFO("External TMDS Table revision: %d\n", ver);
|
||||
tmds->slave_addr = RBIOS8(offset + 4 + 2);
|
||||
tmds->slave_addr >>= 1; /* 7 bit addressing */
|
||||
gpio = RBIOS8(offset + 4 + 3);
|
||||
switch (gpio) {
|
||||
case DDC_MONID:
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
break;
|
||||
case DDC_DVI:
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
break;
|
||||
case DDC_VGA:
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
break;
|
||||
case DDC_CRT2:
|
||||
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
|
||||
if (rdev->family >= CHIP_R300)
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||
else
|
||||
i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
|
||||
tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
|
||||
break;
|
||||
case DDC_LCD: /* MM i2c */
|
||||
DRM_ERROR("MM i2c requires hw i2c engine\n");
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported gpio %d\n", gpio);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tmds->i2c_bus) {
|
||||
DRM_INFO("No valid Ext TMDS info found in BIOS\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
|
||||
@ -1567,20 +1653,25 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
|
||||
ddc_i2c->mask_data_mask = 0x80;
|
||||
ddc_i2c->a_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->a_data_mask = 0x80;
|
||||
ddc_i2c->put_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->put_data_mask = 0x80;
|
||||
ddc_i2c->get_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->get_data_mask = 0x80;
|
||||
ddc_i2c->en_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->en_data_mask = 0x80;
|
||||
ddc_i2c->y_clk_mask = (0x20 << 8);
|
||||
ddc_i2c->y_data_mask = 0x80;
|
||||
ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK;
|
||||
ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK;
|
||||
ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A;
|
||||
ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
|
||||
ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN;
|
||||
ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN;
|
||||
ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG;
|
||||
ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG;
|
||||
ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN;
|
||||
ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN;
|
||||
ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y;
|
||||
ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y;
|
||||
}
|
||||
|
||||
/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
|
||||
if ((rdev->family >= CHIP_R300) &&
|
||||
ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
|
||||
*ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||
|
||||
/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
|
||||
one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
|
||||
if (dev->pdev->device == 0x515e &&
|
||||
@ -1624,6 +1715,12 @@ static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
|
||||
dev->pdev->subsystem_device == 0x280a)
|
||||
return false;
|
||||
|
||||
/* MSI S270 has non-existent TV port */
|
||||
if (dev->pdev->device == 0x5955 &&
|
||||
dev->pdev->subsystem_vendor == 0x1462 &&
|
||||
dev->pdev->subsystem_device == 0x0131)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1939,13 +2036,13 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.a_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.put_clk_mask =
|
||||
ddc_i2c.en_clk_mask =
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.put_data_mask =
|
||||
ddc_i2c.en_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.get_clk_mask =
|
||||
ddc_i2c.y_clk_mask =
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.get_data_mask =
|
||||
ddc_i2c.y_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
break;
|
||||
case DDC_GPIO:
|
||||
@ -1960,13 +2057,13 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.a_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.put_clk_mask =
|
||||
ddc_i2c.en_clk_mask =
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.put_data_mask =
|
||||
ddc_i2c.en_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
ddc_i2c.get_clk_mask =
|
||||
ddc_i2c.y_clk_mask =
|
||||
RBIOS32(lcd_ddc_info + 3);
|
||||
ddc_i2c.get_data_mask =
|
||||
ddc_i2c.y_data_mask =
|
||||
RBIOS32(lcd_ddc_info + 7);
|
||||
break;
|
||||
default:
|
||||
@ -2014,6 +2111,193 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
void radeon_external_tmds_setup(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)
|
||||
return;
|
||||
|
||||
switch (tmds->dvo_chip) {
|
||||
case DVO_SIL164:
|
||||
/* sil 164 */
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 1);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
0x08, 0x30);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
0x09, 0x00);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
0x0a, 0x90);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
0x0c, 0x89);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
0x08, 0x3b);
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 0);
|
||||
break;
|
||||
case DVO_SIL1178:
|
||||
/* sil 1178 - untested */
|
||||
/*
|
||||
* 0x0f, 0x44
|
||||
* 0x0f, 0x4c
|
||||
* 0x0e, 0x01
|
||||
* 0x0a, 0x80
|
||||
* 0x09, 0x30
|
||||
* 0x0c, 0xc9
|
||||
* 0x0d, 0x70
|
||||
* 0x08, 0x32
|
||||
* 0x08, 0x33
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool radeon_combios_external_tmds_setup(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);
|
||||
uint16_t offset;
|
||||
uint8_t blocks, slave_addr, rev;
|
||||
uint32_t index, id;
|
||||
uint32_t reg, val, and_mask, or_mask;
|
||||
struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
|
||||
|
||||
if (rdev->bios == NULL)
|
||||
return false;
|
||||
|
||||
if (!tmds)
|
||||
return false;
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
|
||||
rev = RBIOS8(offset);
|
||||
if (offset) {
|
||||
rev = RBIOS8(offset);
|
||||
if (rev > 1) {
|
||||
blocks = RBIOS8(offset + 3);
|
||||
index = offset + 4;
|
||||
while (blocks > 0) {
|
||||
id = RBIOS16(index);
|
||||
index += 2;
|
||||
switch (id >> 13) {
|
||||
case 0:
|
||||
reg = (id & 0x1fff) * 4;
|
||||
val = RBIOS32(index);
|
||||
index += 4;
|
||||
WREG32(reg, val);
|
||||
break;
|
||||
case 2:
|
||||
reg = (id & 0x1fff) * 4;
|
||||
and_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
or_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
val = RREG32(reg);
|
||||
val = (val & and_mask) | or_mask;
|
||||
WREG32(reg, val);
|
||||
break;
|
||||
case 3:
|
||||
val = RBIOS16(index);
|
||||
index += 2;
|
||||
udelay(val);
|
||||
break;
|
||||
case 4:
|
||||
val = RBIOS16(index);
|
||||
index += 2;
|
||||
udelay(val * 1000);
|
||||
break;
|
||||
case 6:
|
||||
slave_addr = id & 0xff;
|
||||
slave_addr >>= 1; /* 7 bit addressing */
|
||||
index++;
|
||||
reg = RBIOS8(index);
|
||||
index++;
|
||||
val = RBIOS8(index);
|
||||
index++;
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 1);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
slave_addr,
|
||||
reg, val);
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 0);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown id %d\n", id >> 13);
|
||||
break;
|
||||
}
|
||||
blocks--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
|
||||
if (offset) {
|
||||
index = offset + 10;
|
||||
id = RBIOS16(index);
|
||||
while (id != 0xffff) {
|
||||
index += 2;
|
||||
switch (id >> 13) {
|
||||
case 0:
|
||||
reg = (id & 0x1fff) * 4;
|
||||
val = RBIOS32(index);
|
||||
WREG32(reg, val);
|
||||
break;
|
||||
case 2:
|
||||
reg = (id & 0x1fff) * 4;
|
||||
and_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
or_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
val = RREG32(reg);
|
||||
val = (val & and_mask) | or_mask;
|
||||
WREG32(reg, val);
|
||||
break;
|
||||
case 4:
|
||||
val = RBIOS16(index);
|
||||
index += 2;
|
||||
udelay(val);
|
||||
break;
|
||||
case 5:
|
||||
reg = id & 0x1fff;
|
||||
and_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
or_mask = RBIOS32(index);
|
||||
index += 4;
|
||||
val = RREG32_PLL(reg);
|
||||
val = (val & and_mask) | or_mask;
|
||||
WREG32_PLL(reg, val);
|
||||
break;
|
||||
case 6:
|
||||
reg = id & 0x1fff;
|
||||
val = RBIOS8(index);
|
||||
index += 1;
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 1);
|
||||
radeon_i2c_sw_put_byte(tmds->i2c_bus,
|
||||
tmds->slave_addr,
|
||||
reg, val);
|
||||
radeon_i2c_do_lock(tmds->i2c_bus, 0);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown id %d\n", id >> 13);
|
||||
break;
|
||||
}
|
||||
id = RBIOS16(index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -445,10 +445,10 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec
|
||||
ret = connector_status_connected;
|
||||
else {
|
||||
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->ddc_bus->adapter);
|
||||
radeon_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
if (radeon_connector->edid)
|
||||
ret = connector_status_connected;
|
||||
}
|
||||
@ -553,17 +553,17 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
|
||||
if (!encoder)
|
||||
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);
|
||||
radeon_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
if (dret) {
|
||||
if (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
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_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
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
|
||||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
bool dret;
|
||||
|
||||
radeon_i2c_do_lock(radeon_connector, 1);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
|
||||
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 (radeon_connector->edid) {
|
||||
kfree(radeon_connector->edid);
|
||||
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_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
|
||||
if (!radeon_connector->edid) {
|
||||
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
|
||||
ret = connector_status_disconnected;
|
||||
} else
|
||||
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,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
1);
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
@ -1160,6 +1196,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
1);
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
|
@ -76,17 +76,17 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
|
||||
}
|
||||
p->relocs_ptr[i] = &p->relocs[i];
|
||||
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.wdomain = r->write_domain;
|
||||
p->relocs[i].handle = r->handle;
|
||||
p->relocs[i].flags = r->flags;
|
||||
INIT_LIST_HEAD(&p->relocs[i].lobj.list);
|
||||
radeon_object_list_add_object(&p->relocs[i].lobj,
|
||||
&p->validated);
|
||||
radeon_bo_list_add_object(&p->relocs[i].lobj,
|
||||
&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)
|
||||
@ -190,9 +190,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
|
||||
unsigned i;
|
||||
|
||||
if (error) {
|
||||
radeon_object_list_unvalidate(&parser->validated);
|
||||
radeon_bo_list_unvalidate(&parser->validated,
|
||||
parser->ib->fence);
|
||||
} else {
|
||||
radeon_object_list_clean(&parser->validated);
|
||||
radeon_bo_list_unreserve(&parser->validated);
|
||||
}
|
||||
for (i = 0; i < parser->nrelocs; i++) {
|
||||
if (parser->relocs[i].gobj) {
|
||||
|
@ -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)
|
||||
{
|
||||
rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
|
||||
@ -544,6 +562,9 @@ int radeon_device_init(struct radeon_device *rdev,
|
||||
mutex_init(&rdev->cs_mutex);
|
||||
mutex_init(&rdev->ib_pool.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);
|
||||
INIT_LIST_HEAD(&rdev->gem.objects);
|
||||
|
||||
@ -553,7 +574,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
||||
return r;
|
||||
}
|
||||
|
||||
if (radeon_agpmode == -1) {
|
||||
if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
|
||||
radeon_agp_disable(rdev);
|
||||
}
|
||||
|
||||
@ -633,6 +654,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
int r;
|
||||
|
||||
if (dev == NULL || rdev == NULL) {
|
||||
return -ENODEV;
|
||||
@ -643,18 +665,22 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
|
||||
/* unpin the front buffers */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
|
||||
if (rfb == NULL || rfb->obj == NULL) {
|
||||
continue;
|
||||
}
|
||||
robj = rfb->obj->driver_private;
|
||||
if (robj != rdev->fbdev_robj) {
|
||||
radeon_object_unpin(robj);
|
||||
if (robj != rdev->fbdev_rbo) {
|
||||
r = radeon_bo_reserve(robj, false);
|
||||
if (unlikely(r == 0)) {
|
||||
radeon_bo_unpin(robj);
|
||||
radeon_bo_unreserve(robj);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* evict vram memory */
|
||||
radeon_object_evict_vram(rdev);
|
||||
radeon_bo_evict_vram(rdev);
|
||||
/* wait for gpu to finish processing current batch */
|
||||
radeon_fence_wait_last(rdev);
|
||||
|
||||
@ -662,7 +688,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
|
||||
|
||||
radeon_suspend(rdev);
|
||||
/* evict remaining vram memory */
|
||||
radeon_object_evict_vram(rdev);
|
||||
radeon_bo_evict_vram(rdev);
|
||||
|
||||
pci_save_state(dev->pdev);
|
||||
if (state.event == PM_EVENT_SUSPEND) {
|
||||
|
@ -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.a_clk_reg,
|
||||
radeon_connector->ddc_bus->rec.a_data_reg,
|
||||
radeon_connector->ddc_bus->rec.put_clk_reg,
|
||||
radeon_connector->ddc_bus->rec.put_data_reg,
|
||||
radeon_connector->ddc_bus->rec.get_clk_reg,
|
||||
radeon_connector->ddc_bus->rec.get_data_reg);
|
||||
radeon_connector->ddc_bus->rec.en_clk_reg,
|
||||
radeon_connector->ddc_bus->rec.en_data_reg,
|
||||
radeon_connector->ddc_bus->rec.y_clk_reg,
|
||||
radeon_connector->ddc_bus->rec.y_data_reg);
|
||||
DRM_INFO(" Encoders:\n");
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
@ -324,6 +324,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
|
||||
ret = radeon_get_legacy_connector_info_from_table(dev);
|
||||
}
|
||||
if (ret) {
|
||||
radeon_setup_encoder_clones(dev);
|
||||
radeon_print_display_setup(dev);
|
||||
list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
|
||||
radeon_ddc_dump(drm_connector);
|
||||
@ -339,9 +340,9 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
|
||||
if (!radeon_connector->ddc_bus)
|
||||
return -1;
|
||||
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_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
}
|
||||
|
||||
if (radeon_connector->edid) {
|
||||
@ -361,9 +362,9 @@ static int radeon_ddc_dump(struct drm_connector *connector)
|
||||
|
||||
if (!radeon_connector->ddc_bus)
|
||||
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);
|
||||
radeon_i2c_do_lock(radeon_connector, 0);
|
||||
radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
|
||||
if (edid) {
|
||||
kfree(edid);
|
||||
}
|
||||
@ -750,9 +751,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
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,
|
||||
&radeon_encoder->native_mode,
|
||||
&radeon_encoder->native_mode,
|
||||
sizeof(struct drm_display_mode));
|
||||
first = false;
|
||||
} else {
|
||||
|
@ -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_MEM_WRITE 0x00003D00
|
||||
# define R600_IT_INDIRECT_BUFFER 0x00003200
|
||||
# define R600_IT_CP_INTERRUPT 0x00004000
|
||||
# define R600_IT_SURFACE_SYNC 0x00004300
|
||||
# define R600_CB0_DEST_BASE_ENA (1 << 6)
|
||||
# define R600_TC_ACTION_ENA (1 << 23)
|
||||
|
@ -35,6 +35,51 @@ extern int atom_debug;
|
||||
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
|
||||
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
|
||||
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)
|
||||
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,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
@ -198,14 +220,24 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
|
||||
radeon_encoder_set_active_device(encoder);
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
|
||||
if (radeon_encoder->rmx_type != RMX_OFF)
|
||||
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
|
||||
|
||||
/* hw bug */
|
||||
if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
&& (mode->crtc_vsync_start < (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)) {
|
||||
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
|
||||
if (tv_dac) {
|
||||
@ -392,7 +424,7 @@ union lvds_encoder_control {
|
||||
LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
|
||||
};
|
||||
|
||||
static void
|
||||
void
|
||||
atombios_digital_setup(struct drm_encoder *encoder, int action)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
@ -918,12 +950,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
if (is_dig) {
|
||||
switch (mode) {
|
||||
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;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
@ -1354,7 +1386,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
|
||||
encoder->possible_crtcs = 0x1;
|
||||
else
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
|
||||
radeon_encoder->enc_priv = NULL;
|
||||
|
||||
|
@ -140,7 +140,7 @@ int radeonfb_create(struct drm_device *dev,
|
||||
struct radeon_framebuffer *rfb;
|
||||
struct drm_mode_fb_cmd mode_cmd;
|
||||
struct drm_gem_object *gobj = NULL;
|
||||
struct radeon_object *robj = NULL;
|
||||
struct radeon_bo *rbo = NULL;
|
||||
struct device *device = &rdev->pdev->dev;
|
||||
int size, aligned_size, ret;
|
||||
u64 fb_gpuaddr;
|
||||
@ -168,14 +168,14 @@ int radeonfb_create(struct drm_device *dev,
|
||||
ret = radeon_gem_object_create(rdev, aligned_size, 0,
|
||||
RADEON_GEM_DOMAIN_VRAM,
|
||||
false, ttm_bo_type_kernel,
|
||||
false, &gobj);
|
||||
&gobj);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
|
||||
surface_width, surface_height);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
robj = gobj->driver_private;
|
||||
rbo = gobj->driver_private;
|
||||
|
||||
if (fb_tiled)
|
||||
tiling_flags = RADEON_TILING_MACRO;
|
||||
@ -192,8 +192,13 @@ int radeonfb_create(struct drm_device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tiling_flags)
|
||||
radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
|
||||
if (tiling_flags) {
|
||||
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);
|
||||
fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
|
||||
if (fb == NULL) {
|
||||
@ -201,10 +206,19 @@ int radeonfb_create(struct drm_device *dev,
|
||||
ret = -ENOMEM;
|
||||
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) {
|
||||
printk(KERN_ERR "failed to pin framebuffer\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
@ -213,7 +227,7 @@ int radeonfb_create(struct drm_device *dev,
|
||||
*fb_p = fb;
|
||||
rfb = to_radeon_framebuffer(fb);
|
||||
rdev->fbdev_rfb = rfb;
|
||||
rdev->fbdev_robj = robj;
|
||||
rdev->fbdev_rbo = rbo;
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
|
||||
if (info == NULL) {
|
||||
@ -234,15 +248,7 @@ int radeonfb_create(struct drm_device *dev,
|
||||
if (ret)
|
||||
goto out_unref;
|
||||
|
||||
if (fb_tiled)
|
||||
radeon_object_check_tiling(robj, 0, 0);
|
||||
|
||||
ret = radeon_object_kmap(robj, &fbptr);
|
||||
if (ret) {
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
memset_io(fbptr, 0, aligned_size);
|
||||
memset_io(fbptr, 0xff, aligned_size);
|
||||
|
||||
strcpy(info->fix.id, "radeondrmfb");
|
||||
|
||||
@ -288,8 +294,12 @@ int radeonfb_create(struct drm_device *dev,
|
||||
return 0;
|
||||
|
||||
out_unref:
|
||||
if (robj) {
|
||||
radeon_object_kunmap(robj);
|
||||
if (rbo) {
|
||||
ret = radeon_bo_reserve(rbo, false);
|
||||
if (likely(ret == 0)) {
|
||||
radeon_bo_kunmap(rbo);
|
||||
radeon_bo_unreserve(rbo);
|
||||
}
|
||||
}
|
||||
if (fb && ret) {
|
||||
list_del(&fb->filp_head);
|
||||
@ -321,14 +331,22 @@ int radeon_parse_options(char *options)
|
||||
|
||||
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)
|
||||
{
|
||||
struct fb_info *info;
|
||||
struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *rbo;
|
||||
int r;
|
||||
|
||||
if (!fb) {
|
||||
return -EINVAL;
|
||||
@ -336,10 +354,14 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
|
||||
info = fb->fbdev;
|
||||
if (info) {
|
||||
struct radeon_fb_device *rfbdev = info->par;
|
||||
robj = rfb->obj->driver_private;
|
||||
rbo = rfb->obj->driver_private;
|
||||
unregister_framebuffer(info);
|
||||
radeon_object_kunmap(robj);
|
||||
radeon_object_unpin(robj);
|
||||
r = radeon_bo_reserve(rbo, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_kunmap(rbo);
|
||||
radeon_bo_unpin(rbo);
|
||||
radeon_bo_unreserve(rbo);
|
||||
}
|
||||
drm_fb_helper_free(&rfbdev->helper);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
|
||||
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)
|
||||
{
|
||||
struct radeon_device *rdev;
|
||||
@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
r = r600_fence_wait(fence, intr, 0);
|
||||
if (r == -ERESTARTSYS)
|
||||
return -EBUSY;
|
||||
return r;
|
||||
}
|
||||
|
||||
retry:
|
||||
cur_jiffies = jiffies;
|
||||
timeout = HZ / 100;
|
||||
@ -231,14 +193,18 @@ retry:
|
||||
}
|
||||
|
||||
if (intr) {
|
||||
radeon_irq_kms_sw_irq_get(rdev);
|
||||
r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
|
||||
radeon_fence_signaled(fence), timeout);
|
||||
radeon_irq_kms_sw_irq_put(rdev);
|
||||
if (unlikely(r == -ERESTARTSYS)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
} else {
|
||||
radeon_irq_kms_sw_irq_get(rdev);
|
||||
r = wait_event_timeout(rdev->fence_drv.queue,
|
||||
radeon_fence_signaled(fence), timeout);
|
||||
radeon_irq_kms_sw_irq_put(rdev);
|
||||
}
|
||||
if (unlikely(!radeon_fence_signaled(fence))) {
|
||||
if (unlikely(r == 0)) {
|
||||
|
@ -78,11 +78,9 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
|
||||
int r;
|
||||
|
||||
if (rdev->gart.table.vram.robj == NULL) {
|
||||
r = radeon_object_create(rdev, NULL,
|
||||
rdev->gart.table_size,
|
||||
true,
|
||||
RADEON_GEM_DOMAIN_VRAM,
|
||||
false, &rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
|
||||
true, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->gart.table.vram.robj);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
@ -95,32 +93,38 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev)
|
||||
uint64_t gpu_addr;
|
||||
int r;
|
||||
|
||||
r = radeon_object_pin(rdev->gart.table.vram.robj,
|
||||
RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->gart.table.vram.robj,
|
||||
RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
|
||||
if (r) {
|
||||
radeon_object_unref(&rdev->gart.table.vram.robj);
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_kmap(rdev->gart.table.vram.robj,
|
||||
(void **)&rdev->gart.table.vram.ptr);
|
||||
if (r) {
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
radeon_object_unref(&rdev->gart.table.vram.robj);
|
||||
DRM_ERROR("radeon: failed to map gart vram table.\n");
|
||||
radeon_bo_unreserve(rdev->gart.table.vram.robj);
|
||||
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;
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void radeon_gart_table_vram_free(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->gart.table.vram.robj == NULL) {
|
||||
return;
|
||||
}
|
||||
radeon_object_kunmap(rdev->gart.table.vram.robj);
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
radeon_object_unref(&rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
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);
|
||||
}
|
||||
radeon_bo_unref(&rdev->gart.table.vram.robj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_gem_object *obj)
|
||||
|
||||
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;
|
||||
if (robj) {
|
||||
radeon_object_unref(&robj);
|
||||
radeon_bo_unref(&robj);
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_gem_object_create(struct radeon_device *rdev, int size,
|
||||
int alignment, int initial_domain,
|
||||
bool discardable, bool kernel,
|
||||
bool interruptible,
|
||||
struct drm_gem_object **obj)
|
||||
int alignment, int initial_domain,
|
||||
bool discardable, bool kernel,
|
||||
struct drm_gem_object **obj)
|
||||
{
|
||||
struct drm_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
int r;
|
||||
|
||||
*obj = NULL;
|
||||
@ -65,8 +64,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
|
||||
if (alignment < PAGE_SIZE) {
|
||||
alignment = PAGE_SIZE;
|
||||
}
|
||||
r = radeon_object_create(rdev, gobj, size, kernel, initial_domain,
|
||||
interruptible, &robj);
|
||||
r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
|
||||
size, initial_domain, alignment);
|
||||
@ -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,
|
||||
uint64_t *gpu_addr)
|
||||
{
|
||||
struct radeon_object *robj = obj->driver_private;
|
||||
uint32_t flags;
|
||||
struct radeon_bo *robj = obj->driver_private;
|
||||
int r;
|
||||
|
||||
switch (pin_domain) {
|
||||
case RADEON_GEM_DOMAIN_VRAM:
|
||||
flags = TTM_PL_FLAG_VRAM;
|
||||
break;
|
||||
case RADEON_GEM_DOMAIN_GTT:
|
||||
flags = TTM_PL_FLAG_TT;
|
||||
break;
|
||||
default:
|
||||
flags = TTM_PL_FLAG_SYSTEM;
|
||||
break;
|
||||
}
|
||||
return radeon_object_pin(robj, flags, gpu_addr);
|
||||
r = radeon_bo_reserve(robj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(robj, pin_domain, gpu_addr);
|
||||
radeon_bo_unreserve(robj);
|
||||
return r;
|
||||
}
|
||||
|
||||
void radeon_gem_object_unpin(struct drm_gem_object *obj)
|
||||
{
|
||||
struct radeon_object *robj = obj->driver_private;
|
||||
radeon_object_unpin(robj);
|
||||
struct radeon_bo *robj = obj->driver_private;
|
||||
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,
|
||||
uint32_t rdomain, uint32_t wdomain)
|
||||
{
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
uint32_t domain;
|
||||
int r;
|
||||
|
||||
@ -127,11 +125,12 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj,
|
||||
}
|
||||
if (domain == RADEON_GEM_DOMAIN_CPU) {
|
||||
/* Asking for cpu access wait for object idle */
|
||||
r = radeon_object_wait(robj);
|
||||
r = radeon_bo_wait(robj, NULL, false);
|
||||
if (r) {
|
||||
printk(KERN_ERR "Failed to wait for object !\n");
|
||||
return r;
|
||||
}
|
||||
radeon_hdp_flush(robj->rdev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -144,7 +143,7 @@ int radeon_gem_init(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,
|
||||
struct drm_radeon_gem_info *args = data;
|
||||
|
||||
args->vram_size = rdev->mc.real_vram_size;
|
||||
/* FIXME: report somethings that makes sense */
|
||||
args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024);
|
||||
args->gart_size = rdev->mc.gtt_size;
|
||||
args->vram_visible = rdev->mc.real_vram_size;
|
||||
if (rdev->stollen_vga_memory)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -192,8 +195,8 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
|
||||
/* create a gem object to contain this object in */
|
||||
args->size = roundup(args->size, PAGE_SIZE);
|
||||
r = radeon_gem_object_create(rdev, args->size, args->alignment,
|
||||
args->initial_domain, false,
|
||||
false, true, &gobj);
|
||||
args->initial_domain, false,
|
||||
false, &gobj);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
@ -218,7 +221,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
* just validate the BO into a certain domain */
|
||||
struct drm_radeon_gem_set_domain *args = data;
|
||||
struct drm_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
int r;
|
||||
|
||||
/* for now if someone requests domain CPU -
|
||||
@ -244,19 +247,18 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
struct drm_radeon_gem_mmap *args = data;
|
||||
struct drm_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
int r;
|
||||
struct radeon_bo *robj;
|
||||
|
||||
gobj = drm_gem_object_lookup(dev, filp, args->handle);
|
||||
if (gobj == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
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);
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
int r;
|
||||
uint32_t cur_placement;
|
||||
|
||||
@ -273,7 +275,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
robj = gobj->driver_private;
|
||||
r = radeon_object_busy_domain(robj, &cur_placement);
|
||||
r = radeon_bo_wait(robj, &cur_placement, true);
|
||||
switch (cur_placement) {
|
||||
case TTM_PL_VRAM:
|
||||
args->domain = RADEON_GEM_DOMAIN_VRAM;
|
||||
@ -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_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
int r;
|
||||
|
||||
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,
|
||||
return -EINVAL;
|
||||
}
|
||||
robj = gobj->driver_private;
|
||||
r = radeon_object_wait(robj);
|
||||
r = radeon_bo_wait(robj, NULL, false);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
radeon_hdp_flush(robj->rdev);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -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_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *robj;
|
||||
int r = 0;
|
||||
|
||||
DRM_DEBUG("%d \n", args->handle);
|
||||
@ -325,7 +328,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
if (gobj == NULL)
|
||||
return -EINVAL;
|
||||
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);
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
@ -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_gem_object *gobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *rbo;
|
||||
int r = 0;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
gobj = drm_gem_object_lookup(dev, filp, args->handle);
|
||||
if (gobj == NULL)
|
||||
return -EINVAL;
|
||||
robj = gobj->driver_private;
|
||||
radeon_object_get_tiling_flags(robj, &args->tiling_flags,
|
||||
&args->pitch);
|
||||
rbo = gobj->driver_private;
|
||||
r = radeon_bo_reserve(rbo, false);
|
||||
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);
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -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;
|
||||
struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
|
||||
|
||||
/* 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
|
||||
@ -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)));
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (lock_state)
|
||||
temp |= rec->mask_clk_mask;
|
||||
@ -112,8 +112,9 @@ static int get_clock(void *i2c_priv)
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RREG32(rec->get_clk_reg);
|
||||
val &= rec->get_clk_mask;
|
||||
/* read the value off the pin */
|
||||
val = RREG32(rec->y_clk_reg);
|
||||
val &= rec->y_clk_mask;
|
||||
|
||||
return (val != 0);
|
||||
}
|
||||
@ -126,8 +127,10 @@ static int get_data(void *i2c_priv)
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RREG32(rec->get_data_reg);
|
||||
val &= rec->get_data_mask;
|
||||
/* read the value off the pin */
|
||||
val = RREG32(rec->y_data_reg);
|
||||
val &= rec->y_data_mask;
|
||||
|
||||
return (val != 0);
|
||||
}
|
||||
|
||||
@ -138,9 +141,10 @@ static void set_clock(void *i2c_priv, int clock)
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask);
|
||||
val |= clock ? 0 : rec->put_clk_mask;
|
||||
WREG32(rec->put_clk_reg, val);
|
||||
/* set pin direction */
|
||||
val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
|
||||
val |= clock ? 0 : rec->en_clk_mask;
|
||||
WREG32(rec->en_clk_reg, val);
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t val;
|
||||
|
||||
val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask);
|
||||
val |= data ? 0 : rec->put_data_mask;
|
||||
WREG32(rec->put_data_reg, val);
|
||||
/* set pin direction */
|
||||
val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
|
||||
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_bus_rec *rec,
|
||||
const char *name)
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c;
|
||||
int ret;
|
||||
@ -207,3 +212,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
|
||||
{
|
||||
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)
|
||||
|
||||
if (rdev->flags & RADEON_SINGLE_CRTC)
|
||||
num_crtc = 1;
|
||||
|
||||
spin_lock_init(&rdev->irq.sw_lock);
|
||||
r = drm_vblank_init(rdev->ddev, num_crtc);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
/* enable msi */
|
||||
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);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
rdev->msi_enabled = 1;
|
||||
DRM_INFO("radeon: using MSI.\n");
|
||||
}
|
||||
}
|
||||
drm_irq_install(rdev->ddev);
|
||||
rdev->irq.installed = true;
|
||||
@ -114,3 +122,29 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
|
||||
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 @@
|
||||
#include "radeon.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,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
@ -292,8 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
uint32_t mask;
|
||||
|
||||
if (radeon_crtc->crtc_id)
|
||||
mask = (RADEON_CRTC2_EN |
|
||||
RADEON_CRTC2_DISP_DIS |
|
||||
mask = (RADEON_CRTC2_DISP_DIS |
|
||||
RADEON_CRTC2_VSYNC_DIS |
|
||||
RADEON_CRTC2_HSYNC_DIS |
|
||||
RADEON_CRTC2_DISP_REQ_EN_B);
|
||||
@ -305,7 +316,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
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 {
|
||||
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
|
||||
RADEON_CRTC_DISP_REQ_EN_B));
|
||||
@ -319,7 +330,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_pre_modeset(dev, 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 {
|
||||
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
|
||||
RADEON_CRTC_DISP_REQ_EN_B));
|
||||
@ -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_framebuffer *radeon_fb;
|
||||
struct drm_gem_object *obj;
|
||||
struct radeon_bo *rbo;
|
||||
uint64_t base;
|
||||
uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
|
||||
uint32_t crtc_pitch, pitch_pixels;
|
||||
uint32_t tiling_flags;
|
||||
int format;
|
||||
uint32_t gen_cntl_reg, gen_cntl_val;
|
||||
int r;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
/* no fb bound */
|
||||
if (!crtc->fb) {
|
||||
DRM_DEBUG("No FB bound\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
@ -431,10 +449,22 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Pin framebuffer & get tilling informations */
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
/* crtc offset is from display base addr not FB 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,
|
||||
(crtc->fb->bits_per_pixel * 8));
|
||||
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 (ASIC_IS_R300(rdev))
|
||||
@ -530,7 +556,12 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
|
||||
if (old_fb && old_fb != crtc->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 */
|
||||
@ -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 disp2_merge_cntl;
|
||||
|
||||
/* check to see 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 = RADEON_CRTC2_CRT2_ON;
|
||||
else
|
||||
crtc2_gen_cntl = 0;
|
||||
|
||||
/* if TV DAC is enabled for another crtc and keep it enabled */
|
||||
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
|
||||
crtc2_gen_cntl |= ((format << 8)
|
||||
| RADEON_CRTC2_VSYNC_DIS
|
||||
| RADEON_CRTC2_HSYNC_DIS
|
||||
@ -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 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)
|
||||
| RADEON_CRTC_DISP_REQ_EN_B
|
||||
| ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
@ -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)
|
||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
|
||||
if (lvds) {
|
||||
if (lvds->use_bios_dividers) {
|
||||
pll_ref_div = lvds->panel_ref_divider;
|
||||
pll_fb_post_div = (lvds->panel_fb_divider |
|
||||
(lvds->panel_post_divider << 16));
|
||||
htotal_cntl = 0;
|
||||
use_bios_divs = true;
|
||||
if (!rdev->is_atom_bios) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
|
||||
if (lvds) {
|
||||
if (lvds->use_bios_dividers) {
|
||||
pll_ref_div = lvds->panel_ref_divider;
|
||||
pll_fb_post_div = (lvds->panel_fb_divider |
|
||||
(lvds->panel_post_divider << 16));
|
||||
htotal_cntl = 0;
|
||||
use_bios_divs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||
@ -1027,6 +1057,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
|
||||
radeon_crtc_set_base(crtc, x, y, old_fb);
|
||||
radeon_set_crtc_timing(crtc, adjusted_mode);
|
||||
radeon_set_pll(crtc, adjusted_mode);
|
||||
radeon_overscan_setup(crtc, adjusted_mode);
|
||||
if (radeon_crtc->crtc_id == 0) {
|
||||
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
|
||||
} else {
|
||||
@ -1042,12 +1073,29 @@ static int radeon_crtc_mode_set(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)
|
||||
{
|
||||
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 = {
|
||||
|
@ -136,7 +136,14 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
|
||||
lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
|
||||
|
||||
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;
|
||||
if (lvds) {
|
||||
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,
|
||||
(lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
|
||||
} else
|
||||
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_ON |
|
||||
RADEON_LVDS_BLON |
|
||||
@ -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);
|
||||
}
|
||||
|
||||
static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
static bool radeon_legacy_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);
|
||||
|
||||
@ -194,15 +200,22 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
|
||||
radeon_encoder_set_active_device(encoder);
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
|
||||
if (radeon_encoder->rmx_type != RMX_OFF)
|
||||
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
|
||||
/* 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;
|
||||
adjusted_mode->hdisplay = mode->hdisplay;
|
||||
adjusted_mode->vdisplay = mode->vdisplay;
|
||||
adjusted_mode->base.id = mode_id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
|
||||
.dpms = radeon_legacy_lvds_dpms,
|
||||
.mode_fixup = radeon_legacy_lvds_mode_fixup,
|
||||
.mode_fixup = radeon_legacy_mode_fixup,
|
||||
.prepare = radeon_legacy_lvds_prepare,
|
||||
.mode_set = radeon_legacy_lvds_mode_set,
|
||||
.commit = radeon_legacy_lvds_commit,
|
||||
@ -214,17 +227,6 @@ static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = {
|
||||
.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)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
@ -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 = {
|
||||
.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,
|
||||
.mode_set = radeon_legacy_primary_dac_mode_set,
|
||||
.commit = radeon_legacy_primary_dac_commit,
|
||||
@ -423,16 +425,6 @@ static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = {
|
||||
.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)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
@ -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 = {
|
||||
.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,
|
||||
.mode_set = radeon_legacy_tmds_int_mode_set,
|
||||
.commit = radeon_legacy_tmds_int_commit,
|
||||
@ -596,17 +588,6 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = {
|
||||
.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)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
@ -697,6 +678,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
|
||||
/*if (mode->clock > 165000)
|
||||
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) {
|
||||
@ -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);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.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,
|
||||
.mode_set = radeon_legacy_tmds_ext_mode_set,
|
||||
.commit = radeon_legacy_tmds_ext_commit,
|
||||
@ -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 = {
|
||||
.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)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
@ -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 = {
|
||||
.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,
|
||||
.mode_set = radeon_legacy_tv_dac_mode_set,
|
||||
.commit = radeon_legacy_tv_dac_commit,
|
||||
@ -1302,6 +1287,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon
|
||||
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
|
||||
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
|
||||
encoder->possible_crtcs = 0x1;
|
||||
else
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
|
||||
radeon_encoder->enc_priv = NULL;
|
||||
|
||||
@ -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_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -89,24 +89,38 @@ enum radeon_tv_std {
|
||||
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 {
|
||||
bool valid;
|
||||
uint32_t mask_clk_reg;
|
||||
uint32_t mask_data_reg;
|
||||
uint32_t a_clk_reg;
|
||||
uint32_t a_data_reg;
|
||||
uint32_t put_clk_reg;
|
||||
uint32_t put_data_reg;
|
||||
uint32_t get_clk_reg;
|
||||
uint32_t get_data_reg;
|
||||
uint32_t en_clk_reg;
|
||||
uint32_t en_data_reg;
|
||||
uint32_t y_clk_reg;
|
||||
uint32_t y_data_reg;
|
||||
uint32_t mask_clk_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_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 {
|
||||
@ -170,6 +184,11 @@ enum radeon_connector_table {
|
||||
CT_EMAC,
|
||||
};
|
||||
|
||||
enum radeon_dvo_chip {
|
||||
DVO_SIL164,
|
||||
DVO_SIL1178,
|
||||
};
|
||||
|
||||
struct radeon_mode_info {
|
||||
struct atom_context *atom_context;
|
||||
struct card_info *atom_card_info;
|
||||
@ -261,6 +280,13 @@ struct radeon_encoder_int_tmds {
|
||||
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 */
|
||||
struct radeon_atom_ss {
|
||||
uint16_t percentage;
|
||||
@ -329,6 +355,14 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name);
|
||||
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 int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
|
||||
|
||||
@ -343,12 +377,15 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
|
||||
uint32_t *post_div_p,
|
||||
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_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_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);
|
||||
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 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);
|
||||
extern bool radeon_combios_get_clock_info(struct drm_device *dev);
|
||||
extern struct radeon_encoder_atom_dig *
|
||||
radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
|
||||
bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_int_tmds *tmds);
|
||||
bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_int_tmds *tmds);
|
||||
bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_int_tmds *tmds);
|
||||
extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_int_tmds *tmds);
|
||||
extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
|
||||
struct radeon_encoder_int_tmds *tmds);
|
||||
extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
|
||||
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 *
|
||||
radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
|
||||
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);
|
||||
extern struct radeon_encoder_primary_dac *
|
||||
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_initialize_bios_scratch_regs(struct drm_device *dev);
|
||||
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,
|
||||
struct radeon_crtc *radeon_crtc);
|
||||
void radeon_legacy_init_crtc(struct drm_device *dev,
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
|
||||
void radeon_combios_asic_init(struct drm_device *dev);
|
||||
|
@ -34,74 +34,32 @@
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon.h"
|
||||
|
||||
struct radeon_object {
|
||||
struct ttm_buffer_object tobj;
|
||||
struct list_head list;
|
||||
struct radeon_device *rdev;
|
||||
struct drm_gem_object *gobj;
|
||||
struct ttm_bo_kmap_obj kmap;
|
||||
unsigned pin_count;
|
||||
uint64_t gpu_addr;
|
||||
void *kptr;
|
||||
bool is_iomem;
|
||||
uint32_t tiling_flags;
|
||||
uint32_t pitch;
|
||||
int surface_reg;
|
||||
};
|
||||
|
||||
int radeon_ttm_init(struct radeon_device *rdev);
|
||||
void radeon_ttm_fini(struct radeon_device *rdev);
|
||||
static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
|
||||
|
||||
/*
|
||||
* To exclude mutual BO access we rely on bo_reserve exclusion, as all
|
||||
* function are calling it.
|
||||
*/
|
||||
|
||||
static int radeon_object_reserve(struct radeon_object *robj, bool interruptible)
|
||||
static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
|
||||
{
|
||||
return ttm_bo_reserve(&robj->tobj, interruptible, false, false, 0);
|
||||
struct radeon_bo *bo;
|
||||
|
||||
bo = container_of(tbo, struct radeon_bo, tbo);
|
||||
mutex_lock(&bo->rdev->gem.mutex);
|
||||
list_del_init(&bo->list);
|
||||
mutex_unlock(&bo->rdev->gem.mutex);
|
||||
radeon_bo_clear_surface_reg(bo);
|
||||
kfree(bo);
|
||||
}
|
||||
|
||||
static void radeon_object_unreserve(struct radeon_object *robj)
|
||||
static inline u32 radeon_ttm_flags_from_domain(u32 domain)
|
||||
{
|
||||
ttm_bo_unreserve(&robj->tobj);
|
||||
}
|
||||
u32 flags = 0;
|
||||
|
||||
static void radeon_ttm_object_object_destroy(struct ttm_buffer_object *tobj)
|
||||
{
|
||||
struct radeon_object *robj;
|
||||
|
||||
robj = container_of(tobj, struct radeon_object, tobj);
|
||||
list_del_init(&robj->list);
|
||||
radeon_object_clear_surface_reg(robj);
|
||||
kfree(robj);
|
||||
}
|
||||
|
||||
static inline void radeon_object_gpu_addr(struct radeon_object *robj)
|
||||
{
|
||||
/* Default gpu address */
|
||||
robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
|
||||
if (robj->tobj.mem.mm_node == NULL) {
|
||||
return;
|
||||
}
|
||||
robj->gpu_addr = ((u64)robj->tobj.mem.mm_node->start) << PAGE_SHIFT;
|
||||
switch (robj->tobj.mem.mem_type) {
|
||||
case TTM_PL_VRAM:
|
||||
robj->gpu_addr += (u64)robj->rdev->mc.vram_location;
|
||||
break;
|
||||
case TTM_PL_TT:
|
||||
robj->gpu_addr += (u64)robj->rdev->mc.gtt_location;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown placement %d\n", robj->tobj.mem.mem_type);
|
||||
robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t radeon_object_flags_from_domain(uint32_t domain)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
if (domain & RADEON_GEM_DOMAIN_VRAM) {
|
||||
flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
|
||||
}
|
||||
@ -117,17 +75,13 @@ static inline uint32_t radeon_object_flags_from_domain(uint32_t domain)
|
||||
return flags;
|
||||
}
|
||||
|
||||
int radeon_object_create(struct radeon_device *rdev,
|
||||
struct drm_gem_object *gobj,
|
||||
unsigned long size,
|
||||
bool kernel,
|
||||
uint32_t domain,
|
||||
bool interruptible,
|
||||
struct radeon_object **robj_ptr)
|
||||
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)
|
||||
{
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo *bo;
|
||||
enum ttm_bo_type type;
|
||||
uint32_t flags;
|
||||
u32 flags;
|
||||
int r;
|
||||
|
||||
if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
|
||||
@ -138,206 +92,140 @@ int radeon_object_create(struct radeon_device *rdev,
|
||||
} else {
|
||||
type = ttm_bo_type_device;
|
||||
}
|
||||
*robj_ptr = NULL;
|
||||
robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL);
|
||||
if (robj == NULL) {
|
||||
*bo_ptr = NULL;
|
||||
bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
|
||||
if (bo == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
robj->rdev = rdev;
|
||||
robj->gobj = gobj;
|
||||
robj->surface_reg = -1;
|
||||
INIT_LIST_HEAD(&robj->list);
|
||||
bo->rdev = rdev;
|
||||
bo->gobj = gobj;
|
||||
bo->surface_reg = -1;
|
||||
INIT_LIST_HEAD(&bo->list);
|
||||
|
||||
flags = radeon_object_flags_from_domain(domain);
|
||||
r = ttm_buffer_object_init(&rdev->mman.bdev, &robj->tobj, size, type, flags,
|
||||
0, 0, false, NULL, size,
|
||||
&radeon_ttm_object_object_destroy);
|
||||
flags = radeon_ttm_flags_from_domain(domain);
|
||||
retry:
|
||||
r = ttm_buffer_object_init(&rdev->mman.bdev, &bo->tbo, size, type,
|
||||
flags, 0, 0, true, NULL, size,
|
||||
&radeon_ttm_bo_destroy);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r == -ERESTART)
|
||||
goto retry;
|
||||
/* ttm call radeon_ttm_object_object_destroy if error happen */
|
||||
DRM_ERROR("Failed to allocate TTM object (%ld, 0x%08X, %u)\n",
|
||||
size, flags, 0);
|
||||
dev_err(rdev->dev, "object_init failed for (%ld, 0x%08X)\n",
|
||||
size, flags);
|
||||
return r;
|
||||
}
|
||||
*robj_ptr = robj;
|
||||
*bo_ptr = bo;
|
||||
if (gobj) {
|
||||
list_add_tail(&robj->list, &rdev->gem.objects);
|
||||
mutex_lock(&bo->rdev->gem.mutex);
|
||||
list_add_tail(&bo->list, &rdev->gem.objects);
|
||||
mutex_unlock(&bo->rdev->gem.mutex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_object_kmap(struct radeon_object *robj, void **ptr)
|
||||
int radeon_bo_kmap(struct radeon_bo *bo, void **ptr)
|
||||
{
|
||||
bool is_iomem;
|
||||
int r;
|
||||
|
||||
spin_lock(&robj->tobj.lock);
|
||||
if (robj->kptr) {
|
||||
if (bo->kptr) {
|
||||
if (ptr) {
|
||||
*ptr = robj->kptr;
|
||||
*ptr = bo->kptr;
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
return 0;
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
r = ttm_bo_kmap(&robj->tobj, 0, robj->tobj.num_pages, &robj->kmap);
|
||||
r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
spin_lock(&robj->tobj.lock);
|
||||
robj->kptr = ttm_kmap_obj_virtual(&robj->kmap, &robj->is_iomem);
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
|
||||
if (ptr) {
|
||||
*ptr = robj->kptr;
|
||||
*ptr = bo->kptr;
|
||||
}
|
||||
radeon_object_check_tiling(robj, 0, 0);
|
||||
radeon_bo_check_tiling(bo, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_object_kunmap(struct radeon_object *robj)
|
||||
void radeon_bo_kunmap(struct radeon_bo *bo)
|
||||
{
|
||||
spin_lock(&robj->tobj.lock);
|
||||
if (robj->kptr == NULL) {
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
if (bo->kptr == NULL)
|
||||
return;
|
||||
}
|
||||
robj->kptr = NULL;
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
radeon_object_check_tiling(robj, 0, 0);
|
||||
ttm_bo_kunmap(&robj->kmap);
|
||||
bo->kptr = NULL;
|
||||
radeon_bo_check_tiling(bo, 0, 0);
|
||||
ttm_bo_kunmap(&bo->kmap);
|
||||
}
|
||||
|
||||
void radeon_object_unref(struct radeon_object **robj)
|
||||
void radeon_bo_unref(struct radeon_bo **bo)
|
||||
{
|
||||
struct ttm_buffer_object *tobj;
|
||||
struct ttm_buffer_object *tbo;
|
||||
|
||||
if ((*robj) == NULL) {
|
||||
if ((*bo) == NULL)
|
||||
return;
|
||||
}
|
||||
tobj = &((*robj)->tobj);
|
||||
ttm_bo_unref(&tobj);
|
||||
if (tobj == NULL) {
|
||||
*robj = NULL;
|
||||
}
|
||||
tbo = &((*bo)->tbo);
|
||||
ttm_bo_unref(&tbo);
|
||||
if (tbo == NULL)
|
||||
*bo = NULL;
|
||||
}
|
||||
|
||||
int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset)
|
||||
int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
{
|
||||
*offset = robj->tobj.addr_space_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
|
||||
uint64_t *gpu_addr)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t tmp;
|
||||
u32 flags;
|
||||
u32 tmp;
|
||||
int r;
|
||||
|
||||
flags = radeon_object_flags_from_domain(domain);
|
||||
spin_lock(&robj->tobj.lock);
|
||||
if (robj->pin_count) {
|
||||
robj->pin_count++;
|
||||
if (gpu_addr != NULL) {
|
||||
*gpu_addr = robj->gpu_addr;
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
flags = radeon_ttm_flags_from_domain(domain);
|
||||
if (bo->pin_count) {
|
||||
bo->pin_count++;
|
||||
if (gpu_addr)
|
||||
*gpu_addr = radeon_bo_gpu_offset(bo);
|
||||
return 0;
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
r = radeon_object_reserve(robj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to reserve object for pinning it.\n");
|
||||
return r;
|
||||
}
|
||||
tmp = robj->tobj.mem.placement;
|
||||
tmp = bo->tbo.mem.placement;
|
||||
ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM);
|
||||
robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING;
|
||||
r = ttm_buffer_object_validate(&robj->tobj,
|
||||
robj->tobj.proposed_placement,
|
||||
false, false);
|
||||
radeon_object_gpu_addr(robj);
|
||||
if (gpu_addr != NULL) {
|
||||
*gpu_addr = robj->gpu_addr;
|
||||
bo->tbo.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT |
|
||||
TTM_PL_MASK_CACHING;
|
||||
retry:
|
||||
r = ttm_buffer_object_validate(&bo->tbo, bo->tbo.proposed_placement,
|
||||
true, false);
|
||||
if (likely(r == 0)) {
|
||||
bo->pin_count = 1;
|
||||
if (gpu_addr != NULL)
|
||||
*gpu_addr = radeon_bo_gpu_offset(bo);
|
||||
}
|
||||
robj->pin_count = 1;
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to pin object.\n");
|
||||
if (r == -ERESTART)
|
||||
goto retry;
|
||||
dev_err(bo->rdev->dev, "%p pin failed\n", bo);
|
||||
}
|
||||
radeon_object_unreserve(robj);
|
||||
return r;
|
||||
}
|
||||
|
||||
void radeon_object_unpin(struct radeon_object *robj)
|
||||
int radeon_bo_unpin(struct radeon_bo *bo)
|
||||
{
|
||||
uint32_t flags;
|
||||
int r;
|
||||
|
||||
spin_lock(&robj->tobj.lock);
|
||||
if (!robj->pin_count) {
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
printk(KERN_WARNING "Unpin not necessary for %p !\n", robj);
|
||||
return;
|
||||
if (!bo->pin_count) {
|
||||
dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo);
|
||||
return 0;
|
||||
}
|
||||
robj->pin_count--;
|
||||
if (robj->pin_count) {
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
r = radeon_object_reserve(robj, false);
|
||||
bo->pin_count--;
|
||||
if (bo->pin_count)
|
||||
return 0;
|
||||
bo->tbo.proposed_placement = bo->tbo.mem.placement &
|
||||
~TTM_PL_FLAG_NO_EVICT;
|
||||
retry:
|
||||
r = ttm_buffer_object_validate(&bo->tbo, bo->tbo.proposed_placement,
|
||||
true, false);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to reserve object for unpinning it.\n");
|
||||
return;
|
||||
}
|
||||
flags = robj->tobj.mem.placement;
|
||||
robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT;
|
||||
r = ttm_buffer_object_validate(&robj->tobj,
|
||||
robj->tobj.proposed_placement,
|
||||
false, false);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to unpin buffer.\n");
|
||||
}
|
||||
radeon_object_unreserve(robj);
|
||||
}
|
||||
|
||||
int radeon_object_wait(struct radeon_object *robj)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
/* FIXME: should use block reservation instead */
|
||||
r = radeon_object_reserve(robj, true);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to reserve object for waiting.\n");
|
||||
if (r == -ERESTART)
|
||||
goto retry;
|
||||
dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo);
|
||||
return r;
|
||||
}
|
||||
spin_lock(&robj->tobj.lock);
|
||||
if (robj->tobj.sync_obj) {
|
||||
r = ttm_bo_wait(&robj->tobj, true, true, false);
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
radeon_object_unreserve(robj);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r = radeon_object_reserve(robj, true);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to reserve object for waiting.\n");
|
||||
return r;
|
||||
}
|
||||
spin_lock(&robj->tobj.lock);
|
||||
*cur_placement = robj->tobj.mem.mem_type;
|
||||
if (robj->tobj.sync_obj) {
|
||||
r = ttm_bo_wait(&robj->tobj, true, true, true);
|
||||
}
|
||||
spin_unlock(&robj->tobj.lock);
|
||||
radeon_object_unreserve(robj);
|
||||
return r;
|
||||
}
|
||||
|
||||
int radeon_object_evict_vram(struct radeon_device *rdev)
|
||||
int radeon_bo_evict_vram(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
/* Useless to evict on IGP chips */
|
||||
@ -346,30 +234,32 @@ int radeon_object_evict_vram(struct radeon_device *rdev)
|
||||
return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM);
|
||||
}
|
||||
|
||||
void radeon_object_force_delete(struct radeon_device *rdev)
|
||||
void radeon_bo_force_delete(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_object *robj, *n;
|
||||
struct radeon_bo *bo, *n;
|
||||
struct drm_gem_object *gobj;
|
||||
|
||||
if (list_empty(&rdev->gem.objects)) {
|
||||
return;
|
||||
}
|
||||
DRM_ERROR("Userspace still has active objects !\n");
|
||||
list_for_each_entry_safe(robj, n, &rdev->gem.objects, list) {
|
||||
dev_err(rdev->dev, "Userspace still has active objects !\n");
|
||||
list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) {
|
||||
mutex_lock(&rdev->ddev->struct_mutex);
|
||||
gobj = robj->gobj;
|
||||
DRM_ERROR("Force free for (%p,%p,%lu,%lu)\n",
|
||||
gobj, robj, (unsigned long)gobj->size,
|
||||
*((unsigned long *)&gobj->refcount));
|
||||
list_del_init(&robj->list);
|
||||
radeon_object_unref(&robj);
|
||||
gobj = bo->gobj;
|
||||
dev_err(rdev->dev, "%p %p %lu %lu force free\n",
|
||||
gobj, bo, (unsigned long)gobj->size,
|
||||
*((unsigned long *)&gobj->refcount));
|
||||
mutex_lock(&bo->rdev->gem.mutex);
|
||||
list_del_init(&bo->list);
|
||||
mutex_unlock(&bo->rdev->gem.mutex);
|
||||
radeon_bo_unref(&bo);
|
||||
gobj->driver_private = NULL;
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&rdev->ddev->struct_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_object_init(struct radeon_device *rdev)
|
||||
int radeon_bo_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* Add an MTRR for the VRAM */
|
||||
rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
|
||||
@ -382,13 +272,13 @@ int radeon_object_init(struct radeon_device *rdev)
|
||||
return radeon_ttm_init(rdev);
|
||||
}
|
||||
|
||||
void radeon_object_fini(struct radeon_device *rdev)
|
||||
void radeon_bo_fini(struct radeon_device *rdev)
|
||||
{
|
||||
radeon_ttm_fini(rdev);
|
||||
}
|
||||
|
||||
void radeon_object_list_add_object(struct radeon_object_list *lobj,
|
||||
struct list_head *head)
|
||||
void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (lobj->wdomain) {
|
||||
list_add(&lobj->list, head);
|
||||
@ -397,72 +287,67 @@ void radeon_object_list_add_object(struct radeon_object_list *lobj,
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_object_list_reserve(struct list_head *head)
|
||||
int radeon_bo_list_reserve(struct list_head *head)
|
||||
{
|
||||
struct radeon_object_list *lobj;
|
||||
struct radeon_bo_list *lobj;
|
||||
int r;
|
||||
|
||||
list_for_each_entry(lobj, head, list){
|
||||
if (!lobj->robj->pin_count) {
|
||||
r = radeon_object_reserve(lobj->robj, true);
|
||||
if (unlikely(r != 0)) {
|
||||
DRM_ERROR("radeon: failed to reserve object.\n");
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
r = radeon_bo_reserve(lobj->bo, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_object_list_unreserve(struct list_head *head)
|
||||
void radeon_bo_list_unreserve(struct list_head *head)
|
||||
{
|
||||
struct radeon_object_list *lobj;
|
||||
struct radeon_bo_list *lobj;
|
||||
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
if (!lobj->robj->pin_count) {
|
||||
radeon_object_unreserve(lobj->robj);
|
||||
}
|
||||
/* only unreserve object we successfully reserved */
|
||||
if (radeon_bo_is_reserved(lobj->bo))
|
||||
radeon_bo_unreserve(lobj->bo);
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_object_list_validate(struct list_head *head, void *fence)
|
||||
int radeon_bo_list_validate(struct list_head *head, void *fence)
|
||||
{
|
||||
struct radeon_object_list *lobj;
|
||||
struct radeon_object *robj;
|
||||
struct radeon_bo_list *lobj;
|
||||
struct radeon_bo *bo;
|
||||
struct radeon_fence *old_fence = NULL;
|
||||
int r;
|
||||
|
||||
r = radeon_object_list_reserve(head);
|
||||
r = radeon_bo_list_reserve(head);
|
||||
if (unlikely(r != 0)) {
|
||||
radeon_object_list_unreserve(head);
|
||||
return r;
|
||||
}
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
robj = lobj->robj;
|
||||
if (!robj->pin_count) {
|
||||
bo = lobj->bo;
|
||||
if (!bo->pin_count) {
|
||||
if (lobj->wdomain) {
|
||||
robj->tobj.proposed_placement =
|
||||
radeon_object_flags_from_domain(lobj->wdomain);
|
||||
bo->tbo.proposed_placement =
|
||||
radeon_ttm_flags_from_domain(lobj->wdomain);
|
||||
} else {
|
||||
robj->tobj.proposed_placement =
|
||||
radeon_object_flags_from_domain(lobj->rdomain);
|
||||
bo->tbo.proposed_placement =
|
||||
radeon_ttm_flags_from_domain(lobj->rdomain);
|
||||
}
|
||||
r = ttm_buffer_object_validate(&robj->tobj,
|
||||
robj->tobj.proposed_placement,
|
||||
true, false);
|
||||
retry:
|
||||
r = ttm_buffer_object_validate(&bo->tbo,
|
||||
bo->tbo.proposed_placement,
|
||||
true, false);
|
||||
if (unlikely(r)) {
|
||||
DRM_ERROR("radeon: failed to validate.\n");
|
||||
if (r == -ERESTART)
|
||||
goto retry;
|
||||
return r;
|
||||
}
|
||||
radeon_object_gpu_addr(robj);
|
||||
}
|
||||
lobj->gpu_offset = robj->gpu_addr;
|
||||
lobj->tiling_flags = robj->tiling_flags;
|
||||
lobj->gpu_offset = radeon_bo_gpu_offset(bo);
|
||||
lobj->tiling_flags = bo->tiling_flags;
|
||||
if (fence) {
|
||||
old_fence = (struct radeon_fence *)robj->tobj.sync_obj;
|
||||
robj->tobj.sync_obj = radeon_fence_ref(fence);
|
||||
robj->tobj.sync_obj_arg = NULL;
|
||||
old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
|
||||
bo->tbo.sync_obj = radeon_fence_ref(fence);
|
||||
bo->tbo.sync_obj_arg = NULL;
|
||||
}
|
||||
if (old_fence) {
|
||||
radeon_fence_unref(&old_fence);
|
||||
@ -471,51 +356,44 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_object_list_unvalidate(struct list_head *head)
|
||||
void radeon_bo_list_unvalidate(struct list_head *head, void *fence)
|
||||
{
|
||||
struct radeon_object_list *lobj;
|
||||
struct radeon_fence *old_fence = NULL;
|
||||
struct radeon_bo_list *lobj;
|
||||
struct radeon_fence *old_fence;
|
||||
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
|
||||
lobj->robj->tobj.sync_obj = NULL;
|
||||
if (old_fence) {
|
||||
radeon_fence_unref(&old_fence);
|
||||
if (fence)
|
||||
list_for_each_entry(lobj, head, list) {
|
||||
old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj);
|
||||
if (old_fence == fence) {
|
||||
lobj->bo->tbo.sync_obj = NULL;
|
||||
radeon_fence_unref(&old_fence);
|
||||
}
|
||||
}
|
||||
}
|
||||
radeon_object_list_unreserve(head);
|
||||
radeon_bo_list_unreserve(head);
|
||||
}
|
||||
|
||||
void radeon_object_list_clean(struct list_head *head)
|
||||
{
|
||||
radeon_object_list_unreserve(head);
|
||||
}
|
||||
|
||||
int radeon_object_fbdev_mmap(struct radeon_object *robj,
|
||||
int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
return ttm_fbdev_mmap(vma, &robj->tobj);
|
||||
return ttm_fbdev_mmap(vma, &bo->tbo);
|
||||
}
|
||||
|
||||
unsigned long radeon_object_size(struct radeon_object *robj)
|
||||
static int radeon_bo_get_surface_reg(struct radeon_bo *bo)
|
||||
{
|
||||
return robj->tobj.num_pages << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
int radeon_object_get_surface_reg(struct radeon_object *robj)
|
||||
{
|
||||
struct radeon_device *rdev = robj->rdev;
|
||||
struct radeon_device *rdev = bo->rdev;
|
||||
struct radeon_surface_reg *reg;
|
||||
struct radeon_object *old_object;
|
||||
struct radeon_bo *old_object;
|
||||
int steal;
|
||||
int i;
|
||||
|
||||
if (!robj->tiling_flags)
|
||||
BUG_ON(!atomic_read(&bo->tbo.reserved));
|
||||
|
||||
if (!bo->tiling_flags)
|
||||
return 0;
|
||||
|
||||
if (robj->surface_reg >= 0) {
|
||||
reg = &rdev->surface_regs[robj->surface_reg];
|
||||
i = robj->surface_reg;
|
||||
if (bo->surface_reg >= 0) {
|
||||
reg = &rdev->surface_regs[bo->surface_reg];
|
||||
i = bo->surface_reg;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -523,10 +401,10 @@ int radeon_object_get_surface_reg(struct radeon_object *robj)
|
||||
for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
|
||||
|
||||
reg = &rdev->surface_regs[i];
|
||||
if (!reg->robj)
|
||||
if (!reg->bo)
|
||||
break;
|
||||
|
||||
old_object = reg->robj;
|
||||
old_object = reg->bo;
|
||||
if (old_object->pin_count == 0)
|
||||
steal = i;
|
||||
}
|
||||
@ -537,91 +415,101 @@ int radeon_object_get_surface_reg(struct radeon_object *robj)
|
||||
return -ENOMEM;
|
||||
/* find someone with a surface reg and nuke their BO */
|
||||
reg = &rdev->surface_regs[steal];
|
||||
old_object = reg->robj;
|
||||
old_object = reg->bo;
|
||||
/* blow away the mapping */
|
||||
DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object);
|
||||
ttm_bo_unmap_virtual(&old_object->tobj);
|
||||
ttm_bo_unmap_virtual(&old_object->tbo);
|
||||
old_object->surface_reg = -1;
|
||||
i = steal;
|
||||
}
|
||||
|
||||
robj->surface_reg = i;
|
||||
reg->robj = robj;
|
||||
bo->surface_reg = i;
|
||||
reg->bo = bo;
|
||||
|
||||
out:
|
||||
radeon_set_surface_reg(rdev, i, robj->tiling_flags, robj->pitch,
|
||||
robj->tobj.mem.mm_node->start << PAGE_SHIFT,
|
||||
robj->tobj.num_pages << PAGE_SHIFT);
|
||||
radeon_set_surface_reg(rdev, i, bo->tiling_flags, bo->pitch,
|
||||
bo->tbo.mem.mm_node->start << PAGE_SHIFT,
|
||||
bo->tbo.num_pages << PAGE_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_object_clear_surface_reg(struct radeon_object *robj)
|
||||
static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
|
||||
{
|
||||
struct radeon_device *rdev = robj->rdev;
|
||||
struct radeon_device *rdev = bo->rdev;
|
||||
struct radeon_surface_reg *reg;
|
||||
|
||||
if (robj->surface_reg == -1)
|
||||
if (bo->surface_reg == -1)
|
||||
return;
|
||||
|
||||
reg = &rdev->surface_regs[robj->surface_reg];
|
||||
radeon_clear_surface_reg(rdev, robj->surface_reg);
|
||||
reg = &rdev->surface_regs[bo->surface_reg];
|
||||
radeon_clear_surface_reg(rdev, bo->surface_reg);
|
||||
|
||||
reg->robj = NULL;
|
||||
robj->surface_reg = -1;
|
||||
reg->bo = NULL;
|
||||
bo->surface_reg = -1;
|
||||
}
|
||||
|
||||
void radeon_object_set_tiling_flags(struct radeon_object *robj,
|
||||
uint32_t tiling_flags, uint32_t pitch)
|
||||
int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
|
||||
uint32_t tiling_flags, uint32_t pitch)
|
||||
{
|
||||
robj->tiling_flags = tiling_flags;
|
||||
robj->pitch = pitch;
|
||||
int r;
|
||||
|
||||
r = radeon_bo_reserve(bo, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
bo->tiling_flags = tiling_flags;
|
||||
bo->pitch = pitch;
|
||||
radeon_bo_unreserve(bo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_object_get_tiling_flags(struct radeon_object *robj,
|
||||
uint32_t *tiling_flags,
|
||||
uint32_t *pitch)
|
||||
void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
|
||||
uint32_t *tiling_flags,
|
||||
uint32_t *pitch)
|
||||
{
|
||||
BUG_ON(!atomic_read(&bo->tbo.reserved));
|
||||
if (tiling_flags)
|
||||
*tiling_flags = robj->tiling_flags;
|
||||
*tiling_flags = bo->tiling_flags;
|
||||
if (pitch)
|
||||
*pitch = robj->pitch;
|
||||
*pitch = bo->pitch;
|
||||
}
|
||||
|
||||
int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
|
||||
bool force_drop)
|
||||
int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
|
||||
bool force_drop)
|
||||
{
|
||||
if (!(robj->tiling_flags & RADEON_TILING_SURFACE))
|
||||
BUG_ON(!atomic_read(&bo->tbo.reserved));
|
||||
|
||||
if (!(bo->tiling_flags & RADEON_TILING_SURFACE))
|
||||
return 0;
|
||||
|
||||
if (force_drop) {
|
||||
radeon_object_clear_surface_reg(robj);
|
||||
radeon_bo_clear_surface_reg(bo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (robj->tobj.mem.mem_type != TTM_PL_VRAM) {
|
||||
if (bo->tbo.mem.mem_type != TTM_PL_VRAM) {
|
||||
if (!has_moved)
|
||||
return 0;
|
||||
|
||||
if (robj->surface_reg >= 0)
|
||||
radeon_object_clear_surface_reg(robj);
|
||||
if (bo->surface_reg >= 0)
|
||||
radeon_bo_clear_surface_reg(bo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((robj->surface_reg >= 0) && !has_moved)
|
||||
if ((bo->surface_reg >= 0) && !has_moved)
|
||||
return 0;
|
||||
|
||||
return radeon_object_get_surface_reg(robj);
|
||||
return radeon_bo_get_surface_reg(bo);
|
||||
}
|
||||
|
||||
void radeon_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
struct ttm_mem_reg *mem)
|
||||
struct ttm_mem_reg *mem)
|
||||
{
|
||||
struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
|
||||
radeon_object_check_tiling(robj, 0, 1);
|
||||
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
|
||||
radeon_bo_check_tiling(rbo, 0, 1);
|
||||
}
|
||||
|
||||
void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
|
||||
radeon_object_check_tiling(robj, 0, 0);
|
||||
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo);
|
||||
radeon_bo_check_tiling(rbo, 0, 0);
|
||||
}
|
||||
|
@ -28,19 +28,152 @@
|
||||
#ifndef __RADEON_OBJECT_H__
|
||||
#define __RADEON_OBJECT_H__
|
||||
|
||||
#include <ttm/ttm_bo_api.h>
|
||||
#include <ttm/ttm_bo_driver.h>
|
||||
#include <ttm/ttm_placement.h>
|
||||
#include <ttm/ttm_module.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
#include "radeon.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
|
||||
*/
|
||||
struct radeon_mman {
|
||||
struct ttm_bo_global_ref bo_global_ref;
|
||||
struct ttm_global_reference mem_global_ref;
|
||||
bool mem_global_referenced;
|
||||
struct ttm_bo_device bdev;
|
||||
};
|
||||
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.
|
||||
*/
|
||||
static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
|
||||
{
|
||||
return bo->tbo.addr_space_offset;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -27,7 +27,7 @@ int radeon_debugfs_pm_init(struct radeon_device *rdev);
|
||||
int radeon_pm_init(struct radeon_device *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;
|
||||
@ -44,8 +44,8 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
|
||||
seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
|
||||
seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
|
||||
seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1051,20 +1051,25 @@
|
||||
|
||||
/* Multimedia I2C bus */
|
||||
#define RADEON_I2C_CNTL_0 0x0090
|
||||
#define RADEON_I2C_DONE (1<<0)
|
||||
#define RADEON_I2C_NACK (1<<1)
|
||||
#define RADEON_I2C_HALT (1<<2)
|
||||
#define RADEON_I2C_SOFT_RST (1<<5)
|
||||
#define RADEON_I2C_DRIVE_EN (1<<6)
|
||||
#define RADEON_I2C_DRIVE_SEL (1<<7)
|
||||
#define RADEON_I2C_START (1<<8)
|
||||
#define RADEON_I2C_STOP (1<<9)
|
||||
#define RADEON_I2C_RECEIVE (1<<10)
|
||||
#define RADEON_I2C_ABORT (1<<11)
|
||||
#define RADEON_I2C_GO (1<<12)
|
||||
#define RADEON_I2C_DONE (1 << 0)
|
||||
#define RADEON_I2C_NACK (1 << 1)
|
||||
#define RADEON_I2C_HALT (1 << 2)
|
||||
#define RADEON_I2C_SOFT_RST (1 << 5)
|
||||
#define RADEON_I2C_DRIVE_EN (1 << 6)
|
||||
#define RADEON_I2C_DRIVE_SEL (1 << 7)
|
||||
#define RADEON_I2C_START (1 << 8)
|
||||
#define RADEON_I2C_STOP (1 << 9)
|
||||
#define RADEON_I2C_RECEIVE (1 << 10)
|
||||
#define RADEON_I2C_ABORT (1 << 11)
|
||||
#define RADEON_I2C_GO (1 << 12)
|
||||
#define RADEON_I2C_PRESCALE_SHIFT 16
|
||||
#define RADEON_I2C_CNTL_1 0x0094
|
||||
#define RADEON_I2C_SEL (1<<16)
|
||||
#define RADEON_I2C_EN (1<<17)
|
||||
#define RADEON_I2C_DATA_COUNT_SHIFT 0
|
||||
#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_DVI_I2C_CNTL_0 0x02e0
|
||||
@ -1072,7 +1077,7 @@
|
||||
# define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */
|
||||
# define R200_SEL_DDC2 1 /* 0x64 - DVI_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_INTERRUPT_LINE 0x0f3c /* PCI */
|
||||
@ -1143,14 +1148,15 @@
|
||||
# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
|
||||
# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14)
|
||||
# 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_Y 0x01a4
|
||||
#define RADEON_LCD_GPIO_MASK 0x01a0
|
||||
#define RADEON_LCD_GPIO_Y_REG 0x01a4
|
||||
#define RADEON_MDGPIO_A_REG 0x01ac
|
||||
#define RADEON_MDGPIO_EN_REG 0x01b0
|
||||
#define RADEON_MDGPIO_MASK 0x0198
|
||||
#define RADEON_GPIOPAD_MASK 0x0198
|
||||
#define RADEON_GPIOPAD_A 0x019c
|
||||
#define RADEON_MDGPIO_Y_REG 0x01b4
|
||||
#define RADEON_MEM_ADDR_CONFIG 0x0148
|
||||
#define RADEON_MEM_BASE 0x0f10 /* PCI */
|
||||
@ -1360,6 +1366,9 @@
|
||||
#define RADEON_OVR_CLR 0x0230
|
||||
#define RADEON_OVR_WID_LEFT_RIGHT 0x0234
|
||||
#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 */
|
||||
|
||||
|
@ -165,19 +165,24 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
|
||||
return 0;
|
||||
/* Allocate 1M object buffer */
|
||||
INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
|
||||
r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
|
||||
true, RADEON_GEM_DOMAIN_GTT,
|
||||
false, &rdev->ib_pool.robj);
|
||||
r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
|
||||
true, RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->ib_pool.robj);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to ib pool (%d).\n", 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) {
|
||||
radeon_bo_unreserve(rdev->ib_pool.robj);
|
||||
DRM_ERROR("radeon: failed to pin ib pool (%d).\n", 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) {
|
||||
DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
|
||||
return r;
|
||||
@ -203,14 +208,21 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
|
||||
|
||||
void radeon_ib_pool_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!rdev->ib_pool.ready) {
|
||||
return;
|
||||
}
|
||||
mutex_lock(&rdev->ib_pool.mutex);
|
||||
bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
|
||||
if (rdev->ib_pool.robj) {
|
||||
radeon_object_kunmap(rdev->ib_pool.robj);
|
||||
radeon_object_unref(&rdev->ib_pool.robj);
|
||||
r = radeon_bo_reserve(rdev->ib_pool.robj, false);
|
||||
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;
|
||||
}
|
||||
mutex_unlock(&rdev->ib_pool.mutex);
|
||||
@ -288,29 +300,28 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
rdev->cp.ring_size = ring_size;
|
||||
/* Allocate ring buffer */
|
||||
if (rdev->cp.ring_obj == NULL) {
|
||||
r = radeon_object_create(rdev, NULL, rdev->cp.ring_size,
|
||||
true,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
false,
|
||||
&rdev->cp.ring_obj);
|
||||
r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->cp.ring_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r);
|
||||
mutex_unlock(&rdev->cp.mutex);
|
||||
dev_err(rdev->dev, "(%d) ring create failed\n", r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_pin(rdev->cp.ring_obj,
|
||||
RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->cp.gpu_addr);
|
||||
r = radeon_bo_reserve(rdev->cp.ring_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT,
|
||||
&rdev->cp.gpu_addr);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r);
|
||||
mutex_unlock(&rdev->cp.mutex);
|
||||
radeon_bo_unreserve(rdev->cp.ring_obj);
|
||||
dev_err(rdev->dev, "(%d) ring pin failed\n", r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_kmap(rdev->cp.ring_obj,
|
||||
r = radeon_bo_kmap(rdev->cp.ring_obj,
|
||||
(void **)&rdev->cp.ring);
|
||||
radeon_bo_unreserve(rdev->cp.ring_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r);
|
||||
mutex_unlock(&rdev->cp.mutex);
|
||||
dev_err(rdev->dev, "(%d) ring map failed\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -321,11 +332,17 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
|
||||
void radeon_ring_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&rdev->cp.mutex);
|
||||
if (rdev->cp.ring_obj) {
|
||||
radeon_object_kunmap(rdev->cp.ring_obj);
|
||||
radeon_object_unpin(rdev->cp.ring_obj);
|
||||
radeon_object_unref(&rdev->cp.ring_obj);
|
||||
r = radeon_bo_reserve(rdev->cp.ring_obj, false);
|
||||
if (likely(r == 0)) {
|
||||
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_obj = NULL;
|
||||
}
|
||||
|
@ -30,8 +30,8 @@
|
||||
/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
|
||||
void radeon_test_moves(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_object *vram_obj = NULL;
|
||||
struct radeon_object **gtt_obj = NULL;
|
||||
struct radeon_bo *vram_obj = NULL;
|
||||
struct radeon_bo **gtt_obj = NULL;
|
||||
struct radeon_fence *fence = NULL;
|
||||
uint64_t gtt_addr, vram_addr;
|
||||
unsigned i, n, size;
|
||||
@ -52,38 +52,42 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
|
||||
false, &vram_obj);
|
||||
r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
|
||||
&vram_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create VRAM object\n");
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
|
||||
r = radeon_bo_reserve(vram_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
goto out_cleanup;
|
||||
r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to pin VRAM object\n");
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
void *gtt_map, *vram_map;
|
||||
void **gtt_start, **gtt_end;
|
||||
void **vram_start, **vram_end;
|
||||
|
||||
r = radeon_object_create(rdev, NULL, size, true,
|
||||
RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i);
|
||||
r = radeon_bo_create(rdev, NULL, size, true,
|
||||
RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create GTT object %d\n", i);
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_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, >t_addr);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to pin GTT object %d\n", i);
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = radeon_object_kmap(gtt_obj[i], >t_map);
|
||||
r = radeon_bo_kmap(gtt_obj[i], >t_map);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to map GTT object %d\n", i);
|
||||
goto out_cleanup;
|
||||
@ -94,7 +98,7 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
gtt_start++)
|
||||
*gtt_start = gtt_start;
|
||||
|
||||
radeon_object_kunmap(gtt_obj[i]);
|
||||
radeon_bo_kunmap(gtt_obj[i]);
|
||||
|
||||
r = radeon_fence_create(rdev, &fence);
|
||||
if (r) {
|
||||
@ -116,7 +120,7 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
|
||||
radeon_fence_unref(&fence);
|
||||
|
||||
r = radeon_object_kmap(vram_obj, &vram_map);
|
||||
r = radeon_bo_kmap(vram_obj, &vram_map);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
|
||||
goto out_cleanup;
|
||||
@ -131,13 +135,13 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
"expected 0x%p (GTT map 0x%p-0x%p)\n",
|
||||
i, *vram_start, gtt_start, gtt_map,
|
||||
gtt_end);
|
||||
radeon_object_kunmap(vram_obj);
|
||||
radeon_bo_kunmap(vram_obj);
|
||||
goto out_cleanup;
|
||||
}
|
||||
*vram_start = vram_start;
|
||||
}
|
||||
|
||||
radeon_object_kunmap(vram_obj);
|
||||
radeon_bo_kunmap(vram_obj);
|
||||
|
||||
r = radeon_fence_create(rdev, &fence);
|
||||
if (r) {
|
||||
@ -159,7 +163,7 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
|
||||
radeon_fence_unref(&fence);
|
||||
|
||||
r = radeon_object_kmap(gtt_obj[i], >t_map);
|
||||
r = radeon_bo_kmap(gtt_obj[i], >t_map);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to map GTT object after copy %d\n", i);
|
||||
goto out_cleanup;
|
||||
@ -174,12 +178,12 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
"expected 0x%p (VRAM map 0x%p-0x%p)\n",
|
||||
i, *gtt_start, vram_start, vram_map,
|
||||
vram_end);
|
||||
radeon_object_kunmap(gtt_obj[i]);
|
||||
radeon_bo_kunmap(gtt_obj[i]);
|
||||
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",
|
||||
gtt_addr - rdev->mc.gtt_location);
|
||||
@ -187,14 +191,20 @@ void radeon_test_moves(struct radeon_device *rdev)
|
||||
|
||||
out_cleanup:
|
||||
if (vram_obj) {
|
||||
radeon_object_unpin(vram_obj);
|
||||
radeon_object_unref(&vram_obj);
|
||||
if (radeon_bo_is_reserved(vram_obj)) {
|
||||
radeon_bo_unpin(vram_obj);
|
||||
radeon_bo_unreserve(vram_obj);
|
||||
}
|
||||
radeon_bo_unref(&vram_obj);
|
||||
}
|
||||
if (gtt_obj) {
|
||||
for (i = 0; i < n; i++) {
|
||||
if (gtt_obj[i]) {
|
||||
radeon_object_unpin(gtt_obj[i]);
|
||||
radeon_object_unref(>t_obj[i]);
|
||||
if (radeon_bo_is_reserved(gtt_obj[i])) {
|
||||
radeon_bo_unpin(gtt_obj[i]);
|
||||
radeon_bo_unreserve(gtt_obj[i]);
|
||||
}
|
||||
radeon_bo_unref(>t_obj[i]);
|
||||
}
|
||||
}
|
||||
kfree(gtt_obj);
|
||||
@ -206,4 +216,3 @@ out_cleanup:
|
||||
printk(KERN_WARNING "Error while testing BO move.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
||||
man->default_caching = TTM_PL_FLAG_CACHED;
|
||||
break;
|
||||
case TTM_PL_TT:
|
||||
man->gpu_offset = 0;
|
||||
man->gpu_offset = rdev->mc.gtt_location;
|
||||
man->available_caching = TTM_PL_MASK_CACHING;
|
||||
man->default_caching = TTM_PL_FLAG_CACHED;
|
||||
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
|
||||
@ -180,7 +180,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
|
||||
break;
|
||||
case TTM_PL_VRAM:
|
||||
/* "On-card" video ram */
|
||||
man->gpu_offset = 0;
|
||||
man->gpu_offset = rdev->mc.vram_location;
|
||||
man->flags = TTM_MEMTYPE_FLAG_FIXED |
|
||||
TTM_MEMTYPE_FLAG_NEEDS_IOREMAP |
|
||||
TTM_MEMTYPE_FLAG_MAPPABLE;
|
||||
@ -482,27 +482,31 @@ int radeon_ttm_init(struct radeon_device *rdev)
|
||||
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0,
|
||||
((rdev->mc.real_vram_size) >> PAGE_SHIFT));
|
||||
r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM,
|
||||
0, rdev->mc.real_vram_size >> PAGE_SHIFT);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed initializing VRAM heap.\n");
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_create(rdev, NULL, 256 * 1024, true,
|
||||
RADEON_GEM_DOMAIN_VRAM, false,
|
||||
&rdev->stollen_vga_memory);
|
||||
r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
|
||||
RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->stollen_vga_memory);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
|
||||
r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
|
||||
if (r)
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
|
||||
radeon_bo_unreserve(rdev->stollen_vga_memory);
|
||||
if (r) {
|
||||
radeon_object_unref(&rdev->stollen_vga_memory);
|
||||
radeon_bo_unref(&rdev->stollen_vga_memory);
|
||||
return r;
|
||||
}
|
||||
DRM_INFO("radeon: %uM of VRAM memory ready\n",
|
||||
(unsigned)rdev->mc.real_vram_size / (1024 * 1024));
|
||||
r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
|
||||
((rdev->mc.gtt_size) >> PAGE_SHIFT));
|
||||
r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT,
|
||||
0, rdev->mc.gtt_size >> PAGE_SHIFT);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed initializing GTT heap.\n");
|
||||
return r;
|
||||
@ -523,9 +527,15 @@ int radeon_ttm_init(struct radeon_device *rdev)
|
||||
|
||||
void radeon_ttm_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->stollen_vga_memory) {
|
||||
radeon_object_unpin(rdev->stollen_vga_memory);
|
||||
radeon_object_unref(&rdev->stollen_vga_memory);
|
||||
r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
|
||||
if (r == 0) {
|
||||
radeon_bo_unpin(rdev->stollen_vga_memory);
|
||||
radeon_bo_unreserve(rdev->stollen_vga_memory);
|
||||
}
|
||||
radeon_bo_unref(&rdev->stollen_vga_memory);
|
||||
}
|
||||
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);
|
||||
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);
|
||||
|
@ -352,7 +352,7 @@ static int rs400_mc_init(struct radeon_device *rdev)
|
||||
u32 tmp;
|
||||
|
||||
/* Setup GPU memory space */
|
||||
tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
|
||||
tmp = RREG32(R_00015C_NB_TOM);
|
||||
rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
|
||||
rdev->mc.gtt_location = 0xFFFFFFFFUL;
|
||||
r = radeon_mc_setup(rdev);
|
||||
@ -387,13 +387,13 @@ static int rs400_startup(struct radeon_device *rdev)
|
||||
r300_clock_startup(rdev);
|
||||
/* Initialize GPU configuration (# pipes, ...) */
|
||||
rs400_gpu_init(rdev);
|
||||
r100_enable_bm(rdev);
|
||||
/* Initialize GART (initialize after TTM so we can allocate
|
||||
* memory through TTM but finalize after TTM) */
|
||||
r = rs400_gart_enable(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -452,7 +452,7 @@ void rs400_fini(struct radeon_device *rdev)
|
||||
rs400_gart_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -490,10 +490,9 @@ int rs400_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
radeon_combios_asic_init(rdev->ddev);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Get vram informations */
|
||||
@ -510,7 +509,7 @@ int rs400_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rs400_gart_init(rdev);
|
||||
|
@ -45,6 +45,21 @@
|
||||
void rs600_gpu_init(struct radeon_device *rdev);
|
||||
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
|
||||
int rs600_mc_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* read back the MC value from the hw */
|
||||
int r;
|
||||
u32 tmp;
|
||||
|
||||
/* Setup GPU memory space */
|
||||
tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
|
||||
rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
|
||||
rdev->mc.gtt_location = 0xffffffffUL;
|
||||
r = radeon_mc_setup(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* GART.
|
||||
*/
|
||||
@ -100,40 +115,40 @@ int rs600_gart_enable(struct radeon_device *rdev)
|
||||
WREG32(R_00004C_BUS_CNTL, tmp);
|
||||
/* FIXME: setup default page */
|
||||
WREG32_MC(R_000100_MC_PT0_CNTL,
|
||||
(S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
|
||||
S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
|
||||
(S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
|
||||
S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
|
||||
|
||||
for (i = 0; i < 19; i++) {
|
||||
WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
|
||||
S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
|
||||
S_00016C_SYSTEM_ACCESS_MODE_MASK(
|
||||
V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
|
||||
S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
|
||||
V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
|
||||
S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
|
||||
S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
|
||||
S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
|
||||
S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
|
||||
S_00016C_SYSTEM_ACCESS_MODE_MASK(
|
||||
V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) |
|
||||
S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
|
||||
V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) |
|
||||
S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) |
|
||||
S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
|
||||
S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3));
|
||||
}
|
||||
|
||||
/* System context map to GART space */
|
||||
WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
|
||||
WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
|
||||
|
||||
/* enable first context */
|
||||
WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
|
||||
WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
|
||||
WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
|
||||
S_000102_ENABLE_PAGE_TABLE(1) |
|
||||
S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
|
||||
S_000102_ENABLE_PAGE_TABLE(1) |
|
||||
S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
|
||||
|
||||
/* disable all other contexts */
|
||||
for (i = 1; i < 8; i++) {
|
||||
for (i = 1; i < 8; i++)
|
||||
WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
|
||||
}
|
||||
|
||||
/* setup the page table */
|
||||
WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
|
||||
rdev->gart.table_addr);
|
||||
rdev->gart.table_addr);
|
||||
WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
|
||||
WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
|
||||
WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
|
||||
|
||||
/* System context maps to VRAM space */
|
||||
WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start);
|
||||
WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end);
|
||||
|
||||
/* enable page tables */
|
||||
tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
|
||||
WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
|
||||
@ -146,15 +161,20 @@ int rs600_gart_enable(struct radeon_device *rdev)
|
||||
|
||||
void rs600_gart_disable(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
u32 tmp;
|
||||
int r;
|
||||
|
||||
/* FIXME: disable out of gart access */
|
||||
WREG32_MC(R_000100_MC_PT0_CNTL, 0);
|
||||
tmp = RREG32_MC(R_000009_MC_CNTL1);
|
||||
WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
|
||||
if (rdev->gart.table.vram.robj) {
|
||||
radeon_object_kunmap(rdev->gart.table.vram.robj);
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,9 +321,7 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
|
||||
void rs600_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: HDP same place on rs600 ? */
|
||||
r100_hdp_reset(rdev);
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
/* Wait for mc idle */
|
||||
if (rs600_mc_wait_for_idle(rdev))
|
||||
@ -312,9 +330,20 @@ void rs600_gpu_init(struct radeon_device *rdev)
|
||||
|
||||
void rs600_vram_info(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: to do or is these values sane ? */
|
||||
rdev->mc.vram_is_ddr = true;
|
||||
rdev->mc.vram_width = 128;
|
||||
|
||||
rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
|
||||
rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
|
||||
|
||||
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
|
||||
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
|
||||
|
||||
if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.mc_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->mc.real_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.real_vram_size = rdev->mc.aper_size;
|
||||
}
|
||||
|
||||
void rs600_bandwidth_update(struct radeon_device *rdev)
|
||||
@ -388,7 +417,6 @@ static int rs600_startup(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -445,7 +473,7 @@ void rs600_fini(struct radeon_device *rdev)
|
||||
rs600_gart_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -482,10 +510,9 @@ int rs600_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Initialize power management */
|
||||
@ -493,7 +520,7 @@ int rs600_init(struct radeon_device *rdev)
|
||||
/* Get vram informations */
|
||||
rs600_vram_info(rdev);
|
||||
/* Initialize memory controller (also test AGP) */
|
||||
r = r420_mc_init(rdev);
|
||||
r = rs600_mc_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rs600_debugfs(rdev);
|
||||
@ -505,7 +532,7 @@ int rs600_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rs600_gart_init(rdev);
|
||||
|
@ -131,24 +131,25 @@ void rs690_pm_info(struct radeon_device *rdev)
|
||||
|
||||
void rs690_vram_info(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
fixed20_12 a;
|
||||
|
||||
rs400_gart_adjust_size(rdev);
|
||||
/* DDR for all card after R300 & IGP */
|
||||
|
||||
rdev->mc.vram_is_ddr = true;
|
||||
/* FIXME: is this correct for RS690/RS740 ? */
|
||||
tmp = RREG32(RADEON_MEM_CNTL);
|
||||
if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
|
||||
rdev->mc.vram_width = 128;
|
||||
} else {
|
||||
rdev->mc.vram_width = 64;
|
||||
}
|
||||
rdev->mc.vram_width = 128;
|
||||
|
||||
rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
|
||||
rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
|
||||
|
||||
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
|
||||
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
|
||||
|
||||
if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.mc_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->mc.real_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.real_vram_size = rdev->mc.aper_size;
|
||||
|
||||
rs690_pm_info(rdev);
|
||||
/* FIXME: we should enforce default clock in case GPU is not in
|
||||
* default setup
|
||||
@ -161,6 +162,21 @@ void rs690_vram_info(struct radeon_device *rdev)
|
||||
rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
|
||||
}
|
||||
|
||||
static int rs690_mc_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
u32 tmp;
|
||||
|
||||
/* Setup GPU memory space */
|
||||
tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
|
||||
rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
|
||||
rdev->mc.gtt_location = 0xFFFFFFFFUL;
|
||||
r = radeon_mc_setup(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rs690_line_buffer_adjust(struct radeon_device *rdev,
|
||||
struct drm_display_mode *mode1,
|
||||
struct drm_display_mode *mode2)
|
||||
@ -605,7 +621,6 @@ static int rs690_startup(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -662,7 +677,7 @@ void rs690_fini(struct radeon_device *rdev)
|
||||
rs400_gart_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -700,10 +715,9 @@ int rs690_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Initialize power management */
|
||||
@ -711,7 +725,7 @@ int rs690_init(struct radeon_device *rdev)
|
||||
/* Get vram informations */
|
||||
rs690_vram_info(rdev);
|
||||
/* Initialize memory controller (also test AGP) */
|
||||
r = r420_mc_init(rdev);
|
||||
r = rs690_mc_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv515_debugfs(rdev);
|
||||
@ -723,7 +737,7 @@ int rs690_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rs400_gart_init(rdev);
|
||||
|
@ -478,7 +478,6 @@ static int rv515_startup(struct radeon_device *rdev)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
rs600_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
@ -540,11 +539,11 @@ void rv515_fini(struct radeon_device *rdev)
|
||||
r100_wb_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
rv370_pcie_gart_fini(rdev);
|
||||
rv370_pcie_gart_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
@ -580,10 +579,8 @@ int rv515_init(struct radeon_device *rdev)
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
if (radeon_boot_test_post_card(rdev) == false)
|
||||
return -EINVAL;
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Initialize power management */
|
||||
@ -603,7 +600,7 @@ int rv515_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rv370_pcie_gart_init(rdev);
|
||||
|
@ -92,7 +92,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
|
||||
void rv770_pcie_gart_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
int i;
|
||||
int i, r;
|
||||
|
||||
/* Disable all tables */
|
||||
for (i = 0; i < 7; i++)
|
||||
@ -113,8 +113,12 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
|
||||
WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
|
||||
if (rdev->gart.table.vram.robj) {
|
||||
radeon_object_kunmap(rdev->gart.table.vram.robj);
|
||||
radeon_object_unpin(rdev->gart.table.vram.robj);
|
||||
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -880,13 +884,26 @@ static int rv770_startup(struct radeon_device *rdev)
|
||||
}
|
||||
rv770_gpu_init(rdev);
|
||||
|
||||
r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->r600_blit.shader_gpu_addr);
|
||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->r600_blit.shader_gpu_addr);
|
||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||
if (r) {
|
||||
DRM_ERROR("failed to pin blit object %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Enable IRQ */
|
||||
r = r600_irq_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: IH init failed (%d).\n", r);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r600_irq_set(rdev);
|
||||
|
||||
r = radeon_ring_init(rdev, rdev->cp.ring_size);
|
||||
if (r)
|
||||
return r;
|
||||
@ -934,13 +951,19 @@ int rv770_resume(struct radeon_device *rdev)
|
||||
|
||||
int rv770_suspend(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* FIXME: we should wait for ring to be empty */
|
||||
r700_cp_stop(rdev);
|
||||
rdev->cp.ready = false;
|
||||
r600_wb_disable(rdev);
|
||||
rv770_pcie_gart_disable(rdev);
|
||||
/* unpin shaders bo */
|
||||
radeon_object_unpin(rdev->r600_blit.shader_obj);
|
||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_unpin(rdev->r600_blit.shader_obj);
|
||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -975,7 +998,11 @@ int rv770_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Post card if necessary */
|
||||
if (!r600_card_posted(rdev) && rdev->bios) {
|
||||
if (!r600_card_posted(rdev)) {
|
||||
if (!rdev->bios) {
|
||||
dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
@ -998,14 +1025,22 @@ int rv770_init(struct radeon_device *rdev)
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
r = radeon_bo_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = radeon_irq_kms_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
rdev->cp.ring_obj = NULL;
|
||||
r600_ring_init(rdev, 1024 * 1024);
|
||||
|
||||
if (!rdev->me_fw || !rdev->pfp_fw) {
|
||||
r = r600_cp_init_microcode(rdev);
|
||||
rdev->ih.ring_obj = NULL;
|
||||
r600_ih_ring_init(rdev, 64 * 1024);
|
||||
|
||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||
r = r600_init_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load firmware!\n");
|
||||
return r;
|
||||
@ -1051,6 +1086,8 @@ void rv770_fini(struct radeon_device *rdev)
|
||||
rv770_suspend(rdev);
|
||||
|
||||
r600_blit_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_ring_fini(rdev);
|
||||
r600_wb_fini(rdev);
|
||||
rv770_pcie_gart_fini(rdev);
|
||||
@ -1059,7 +1096,7 @@ void rv770_fini(struct radeon_device *rdev)
|
||||
radeon_clocks_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_AGP)
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user