drivers/gpu/drm/radeon/rs400.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/rs400.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/radeon/rs400.c- Extension
.c- Size
- 16581 bytes
- Lines
- 600
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/debugfs.hlinux/seq_file.hlinux/slab.hdrm/drm_device.hdrm/drm_file.hradeon.hradeon_asic.hrs400d.h
Detected Declarations
function rs400_gart_adjust_sizefunction rs400_gart_tlb_flushfunction rs400_gart_initfunction rs400_gart_enablefunction rs400_gart_disablefunction rs400_gart_finifunction rs400_gart_get_page_entryfunction rs400_gart_set_pagefunction rs400_mc_wait_for_idlefunction rs400_gpu_initfunction rs400_mc_initfunction rs400_mc_rregfunction rs400_mc_wregfunction rs400_debugfs_gart_info_showfunction rs400_debugfs_pcie_gart_info_initfunction rs400_mc_programfunction rs400_startupfunction rs400_resumefunction rs400_suspendfunction rs400_finifunction rs400_init
Annotated Snippet
if (tmp & RADEON_MC_IDLE) {
return 0;
}
udelay(1);
}
return -1;
}
static void rs400_gpu_init(struct radeon_device *rdev)
{
/* Earlier code was calling r420_pipes_init and then
* rs400_mc_wait_for_idle(rdev). The problem is that
* at least on my Mobility Radeon Xpress 200M RC410 card
* that ends up in this code path ends up num_gb_pipes == 3
* while the card seems to have only one pipe. With the
* r420 pipe initialization method.
*
* Problems shown up as HyperZ glitches, see:
* https://bugs.freedesktop.org/show_bug.cgi?id=110897
*
* Delegating initialization to r300 code seems to work
* and results in proper pipe numbers. The rs400 cards
* are said to be not r400, but r300 kind of cards.
*/
r300_gpu_init(rdev);
if (rs400_mc_wait_for_idle(rdev)) {
pr_warn("rs400: Failed to wait MC idle while programming pipes. Bad things might happen. %08x\n",
RREG32(RADEON_MC_STATUS));
}
}
static void rs400_mc_init(struct radeon_device *rdev)
{
u64 base;
rs400_gart_adjust_size(rdev);
rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
/* DDR for all card after R300 & IGP */
rdev->mc.vram_is_ddr = true;
rdev->mc.vram_width = 128;
r100_vram_init_sizes(rdev);
base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev);
}
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
unsigned long flags;
uint32_t r;
spin_lock_irqsave(&rdev->mc_idx_lock, flags);
WREG32(RS480_NB_MC_INDEX, reg & 0xff);
r = RREG32(RS480_NB_MC_DATA);
WREG32(RS480_NB_MC_INDEX, 0xff);
spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);
return r;
}
void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
unsigned long flags;
spin_lock_irqsave(&rdev->mc_idx_lock, flags);
WREG32(RS480_NB_MC_INDEX, ((reg) & 0xff) | RS480_NB_MC_IND_WR_EN);
WREG32(RS480_NB_MC_DATA, (v));
WREG32(RS480_NB_MC_INDEX, 0xff);
spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);
}
#if defined(CONFIG_DEBUG_FS)
static int rs400_debugfs_gart_info_show(struct seq_file *m, void *unused)
{
struct radeon_device *rdev = m->private;
uint32_t tmp;
tmp = RREG32(RADEON_HOST_PATH_CNTL);
seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp);
tmp = RREG32(RADEON_BUS_CNTL);
seq_printf(m, "BUS_CNTL 0x%08x\n", tmp);
tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
seq_printf(m, "AIC_CTRL_SCRATCH 0x%08x\n", tmp);
if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {
tmp = RREG32_MC(RS690_MCCFG_AGP_BASE);
seq_printf(m, "MCCFG_AGP_BASE 0x%08x\n", tmp);
tmp = RREG32_MC(RS690_MCCFG_AGP_BASE_2);
seq_printf(m, "MCCFG_AGP_BASE_2 0x%08x\n", tmp);
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/seq_file.h`, `linux/slab.h`, `drm/drm_device.h`, `drm/drm_file.h`, `radeon.h`, `radeon_asic.h`, `rs400d.h`.
- Detected declarations: `function rs400_gart_adjust_size`, `function rs400_gart_tlb_flush`, `function rs400_gart_init`, `function rs400_gart_enable`, `function rs400_gart_disable`, `function rs400_gart_fini`, `function rs400_gart_get_page_entry`, `function rs400_gart_set_page`, `function rs400_mc_wait_for_idle`, `function rs400_gpu_init`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.