/** *avivo_wait_for_vblank-vblankwaitasiccallback. * *@rdev:radeon_devicepointer *@crtc:crtctowaitforvblankon * *Waitforvblankontherequestedcrtc(r5xx-r7xx).
*/ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{ unsigned i = 0;
if (crtc >= rdev->num_crtc) return;
if (!(RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN)) return;
/* depending on when we hit vblank, we may be close to active; if so, *waitforanotherframe.
*/ while (avivo_is_in_vblank(rdev, crtc)) { if (i++ % 100 == 0) { if (!avivo_is_counter_moving(rdev, crtc)) break;
}
}
while (!avivo_is_in_vblank(rdev, crtc)) { if (i++ % 100 == 0) { if (!avivo_is_counter_moving(rdev, crtc)) break;
}
}
}
/* Wait for update_pending to go high. */ for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */
tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
}
/* 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);
status = rs600_irq_ack(rdev); if (!status &&
!rdev->irq.stat_regs.r500.disp_int &&
!rdev->irq.stat_regs.r500.hdmi0_status) { return IRQ_NONE;
} while (status ||
rdev->irq.stat_regs.r500.disp_int ||
rdev->irq.stat_regs.r500.hdmi0_status) { /* SW interrupt */ if (G_000044_SW_INT(status)) {
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
} /* Vertical blank interrupts */ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { if (rdev->irq.crtc_vblank_int[0]) {
drm_handle_vblank(rdev_to_drm(rdev), 0);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
} if (atomic_read(&rdev->irq.pflip[0]))
radeon_crtc_handle_vblank(rdev, 0);
} if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { if (rdev->irq.crtc_vblank_int[1]) {
drm_handle_vblank(rdev_to_drm(rdev), 1);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
} if (atomic_read(&rdev->irq.pflip[1]))
radeon_crtc_handle_vblank(rdev, 1);
} if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
queue_hotplug = true;
DRM_DEBUG("HPD1\n");
} if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
queue_hotplug = true;
DRM_DEBUG("HPD2\n");
} if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) {
queue_hdmi = true;
DRM_DEBUG("HDMI0\n");
}
status = rs600_irq_ack(rdev);
} if (queue_hotplug)
schedule_delayed_work(&rdev->hotplug_work, 0); if (queue_hdmi)
schedule_work(&rdev->audio_work); if (rdev->msi_enabled) { switch (rdev->family) { case CHIP_RS600: case CHIP_RS690: case CHIP_RS740:
msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM;
WREG32(RADEON_BUS_CNTL, msi_rearm);
WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); break; default:
WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); break;
}
} return IRQ_HANDLED;
}
u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc)
{ if (crtc == 0) return RREG32(R_0060A4_D1CRTC_STATUS_FRAME_COUNT); else return RREG32(R_0068A4_D2CRTC_STATUS_FRAME_COUNT);
}
int rs600_mc_wait_for_idle(struct radeon_device *rdev)
{ unsigned i;
for (i = 0; i < rdev->usec_timeout; i++) { if (G_000000_MC_IDLE(RREG32_MC(R_000000_MC_STATUS))) return0;
udelay(1);
} return -1;
}
staticvoid rs600_gpu_init(struct radeon_device *rdev)
{
r420_pipes_init(rdev); /* Wait for mc idle */ if (rs600_mc_wait_for_idle(rdev))
dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
}
if (!rdev->mode_info.mode_config_initialized) return;
radeon_update_display_priority(rdev);
if (rdev->mode_info.crtcs[0]->base.enabled)
mode0 = &rdev->mode_info.crtcs[0]->base.mode; if (rdev->mode_info.crtcs[1]->base.enabled)
mode1 = &rdev->mode_info.crtcs[1]->base.mode;
/* Stops all mc clients */
rv515_mc_stop(rdev, &save);
/* Wait for mc idle */ if (rs600_mc_wait_for_idle(rdev))
dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
/* FIXME: What does AGP means for such chipset ? */
WREG32_MC(R_000005_MC_AGP_LOCATION, 0x0FFFFFFF);
WREG32_MC(R_000006_AGP_BASE, 0);
WREG32_MC(R_000007_AGP_BASE_2, 0); /* Program MC */
WREG32_MC(R_000004_MC_FB_LOCATION,
S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
WREG32(R_000134_HDP_FB_LOCATION,
S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
rv515_mc_resume(rdev, &save);
}
staticint rs600_startup(struct radeon_device *rdev)
{ int r;
rs600_mc_program(rdev); /* Resume clock */
rv515_clock_startup(rdev); /* Initialize GPU configuration (# pipes, ...) */
rs600_gpu_init(rdev); /* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */
r = rs600_gart_enable(rdev); if (r) return r;
/* allocate wb buffer */
r = radeon_wb_init(rdev); if (r) return r;
r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) {
dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); return r;
}
/* Enable IRQ */ if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev); if (r) return r;
}
rs600_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024); if (r) {
dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r;
}
r = radeon_ib_pool_init(rdev); if (r) {
dev_err(rdev->dev, "IB initialization failed (%d).\n", r); return r;
}
r = radeon_audio_init(rdev); if (r) {
dev_err(rdev->dev, "failed initializing audio\n"); return r;
}
return0;
}
int rs600_resume(struct radeon_device *rdev)
{ int r;
/* Make sur GART are not working */
rs600_gart_disable(rdev); /* Resume clock before doing reset */
rv515_clock_startup(rdev); /* Reset gpu before posting otherwise ATOM will enter infinite loop */ if (radeon_asic_reset(rdev)) {
dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
RREG32(R_000E40_RBBM_STATUS),
RREG32(R_0007C0_CP_STAT));
} /* post */
atom_asic_init(rdev->mode_info.atom_context); /* Resume clock after posting */
rv515_clock_startup(rdev); /* Initialize surface registers */
radeon_surface_init(rdev);
rdev->accel_working = true;
r = rs600_startup(rdev); if (r) {
rdev->accel_working = false;
} return r;
}
int rs600_init(struct radeon_device *rdev)
{ int r;
/* Disable VGA */
rv515_vga_render_disable(rdev); /* Initialize scratch registers */
radeon_scratch_init(rdev); /* Initialize surface registers */
radeon_surface_init(rdev); /* restore some register to sane defaults */
r100_restore_sanity(rdev); /* BIOS */ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) return -EINVAL;
} if (rdev->is_atom_bios) {
r = radeon_atombios_init(rdev); if (r) return r;
} else {
dev_err(rdev->dev, "Expecting atombios for RS600 GPU\n"); return -EINVAL;
} /* Reset gpu before posting otherwise ATOM will enter infinite loop */ if (radeon_asic_reset(rdev)) {
dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
RREG32(R_000E40_RBBM_STATUS),
RREG32(R_0007C0_CP_STAT));
} /* check if cards are posted or not */ if (radeon_boot_test_post_card(rdev) == false) return -EINVAL;
/* Initialize clocks */
radeon_get_clock_info(rdev_to_drm(rdev)); /* initialize memory controller */
rs600_mc_init(rdev);
r100_debugfs_rbbm_init(rdev); /* Fence driver */
radeon_fence_driver_init(rdev); /* Memory manager */
r = radeon_bo_init(rdev); if (r) return r;
r = rs600_gart_init(rdev); if (r) return r;
rs600_set_safe_registers(rdev);
/* Initialize power management */
radeon_pm_init(rdev);
rdev->accel_working = true;
r = rs600_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */
dev_err(rdev->dev, "Disabling GPU acceleration\n");
r100_cp_fini(rdev);
radeon_wb_fini(rdev);
radeon_ib_pool_fini(rdev);
rs600_gart_fini(rdev);
radeon_irq_kms_fini(rdev);
rdev->accel_working = false;
} return0;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.5Bemerkung:
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.