|
|
@@ -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)
|