diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2015-09-23 13:57:53 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2015-10-08 05:24:12 -0400 |
commit | 08bfb453f0458dd353f37737d80475ff13868d9c (patch) | |
tree | a41511f29a6c901b88d2227d42041b3c4de42668 | |
parent | 2035608e126f4ddc6a48f6b04ef967f89db460e1 (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.c | 133 | ||||
-rw-r--r-- | drivers/video/fbdev/aty/radeonfb.h | 144 |
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; | |||
276 | static int backlight = 0; | 276 | static 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 | */ |
285 | void _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 | |||
293 | void 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 | |||
300 | void 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 | |||
316 | void _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 | |||
329 | u32 __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 | |||
340 | void __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 | |||
348 | void __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 | |||
359 | void _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 | |||
371 | void 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 | |||
393 | void _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 | ||
283 | static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) | 412 | static 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, | 373 | void _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 | */ | ||
379 | static 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 | ||
395 | static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, | 382 | void _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 | */ |
403 | void radeon_pll_errata_after_index_slow(struct radeonfb_info *rinfo); | ||
428 | static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo) | 404 | static 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 | ||
410 | void radeon_pll_errata_after_data_slow(struct radeonfb_info *rinfo); | ||
437 | static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo) | 411 | static 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 | |||
453 | static 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 | |||
464 | static 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 | |||
475 | static 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 | ||
417 | u32 __INPLL(struct radeonfb_info *rinfo, u32 addr); | ||
418 | void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val); | ||
419 | void __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 | ||
535 | static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) | 470 | void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries); |
536 | { | 471 | void radeon_engine_flush(struct radeonfb_info *rinfo); |
537 | int i; | 472 | void _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 | |||
547 | static 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 | |||
570 | static 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) |