diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/video/fbdev/aty | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/video/fbdev/aty')
-rw-r--r-- | kernel/drivers/video/fbdev/aty/aty128fb.c | 36 | ||||
-rw-r--r-- | kernel/drivers/video/fbdev/aty/atyfb.h | 5 | ||||
-rw-r--r-- | kernel/drivers/video/fbdev/aty/atyfb_base.c | 109 | ||||
-rw-r--r-- | kernel/drivers/video/fbdev/aty/radeon_base.c | 162 | ||||
-rw-r--r-- | kernel/drivers/video/fbdev/aty/radeonfb.h | 146 |
5 files changed, 210 insertions, 248 deletions
diff --git a/kernel/drivers/video/fbdev/aty/aty128fb.c b/kernel/drivers/video/fbdev/aty/aty128fb.c index 0156954bf..c42ce2fdf 100644 --- a/kernel/drivers/video/fbdev/aty/aty128fb.c +++ b/kernel/drivers/video/fbdev/aty/aty128fb.c @@ -80,10 +80,6 @@ #include <asm/btext.h> #endif /* CONFIG_BOOTX_TEXT */ -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif - #include <video/aty128.h> /* Debug flag */ @@ -399,10 +395,7 @@ static int default_cmode = CMODE_8; static int default_crt_on = 0; static int default_lcd_on = 1; - -#ifdef CONFIG_MTRR static bool mtrr = true; -#endif #ifdef CONFIG_FB_ATY128_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT @@ -456,9 +449,7 @@ struct aty128fb_par { u32 vram_size; /* onboard video ram */ int chip_gen; const struct aty128_meminfo *mem; /* onboard mem info */ -#ifdef CONFIG_MTRR - struct { int vram; int vram_valid; } mtrr; -#endif + int wc_cookie; int blitter_may_be_busy; int fifo_slots; /* free slots in FIFO (64 max) */ @@ -1725,12 +1716,10 @@ static int aty128fb_setup(char *options) #endif continue; } -#ifdef CONFIG_MTRR if(!strncmp(this_opt, "nomtrr", 6)) { mtrr = 0; continue; } -#endif #ifdef CONFIG_PPC_PMAC /* vmode and cmode deprecated */ if (!strncmp(this_opt, "vmode:", 6)) { @@ -2133,7 +2122,7 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF; /* Virtualize the framebuffer */ - info->screen_base = ioremap(fb_addr, par->vram_size); + info->screen_base = ioremap_wc(fb_addr, par->vram_size); if (!info->screen_base) goto err_unmap_out; @@ -2170,15 +2159,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!aty128_init(pdev, ent)) goto err_out; -#ifdef CONFIG_MTRR - if (mtrr) { - par->mtrr.vram = mtrr_add(info->fix.smem_start, - par->vram_size, MTRR_TYPE_WRCOMB, 1); - par->mtrr.vram_valid = 1; - /* let there be speed */ - printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n"); - } -#endif /* CONFIG_MTRR */ + if (mtrr) + par->wc_cookie = arch_phys_wc_add(info->fix.smem_start, + par->vram_size); return 0; err_out: @@ -2212,11 +2195,7 @@ static void aty128_remove(struct pci_dev *pdev) aty128_bl_exit(info->bl_dev); #endif -#ifdef CONFIG_MTRR - if (par->mtrr.vram_valid) - mtrr_del(par->mtrr.vram, info->fix.smem_start, - par->vram_size); -#endif /* CONFIG_MTRR */ + arch_phys_wc_del(par->wc_cookie); iounmap(par->regbase); iounmap(info->screen_base); @@ -2625,8 +2604,5 @@ MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards"); MODULE_LICENSE("GPL"); module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); -#ifdef CONFIG_MTRR module_param_named(nomtrr, mtrr, invbool, 0); MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)"); -#endif - diff --git a/kernel/drivers/video/fbdev/aty/atyfb.h b/kernel/drivers/video/fbdev/aty/atyfb.h index 1f39a62f8..63c4842eb 100644 --- a/kernel/drivers/video/fbdev/aty/atyfb.h +++ b/kernel/drivers/video/fbdev/aty/atyfb.h @@ -182,10 +182,7 @@ struct atyfb_par { unsigned long irq_flags; unsigned int irq; spinlock_t int_lock; -#ifdef CONFIG_MTRR - int mtrr_aper; - int mtrr_reg; -#endif + int wc_cookie; u32 mem_cntl; struct crtc saved_crtc; union aty_pll saved_pll; diff --git a/kernel/drivers/video/fbdev/aty/atyfb_base.c b/kernel/drivers/video/fbdev/aty/atyfb_base.c index 8789e487b..f34ed47fc 100644 --- a/kernel/drivers/video/fbdev/aty/atyfb_base.c +++ b/kernel/drivers/video/fbdev/aty/atyfb_base.c @@ -98,9 +98,6 @@ #ifdef CONFIG_PMAC_BACKLIGHT #include <asm/backlight.h> #endif -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif /* * Debug flags. @@ -303,9 +300,7 @@ static struct fb_ops atyfb_ops = { }; static bool noaccel; -#ifdef CONFIG_MTRR static bool nomtrr; -#endif static int vram; static int pll; static int mclk; @@ -427,6 +422,20 @@ static struct { #endif /* CONFIG_FB_ATY_CT */ }; +/* + * Last page of 8 MB (4 MB on ISA) aperture is MMIO, + * unless the auxiliary register aperture is used. + */ +static void aty_fudge_framebuffer_len(struct fb_info *info) +{ + struct atyfb_par *par = (struct atyfb_par *) info->par; + + if (!par->aux_start && + (info->fix.smem_len == 0x800000 || + (par->bus_type == ISA && info->fix.smem_len == 0x400000))) + info->fix.smem_len -= GUI_RESERVE; +} + static int correct_chipset(struct atyfb_par *par) { u8 rev; @@ -2603,14 +2612,7 @@ static int aty_init(struct fb_info *info) if (par->pll_ops->resume_pll) par->pll_ops->resume_pll(info, &par->pll); - /* - * Last page of 8 MB (4 MB on ISA) aperture is MMIO, - * unless the auxiliary register aperture is used. - */ - if (!par->aux_start && - (info->fix.smem_len == 0x800000 || - (par->bus_type == ISA && info->fix.smem_len == 0x400000))) - info->fix.smem_len -= GUI_RESERVE; + aty_fudge_framebuffer_len(info); /* * Disable register access through the linear aperture @@ -2621,25 +2623,13 @@ static int aty_init(struct fb_info *info) aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); -#ifdef CONFIG_MTRR - par->mtrr_aper = -1; - par->mtrr_reg = -1; - if (!nomtrr) { - /* Cover the whole resource. */ - par->mtrr_aper = mtrr_add(par->res_start, par->res_size, - MTRR_TYPE_WRCOMB, 1); - if (par->mtrr_aper >= 0 && !par->aux_start) { - /* Make a hole for mmio. */ - par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - - GUI_RESERVE, GUI_RESERVE, - MTRR_TYPE_UNCACHABLE, 1); - if (par->mtrr_reg < 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; - } - } - } -#endif + if (!nomtrr) + /* + * Only the ioremap_wc()'d area will get WC here + * since ioremap_uc() was used on the entire PCI BAR. + */ + par->wc_cookie = arch_phys_wc_add(par->res_start, + par->res_size); info->fbops = &atyfb_ops; info->pseudo_palette = par->pseudo_palette; @@ -2767,17 +2757,8 @@ aty_init_exit: /* restore video mode */ aty_set_crtc(par, &par->saved_crtc); par->pll_ops->set_pll(info, &par->saved_pll); + arch_phys_wc_del(par->wc_cookie); -#ifdef CONFIG_MTRR - if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; - } - if (par->mtrr_aper >= 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; - } -#endif return ret; } @@ -3459,7 +3440,11 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, } info->fix.mmio_start = raddr; - par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); + /* + * By using strong UC we force the MTRR to never have an + * effect on the MMIO region on both non-PAT and PAT systems. + */ + par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000); if (par->ati_regbase == NULL) return -ENOMEM; @@ -3482,7 +3467,24 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, /* Map in frame buffer */ info->fix.smem_start = addr; - info->screen_base = ioremap(addr, 0x800000); + + /* + * The framebuffer is not always 8 MiB, that's just the size of the + * PCI BAR. We temporarily abuse smem_len here to store the size + * of the BAR. aty_init() will later correct it to match the actual + * framebuffer size. + * + * On devices that don't have the auxiliary register aperture, the + * registers are housed at the top end of the framebuffer PCI BAR. + * aty_fudge_framebuffer_len() is used to reduce smem_len to not + * overlap with the registers. + */ + info->fix.smem_len = 0x800000; + + aty_fudge_framebuffer_len(info); + + info->screen_base = ioremap_wc(info->fix.smem_start, + info->fix.smem_len); if (info->screen_base == NULL) { ret = -ENOMEM; goto atyfb_setup_generic_fail; @@ -3554,6 +3556,7 @@ static int atyfb_pci_probe(struct pci_dev *pdev, return -ENOMEM; } par = info->par; + par->bus_type = PCI; info->fix = atyfb_fix; info->device = &pdev->dev; par->pci_id = pdev->device; @@ -3655,7 +3658,8 @@ static int __init atyfb_atari_probe(void) * Map the video memory (physical address given) * to somewhere in the kernel address space. */ - info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); + info->screen_base = ioremap_wc(phys_vmembase[m64_num], + phys_size[m64_num]); info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) + 0xFC00ul; @@ -3721,17 +3725,8 @@ static void atyfb_remove(struct fb_info *info) if (M64_HAS(MOBIL_BUS)) aty_bl_exit(info->bl_dev); #endif + arch_phys_wc_del(par->wc_cookie); -#ifdef CONFIG_MTRR - if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; - } - if (par->mtrr_aper >= 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; - } -#endif #ifndef __sparc__ if (par->ati_regbase) iounmap(par->ati_regbase); @@ -3847,10 +3842,8 @@ static int __init atyfb_setup(char *options) while ((this_opt = strsep(&options, ",")) != NULL) { if (!strncmp(this_opt, "noaccel", 7)) { noaccel = 1; -#ifdef CONFIG_MTRR } else if (!strncmp(this_opt, "nomtrr", 6)) { nomtrr = 1; -#endif } else if (!strncmp(this_opt, "vram:", 5)) vram = simple_strtoul(this_opt + 5, NULL, 0); else if (!strncmp(this_opt, "pll:", 4)) @@ -4020,7 +4013,5 @@ module_param(comp_sync, int, 0); MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)"); module_param(mode, charp, 0); MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); -#ifdef CONFIG_MTRR module_param(nomtrr, bool, 0); MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); -#endif diff --git a/kernel/drivers/video/fbdev/aty/radeon_base.c b/kernel/drivers/video/fbdev/aty/radeon_base.c index 01237c8fc..ce0b1d05a 100644 --- a/kernel/drivers/video/fbdev/aty/radeon_base.c +++ b/kernel/drivers/video/fbdev/aty/radeon_base.c @@ -85,10 +85,6 @@ #endif /* CONFIG_PPC */ -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif - #include <video/radeon.h> #include <linux/radeonfb.h> @@ -271,9 +267,7 @@ static bool mirror = 0; static int panel_yres = 0; static bool force_dfp = 0; static bool force_measure_pll = 0; -#ifdef CONFIG_MTRR static bool nomtrr = 0; -#endif static bool force_sleep; static bool ignore_devlist; #ifdef CONFIG_PMAC_BACKLIGHT @@ -282,9 +276,138 @@ static int backlight = 1; static int backlight = 0; #endif -/* - * prototypes +/* Note about this function: we have some rare cases where we must not schedule, + * this typically happen with our special "wake up early" hook which allows us to + * wake up the graphic chip (and thus get the console back) before everything else + * on some machines that support that mechanism. At this point, interrupts are off + * and scheduling is not permitted */ +void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) +{ + if (rinfo->no_schedule || oops_in_progress) + mdelay(ms); + else + msleep(ms); +} + +void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo) +{ + /* Called if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS) is set */ + (void)INREG(CLOCK_CNTL_DATA); + (void)INREG(CRTC_GEN_CNTL); +} + +void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo) +{ + if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) { + /* we can't deal with posted writes here ... */ + _radeon_msleep(rinfo, 5); + } + if (rinfo->errata & CHIP_ERRATA_R300_CG) { + u32 save, tmp; + save = INREG(CLOCK_CNTL_INDEX); + tmp = save & ~(0x3f | PLL_WR_EN); + OUTREG(CLOCK_CNTL_INDEX, tmp); + tmp = INREG(CLOCK_CNTL_DATA); + OUTREG(CLOCK_CNTL_INDEX, save); + } +} + +void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask) +{ + unsigned long flags; + unsigned int tmp; + + spin_lock_irqsave(&rinfo->reg_lock, flags); + tmp = INREG(addr); + tmp &= (mask); + tmp |= (val); + OUTREG(addr, tmp); + spin_unlock_irqrestore(&rinfo->reg_lock, flags); +} + +u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) +{ + u32 data; + + OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); + radeon_pll_errata_after_index(rinfo); + data = INREG(CLOCK_CNTL_DATA); + radeon_pll_errata_after_data(rinfo); + return data; +} + +void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val) +{ + OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); + radeon_pll_errata_after_index(rinfo); + OUTREG(CLOCK_CNTL_DATA, val); + radeon_pll_errata_after_data(rinfo); +} + +void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, + u32 val, u32 mask) +{ + unsigned int tmp; + + tmp = __INPLL(rinfo, index); + tmp &= (mask); + tmp |= (val); + __OUTPLL(rinfo, index, tmp); +} + +void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) +{ + int i; + + for (i=0; i<2000000; i++) { + if ((INREG(RBBM_STATUS) & 0x7f) >= entries) + return; + udelay(1); + } + printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); +} + +void radeon_engine_flush(struct radeonfb_info *rinfo) +{ + int i; + + /* Initiate flush */ + OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, + ~RB2D_DC_FLUSH_ALL); + + /* Ensure FIFO is empty, ie, make sure the flush commands + * has reached the cache + */ + _radeon_fifo_wait(rinfo, 64); + + /* Wait for the flush to complete */ + for (i=0; i < 2000000; i++) { + if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) + return; + udelay(1); + } + printk(KERN_ERR "radeonfb: Flush Timeout !\n"); +} + +void _radeon_engine_idle(struct radeonfb_info *rinfo) +{ + int i; + + /* ensure FIFO is empty before waiting for idle */ + _radeon_fifo_wait(rinfo, 64); + + for (i=0; i<2000000; i++) { + if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { + radeon_engine_flush(rinfo); + return; + } + udelay(1); + } + printk(KERN_ERR "radeonfb: Idle Timeout !\n"); +} + + static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) { @@ -2260,8 +2383,8 @@ static int radeonfb_pci_register(struct pci_dev *pdev, rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram); do { - rinfo->fb_base = ioremap (rinfo->fb_base_phys, - rinfo->mapped_vram); + rinfo->fb_base = ioremap_wc(rinfo->fb_base_phys, + rinfo->mapped_vram); } while (rinfo->fb_base == NULL && ((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM)); @@ -2359,11 +2482,9 @@ static int radeonfb_pci_register(struct pci_dev *pdev, goto err_unmap_fb; } -#ifdef CONFIG_MTRR - rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys, - rinfo->video_ram, - MTRR_TYPE_WRCOMB, 1); -#endif + if (!nomtrr) + rinfo->wc_cookie = arch_phys_wc_add(rinfo->fb_base_phys, + rinfo->video_ram); if (backlight) radeonfb_bl_init(rinfo); @@ -2428,12 +2549,7 @@ static void radeonfb_pci_unregister(struct pci_dev *pdev) #endif del_timer_sync(&rinfo->lvds_timer); - -#ifdef CONFIG_MTRR - if (rinfo->mtrr_hdl >= 0) - mtrr_del(rinfo->mtrr_hdl, 0, 0); -#endif - + arch_phys_wc_del(rinfo->wc_cookie); unregister_framebuffer(info); radeonfb_bl_exit(rinfo); @@ -2489,10 +2605,8 @@ static int __init radeonfb_setup (char *options) panel_yres = simple_strtoul((this_opt+11), NULL, 0); } else if (!strncmp(this_opt, "backlight:", 10)) { backlight = simple_strtoul(this_opt+10, NULL, 0); -#ifdef CONFIG_MTRR } else if (!strncmp(this_opt, "nomtrr", 6)) { nomtrr = 1; -#endif } else if (!strncmp(this_opt, "nomodeset", 9)) { nomodeset = 1; } else if (!strncmp(this_opt, "force_measure_pll", 17)) { @@ -2552,10 +2666,8 @@ module_param(monitor_layout, charp, 0); MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); module_param(force_measure_pll, bool, 0); MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); -#ifdef CONFIG_MTRR module_param(nomtrr, bool, 0); MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); -#endif module_param(panel_yres, int, 0); MODULE_PARM_DESC(panel_yres, "int: set panel yres"); module_param(mode_option, charp, 0); diff --git a/kernel/drivers/video/fbdev/aty/radeonfb.h b/kernel/drivers/video/fbdev/aty/radeonfb.h index 039def41c..962e31263 100644 --- a/kernel/drivers/video/fbdev/aty/radeonfb.h +++ b/kernel/drivers/video/fbdev/aty/radeonfb.h @@ -340,7 +340,7 @@ struct radeonfb_info { struct pll_info pll; - int mtrr_hdl; + int wc_cookie; u32 save_regs[100]; int asleep; @@ -370,20 +370,7 @@ struct radeonfb_info { * IO macros */ -/* Note about this function: we have some rare cases where we must not schedule, - * this typically happen with our special "wake up early" hook which allows us to - * wake up the graphic chip (and thus get the console back) before everything else - * on some machines that support that mechanism. At this point, interrupts are off - * and scheduling is not permitted - */ -static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) -{ - if (rinfo->no_schedule || oops_in_progress) - mdelay(ms); - else - msleep(ms); -} - +void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms); #define INREG8(addr) readb((rinfo->mmio_base)+addr) #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) @@ -392,19 +379,7 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) #define INREG(addr) readl((rinfo->mmio_base)+addr) #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) -static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, - u32 val, u32 mask) -{ - unsigned long flags; - unsigned int tmp; - - spin_lock_irqsave(&rinfo->reg_lock, flags); - tmp = INREG(addr); - tmp &= (mask); - tmp |= (val); - OUTREG(addr, tmp); - spin_unlock_irqrestore(&rinfo->reg_lock, flags); -} +void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask); #define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask) @@ -425,64 +400,24 @@ static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, * possible exception to this rule is the call to unblank(), which may * be done at irq time if an oops is in progress. */ +void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo); static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo) { - if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)) - return; - - (void)INREG(CLOCK_CNTL_DATA); - (void)INREG(CRTC_GEN_CNTL); + if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS) + radeon_pll_errata_after_index_slow(rinfo); } +void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo); static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo) { - if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) { - /* we can't deal with posted writes here ... */ - _radeon_msleep(rinfo, 5); - } - if (rinfo->errata & CHIP_ERRATA_R300_CG) { - u32 save, tmp; - save = INREG(CLOCK_CNTL_INDEX); - tmp = save & ~(0x3f | PLL_WR_EN); - OUTREG(CLOCK_CNTL_INDEX, tmp); - tmp = INREG(CLOCK_CNTL_DATA); - OUTREG(CLOCK_CNTL_INDEX, save); - } -} - -static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) -{ - u32 data; - - OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); - radeon_pll_errata_after_index(rinfo); - data = INREG(CLOCK_CNTL_DATA); - radeon_pll_errata_after_data(rinfo); - return data; -} - -static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, - u32 val) -{ - - OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); - radeon_pll_errata_after_index(rinfo); - OUTREG(CLOCK_CNTL_DATA, val); - radeon_pll_errata_after_data(rinfo); -} - - -static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, - u32 val, u32 mask) -{ - unsigned int tmp; - - tmp = __INPLL(rinfo, index); - tmp &= (mask); - tmp |= (val); - __OUTPLL(rinfo, index, tmp); + if (rinfo->errata & (CHIP_ERRATA_PLL_DELAY|CHIP_ERRATA_R300_CG)) + radeon_pll_errata_after_data_slow(rinfo); } +u32 __INPLL(struct radeonfb_info *rinfo, u32 addr); +void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val); +void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, + u32 val, u32 mask); #define INPLL(addr) __INPLL(rinfo, addr) #define OUTPLL(index, val) __OUTPLL(rinfo, index, val) @@ -532,58 +467,9 @@ static inline u32 radeon_get_dstbpp(u16 depth) * 2D Engine helper routines */ -static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) -{ - int i; - - for (i=0; i<2000000; i++) { - if ((INREG(RBBM_STATUS) & 0x7f) >= entries) - return; - udelay(1); - } - printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); -} - -static inline void radeon_engine_flush (struct radeonfb_info *rinfo) -{ - int i; - - /* Initiate flush */ - OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, - ~RB2D_DC_FLUSH_ALL); - - /* Ensure FIFO is empty, ie, make sure the flush commands - * has reached the cache - */ - _radeon_fifo_wait (rinfo, 64); - - /* Wait for the flush to complete */ - for (i=0; i < 2000000; i++) { - if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) - return; - udelay(1); - } - printk(KERN_ERR "radeonfb: Flush Timeout !\n"); -} - - -static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) -{ - int i; - - /* ensure FIFO is empty before waiting for idle */ - _radeon_fifo_wait (rinfo, 64); - - for (i=0; i<2000000; i++) { - if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { - radeon_engine_flush (rinfo); - return; - } - udelay(1); - } - printk(KERN_ERR "radeonfb: Idle Timeout !\n"); -} - +void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries); +void radeon_engine_flush(struct radeonfb_info *rinfo); +void _radeon_engine_idle(struct radeonfb_info *rinfo); #define radeon_engine_idle() _radeon_engine_idle(rinfo) #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) |