From cd414bd424647cccbe47bd6c0440400dcefd328a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 29 Jun 2010 20:46:46 -0400 Subject: [PATCH] drm/radeon/kms: use io ports for combios asic init This may fix s/r issues on some combios systems. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r100.c | 7 +-- drivers/gpu/drm/radeon/radeon.h | 49 +++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_combios.c | 73 +++++++++++++++---------------- 3 files changed, 87 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a4f7590..0b77c55 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2365,11 +2365,10 @@ void r100_mc_init(struct radeon_device *rdev) */ void r100_pll_errata_after_index(struct radeon_device *rdev) { - if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { - return; + if ((rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { + (void)RREG32(RADEON_CLOCK_CNTL_DATA); + (void)RREG32(RADEON_CRTC_GEN_CNTL); } - (void)RREG32(RADEON_CLOCK_CNTL_DATA); - (void)RREG32(RADEON_CRTC_GEN_CNTL); } static void r100_pll_errata_after_data(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 35f0800..57643db 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1175,6 +1175,55 @@ static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) #define RREG32_IO(reg) r100_io_rreg(rdev, (reg)) #define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v)) +static inline u32 r100_pll_io_rreg(struct radeon_device *rdev, u32 reg) +{ + u32 data; + + iowrite8((reg & 0x3f), rdev->rio_mem + RADEON_CLOCK_CNTL_INDEX); + if ((rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { + (void)RREG32_IO(RADEON_CLOCK_CNTL_DATA); + (void)RREG32_IO(RADEON_CRTC_GEN_CNTL); + } + data = RREG32_IO(RADEON_CLOCK_CNTL_DATA); + if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) + udelay(5000); + if (rdev->pll_errata & CHIP_ERRATA_R300_CG) { + u32 save, tmp; + + save = RREG32_IO(RADEON_CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | RADEON_PLL_WR_EN); + WREG32_IO(RADEON_CLOCK_CNTL_INDEX, tmp); + tmp = RREG32_IO(RADEON_CLOCK_CNTL_DATA); + WREG32_IO(RADEON_CLOCK_CNTL_INDEX, save); + } + return data; +} + +static inline void r100_pll_io_wreg(struct radeon_device *rdev, u32 reg, uint32_t v) +{ + iowrite8(((reg & 0x3f) | RADEON_PLL_WR_EN), + rdev->rio_mem + RADEON_CLOCK_CNTL_INDEX); + if ((rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { + (void)RREG32_IO(RADEON_CLOCK_CNTL_DATA); + (void)RREG32_IO(RADEON_CRTC_GEN_CNTL); + } + WREG32_IO(RADEON_CLOCK_CNTL_DATA, v); + if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) + udelay(5000); + if (rdev->pll_errata & CHIP_ERRATA_R300_CG) { + u32 save, tmp; + + save = RREG32_IO(RADEON_CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | RADEON_PLL_WR_EN); + WREG32_IO(RADEON_CLOCK_CNTL_INDEX, tmp); + tmp = RREG32_IO(RADEON_CLOCK_CNTL_DATA); + WREG32_IO(RADEON_CLOCK_CNTL_INDEX, save); + } +} + +#define RREG32_PLL_IO(reg) r100_pll_io_rreg(rdev, (reg)) +#define WREG32_PLL_IO(reg, v) r100_pll_io_wreg(rdev, (reg), (v)) + /* * Indirect registers accessor */ diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 729e2f5..55ac008 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2695,32 +2695,32 @@ static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) case 0: val = RBIOS32(offset); offset += 4; - WREG32(addr, val); + WREG32_IO(addr, val); break; case 1: val = RBIOS32(offset); offset += 4; - WREG32(addr, val); + WREG32_IO(addr, val); break; case 2: and_mask = RBIOS32(offset); offset += 4; or_mask = RBIOS32(offset); offset += 4; - tmp = RREG32(addr); + tmp = RREG32_IO(addr); tmp &= and_mask; tmp |= or_mask; - WREG32(addr, tmp); + WREG32_IO(addr, tmp); break; case 3: and_mask = RBIOS32(offset); offset += 4; or_mask = RBIOS32(offset); offset += 4; - tmp = RREG32(addr); + tmp = RREG32_IO(addr); tmp &= and_mask; tmp |= or_mask; - WREG32(addr, tmp); + WREG32_IO(addr, tmp); break; case 4: val = RBIOS16(offset); @@ -2734,7 +2734,7 @@ static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) case 8: while (val--) { if (! - (RREG32_PLL + (RREG32_PLL_IO (RADEON_CLK_PWRMGT_CNTL) & RADEON_MC_BUSY)) break; @@ -2742,7 +2742,7 @@ static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) break; case 9: while (val--) { - if ((RREG32(RADEON_MC_STATUS) & + if ((RREG32_IO(RADEON_MC_STATUS) & RADEON_MC_IDLE)) break; } @@ -2774,7 +2774,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) case 0: val = RBIOS32(offset); offset += 4; - WREG32_PLL(addr, val); + WREG32_PLL_IO(addr, val); break; case 1: shift = RBIOS8(offset) * 8; @@ -2784,10 +2784,10 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) offset++; or_mask = RBIOS8(offset) << shift; offset++; - tmp = RREG32_PLL(addr); + tmp = RREG32_PLL_IO(addr); tmp &= and_mask; tmp |= or_mask; - WREG32_PLL(addr, tmp); + WREG32_PLL_IO(addr, tmp); break; case 2: case 3: @@ -2802,7 +2802,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) case 3: while (tmp--) { if (! - (RREG32_PLL + (RREG32_PLL_IO (RADEON_CLK_PWRMGT_CNTL) & RADEON_MC_BUSY)) break; @@ -2810,7 +2810,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) break; case 4: while (tmp--) { - if (RREG32_PLL + if (RREG32_PLL_IO (RADEON_CLK_PWRMGT_CNTL) & RADEON_DLL_READY) break; @@ -2818,19 +2818,19 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) break; case 5: tmp = - RREG32_PLL(RADEON_CLK_PWRMGT_CNTL); + RREG32_PLL_IO(RADEON_CLK_PWRMGT_CNTL); if (tmp & RADEON_CG_NO1_DEBUG_0) { #if 0 uint32_t mclk_cntl = - RREG32_PLL + RREG32_PLL_IO (RADEON_MCLK_CNTL); mclk_cntl &= 0xffff0000; /*mclk_cntl |= 0x00001111;*//* ??? */ - WREG32_PLL(RADEON_MCLK_CNTL, + WREG32_PLL_IO(RADEON_MCLK_CNTL, mclk_cntl); udelay(10000); #endif - WREG32_PLL + WREG32_PLL_IO (RADEON_CLK_PWRMGT_CNTL, tmp & ~RADEON_CG_NO1_DEBUG_0); @@ -2870,7 +2870,7 @@ static void combios_parse_ram_reset_table(struct drm_device *dev, RADEON_MEM_PWRUP_COMPLETE; tmp = 20000; while (tmp--) { - if ((RREG32(RADEON_MEM_STR_CNTL) & + if ((RREG32_IO(RADEON_MEM_STR_CNTL) & channel_complete_mask) == channel_complete_mask) break; @@ -2879,16 +2879,16 @@ static void combios_parse_ram_reset_table(struct drm_device *dev, uint32_t or_mask = RBIOS16(offset); offset += 2; - tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); + tmp = RREG32_IO(RADEON_MEM_SDRAM_MODE_REG); tmp &= RADEON_SDRAM_MODE_MASK; tmp |= or_mask; - WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); + WREG32_IO(RADEON_MEM_SDRAM_MODE_REG, tmp); or_mask = val << 24; - tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); + tmp = RREG32_IO(RADEON_MEM_SDRAM_MODE_REG); tmp &= RADEON_B3MEM_RESET_MASK; tmp |= or_mask; - WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); + WREG32_IO(RADEON_MEM_SDRAM_MODE_REG, tmp); } val = RBIOS8(offset); } @@ -2903,14 +2903,14 @@ static uint32_t combios_detect_ram(struct drm_device *dev, int ram, uint32_t mem_size; uint32_t addr = 0; - mem_cntl = RREG32(RADEON_MEM_CNTL); + mem_cntl = RREG32_IO(RADEON_MEM_CNTL); if (mem_cntl & RV100_HALF_MODE) ram /= 2; mem_size = ram; mem_cntl &= ~(0xff << 8); mem_cntl |= (mem_addr_mapping & 0xff) << 8; - WREG32(RADEON_MEM_CNTL, mem_cntl); - RREG32(RADEON_MEM_CNTL); + WREG32_IO(RADEON_MEM_CNTL, mem_cntl); + RREG32_IO(RADEON_MEM_CNTL); /* sdram reset ? */ @@ -2918,11 +2918,11 @@ static uint32_t combios_detect_ram(struct drm_device *dev, int ram, while (ram--) { addr = ram * 1024 * 1024; /* write to each page */ - WREG32(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); - WREG32(RADEON_MM_DATA, 0xdeadbeef); + WREG32_IO(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); + WREG32_IO(RADEON_MM_DATA, 0xdeadbeef); /* read back and verify */ - WREG32(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); - if (RREG32(RADEON_MM_DATA) != 0xdeadbeef) + WREG32_IO(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); + if (RREG32_IO(RADEON_MM_DATA) != 0xdeadbeef) return 0; } @@ -2948,10 +2948,9 @@ static void combios_write_ram_size(struct drm_device *dev) if (rev < 3) { mem_cntl = RBIOS32(offset + 1); mem_size = RBIOS16(offset + 5); - if (((rdev->flags & RADEON_FAMILY_MASK) < CHIP_R200) && - ((dev->pdev->device != 0x515e) - && (dev->pdev->device != 0x5969))) - WREG32(RADEON_MEM_CNTL, mem_cntl); + if ((rdev->family < CHIP_R200) && + !ASIC_IS_RN50(rdev)) + WREG32_IO(RADEON_MEM_CNTL, mem_cntl); } } @@ -2961,10 +2960,8 @@ static void combios_write_ram_size(struct drm_device *dev) if (offset) { rev = RBIOS8(offset - 1); if (rev < 1) { - if (((rdev->flags & RADEON_FAMILY_MASK) < - CHIP_R200) - && ((dev->pdev->device != 0x515e) - && (dev->pdev->device != 0x5969))) { + if ((rdev->family < CHIP_R200) && + !ASIC_IS_RN50(rdev)) { int ram = 0; int mem_addr_mapping = 0; @@ -2991,7 +2988,7 @@ static void combios_write_ram_size(struct drm_device *dev) } mem_size *= (1024 * 1024); /* convert to bytes */ - WREG32(RADEON_CONFIG_MEMSIZE, mem_size); + WREG32_IO(RADEON_CONFIG_MEMSIZE, mem_size); } void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable) -- 1.7.0.1