aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2015-09-23 13:57:53 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-10-08 05:24:12 -0400
commit08bfb453f0458dd353f37737d80475ff13868d9c (patch)
treea41511f29a6c901b88d2227d42041b3c4de42668
parent2035608e126f4ddc6a48f6b04ef967f89db460e1 (diff)
radeonfb: Deinline large functions
With this .config: http://busybox.net/~vda/kernel_config, after uninlining these functions have sizes and callsite counts as follows: __OUTPLLP: 61 bytes, 12 callsites __INPLL: 79 bytes, 150 callsites __OUTPLL: 82 bytes, 138 callsites _OUTREGP: 101 bytes, 8 callsites _radeon_msleep: 66 bytes, 18 callsites _radeon_fifo_wait: 83 bytes, 24 callsites _radeon_engine_idle: 92 bytes, 10 callsites radeon_engine_flush: 105 bytes, 2 callsites radeon_pll_errata_after_index_slow: 31 bytes, 11 callsites radeon_pll_errata_after_data_slow: 91 bytes, 9 callsites radeon_pll_errata_after_FOO functions are split into two parts: the inlined part which checks corresponding rinfo->errata bit, and out-of-line part which performs workaround magic per se. Reduction in code size is about 49,500 bytes: text data bss dec hex filename 85789648 22294616 20627456 128711720 7abfc28 vmlinux.before 85740176 22294680 20627456 128662312 7ab3b28 vmlinux Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: Richard Purdie <rpurdie@rpsys.net> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: David Airlie <airlied@linux.ie> Cc: Alex Deucher <alexdeucher@gmail.com> Cc: Ben Skeggs <bskeggs@redhat.com> Cc: Zhang Rui <rui.zhang@intel.com> Cc: Len Brown <lenb@kernel.org> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Dave Airlie <airlied@redhat.com> Cc: linux-kernel@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/fbdev/aty/radeon_base.c133
-rw-r--r--drivers/video/fbdev/aty/radeonfb.h144
2 files changed, 146 insertions, 131 deletions
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 2bdb070707e4..ce0b1d05a388 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -276,9 +276,138 @@ static int backlight = 1;
276static int backlight = 0; 276static int backlight = 0;
277#endif 277#endif
278 278
279/* 279/* Note about this function: we have some rare cases where we must not schedule,
280 * prototypes 280 * this typically happen with our special "wake up early" hook which allows us to
281 * wake up the graphic chip (and thus get the console back) before everything else
282 * on some machines that support that mechanism. At this point, interrupts are off
283 * and scheduling is not permitted
281 */ 284 */
285void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
286{
287 if (rinfo->no_schedule || oops_in_progress)
288 mdelay(ms);
289 else
290 msleep(ms);
291}
292
293void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo)
294{
295 /* Called if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS) is set */
296 (void)INREG(CLOCK_CNTL_DATA);
297 (void)INREG(CRTC_GEN_CNTL);
298}
299
300void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo)
301{
302 if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) {
303 /* we can't deal with posted writes here ... */
304 _radeon_msleep(rinfo, 5);
305 }
306 if (rinfo->errata & CHIP_ERRATA_R300_CG) {
307 u32 save, tmp;
308 save = INREG(CLOCK_CNTL_INDEX);
309 tmp = save & ~(0x3f | PLL_WR_EN);
310 OUTREG(CLOCK_CNTL_INDEX, tmp);
311 tmp = INREG(CLOCK_CNTL_DATA);
312 OUTREG(CLOCK_CNTL_INDEX, save);
313 }
314}
315
316void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask)
317{
318 unsigned long flags;
319 unsigned int tmp;
320
321 spin_lock_irqsave(&rinfo->reg_lock, flags);
322 tmp = INREG(addr);
323 tmp &= (mask);
324 tmp |= (val);
325 OUTREG(addr, tmp);
326 spin_unlock_irqrestore(&rinfo->reg_lock, flags);
327}
328
329u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
330{
331 u32 data;
332
333 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
334 radeon_pll_errata_after_index(rinfo);
335 data = INREG(CLOCK_CNTL_DATA);
336 radeon_pll_errata_after_data(rinfo);
337 return data;
338}
339
340void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val)
341{
342 OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
343 radeon_pll_errata_after_index(rinfo);
344 OUTREG(CLOCK_CNTL_DATA, val);
345 radeon_pll_errata_after_data(rinfo);
346}
347
348void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
349 u32 val, u32 mask)
350{
351 unsigned int tmp;
352
353 tmp = __INPLL(rinfo, index);
354 tmp &= (mask);
355 tmp |= (val);
356 __OUTPLL(rinfo, index, tmp);
357}
358
359void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
360{
361 int i;
362
363 for (i=0; i<2000000; i++) {
364 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
365 return;
366 udelay(1);
367 }
368 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
369}
370
371void radeon_engine_flush(struct radeonfb_info *rinfo)
372{
373 int i;
374
375 /* Initiate flush */
376 OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
377 ~RB2D_DC_FLUSH_ALL);
378
379 /* Ensure FIFO is empty, ie, make sure the flush commands
380 * has reached the cache
381 */
382 _radeon_fifo_wait(rinfo, 64);
383
384 /* Wait for the flush to complete */
385 for (i=0; i < 2000000; i++) {
386 if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
387 return;
388 udelay(1);
389 }
390 printk(KERN_ERR "radeonfb: Flush Timeout !\n");
391}
392
393void _radeon_engine_idle(struct radeonfb_info *rinfo)
394{
395 int i;
396
397 /* ensure FIFO is empty before waiting for idle */
398 _radeon_fifo_wait(rinfo, 64);
399
400 for (i=0; i<2000000; i++) {
401 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
402 radeon_engine_flush(rinfo);
403 return;
404 }
405 udelay(1);
406 }
407 printk(KERN_ERR "radeonfb: Idle Timeout !\n");
408}
409
410
282 411
283static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) 412static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
284{ 413{
diff --git a/drivers/video/fbdev/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h
index 5bc1944ea1a9..962e31263225 100644
--- a/drivers/video/fbdev/aty/radeonfb.h
+++ b/drivers/video/fbdev/aty/radeonfb.h
@@ -370,20 +370,7 @@ struct radeonfb_info {
370 * IO macros 370 * IO macros
371 */ 371 */
372 372
373/* Note about this function: we have some rare cases where we must not schedule, 373void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms);
374 * this typically happen with our special "wake up early" hook which allows us to
375 * wake up the graphic chip (and thus get the console back) before everything else
376 * on some machines that support that mechanism. At this point, interrupts are off
377 * and scheduling is not permitted
378 */
379static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
380{
381 if (rinfo->no_schedule || oops_in_progress)
382 mdelay(ms);
383 else
384 msleep(ms);
385}
386
387 374
388#define INREG8(addr) readb((rinfo->mmio_base)+addr) 375#define INREG8(addr) readb((rinfo->mmio_base)+addr)
389#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) 376#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)
392#define INREG(addr) readl((rinfo->mmio_base)+addr) 379#define INREG(addr) readl((rinfo->mmio_base)+addr)
393#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) 380#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
394 381
395static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, 382void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask);
396 u32 val, u32 mask)
397{
398 unsigned long flags;
399 unsigned int tmp;
400
401 spin_lock_irqsave(&rinfo->reg_lock, flags);
402 tmp = INREG(addr);
403 tmp &= (mask);
404 tmp |= (val);
405 OUTREG(addr, tmp);
406 spin_unlock_irqrestore(&rinfo->reg_lock, flags);
407}
408 383
409#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask) 384#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask)
410 385
@@ -425,64 +400,24 @@ static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
425 * possible exception to this rule is the call to unblank(), which may 400 * possible exception to this rule is the call to unblank(), which may
426 * be done at irq time if an oops is in progress. 401 * be done at irq time if an oops is in progress.
427 */ 402 */
403void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo);
428static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo) 404static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo)
429{ 405{
430 if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)) 406 if (rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS)
431 return; 407 radeon_pll_errata_after_index_slow(rinfo);
432
433 (void)INREG(CLOCK_CNTL_DATA);
434 (void)INREG(CRTC_GEN_CNTL);
435} 408}
436 409
410void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo);
437static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo) 411static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo)
438{ 412{
439 if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) { 413 if (rinfo->errata & (CHIP_ERRATA_PLL_DELAY|CHIP_ERRATA_R300_CG))
440 /* we can't deal with posted writes here ... */ 414 radeon_pll_errata_after_data_slow(rinfo);
441 _radeon_msleep(rinfo, 5);
442 }
443 if (rinfo->errata & CHIP_ERRATA_R300_CG) {
444 u32 save, tmp;
445 save = INREG(CLOCK_CNTL_INDEX);
446 tmp = save & ~(0x3f | PLL_WR_EN);
447 OUTREG(CLOCK_CNTL_INDEX, tmp);
448 tmp = INREG(CLOCK_CNTL_DATA);
449 OUTREG(CLOCK_CNTL_INDEX, save);
450 }
451}
452
453static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
454{
455 u32 data;
456
457 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
458 radeon_pll_errata_after_index(rinfo);
459 data = INREG(CLOCK_CNTL_DATA);
460 radeon_pll_errata_after_data(rinfo);
461 return data;
462}
463
464static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
465 u32 val)
466{
467
468 OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
469 radeon_pll_errata_after_index(rinfo);
470 OUTREG(CLOCK_CNTL_DATA, val);
471 radeon_pll_errata_after_data(rinfo);
472}
473
474
475static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
476 u32 val, u32 mask)
477{
478 unsigned int tmp;
479
480 tmp = __INPLL(rinfo, index);
481 tmp &= (mask);
482 tmp |= (val);
483 __OUTPLL(rinfo, index, tmp);
484} 415}
485 416
417u32 __INPLL(struct radeonfb_info *rinfo, u32 addr);
418void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val);
419void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
420 u32 val, u32 mask);
486 421
487#define INPLL(addr) __INPLL(rinfo, addr) 422#define INPLL(addr) __INPLL(rinfo, addr)
488#define OUTPLL(index, val) __OUTPLL(rinfo, index, val) 423#define OUTPLL(index, val) __OUTPLL(rinfo, index, val)
@@ -532,58 +467,9 @@ static inline u32 radeon_get_dstbpp(u16 depth)
532 * 2D Engine helper routines 467 * 2D Engine helper routines
533 */ 468 */
534 469
535static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) 470void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries);
536{ 471void radeon_engine_flush(struct radeonfb_info *rinfo);
537 int i; 472void _radeon_engine_idle(struct radeonfb_info *rinfo);
538
539 for (i=0; i<2000000; i++) {
540 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
541 return;
542 udelay(1);
543 }
544 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
545}
546
547static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
548{
549 int i;
550
551 /* Initiate flush */
552 OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
553 ~RB2D_DC_FLUSH_ALL);
554
555 /* Ensure FIFO is empty, ie, make sure the flush commands
556 * has reached the cache
557 */
558 _radeon_fifo_wait (rinfo, 64);
559
560 /* Wait for the flush to complete */
561 for (i=0; i < 2000000; i++) {
562 if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
563 return;
564 udelay(1);
565 }
566 printk(KERN_ERR "radeonfb: Flush Timeout !\n");
567}
568
569
570static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
571{
572 int i;
573
574 /* ensure FIFO is empty before waiting for idle */
575 _radeon_fifo_wait (rinfo, 64);
576
577 for (i=0; i<2000000; i++) {
578 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
579 radeon_engine_flush (rinfo);
580 return;
581 }
582 udelay(1);
583 }
584 printk(KERN_ERR "radeonfb: Idle Timeout !\n");
585}
586
587 473
588#define radeon_engine_idle() _radeon_engine_idle(rinfo) 474#define radeon_engine_idle() _radeon_engine_idle(rinfo)
589#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) 475#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)