linux/arch/powerpc/boot/util.S
<<
>>
Prefs
   1/*
   2 * Copied from <file:arch/powerpc/kernel/misc_32.S>
   3 *
   4 * This file contains miscellaneous low-level functions.
   5 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
   6 *
   7 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
   8 * and Paul Mackerras.
   9 *
  10 * kexec bits:
  11 * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
  12 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
  13 *
  14 * This program is free software; you can redistribute it and/or
  15 * modify it under the terms of the GNU General Public License
  16 * as published by the Free Software Foundation; either version
  17 * 2 of the License, or (at your option) any later version.
  18 *
  19 */
  20#include "ppc_asm.h"
  21
  22#define SPRN_PVR        0x11F   /* Processor Version Register */
  23
  24        .text
  25
  26/* udelay (on non-601 processors) needs to know the period of the
  27 * timebase in nanoseconds.  This used to be hardcoded to be 60ns
  28 * (period of 66MHz/4).  Now a variable is used that is initialized to
  29 * 60 for backward compatibility, but it can be overridden as necessary
  30 * with code something like this:
  31 *    extern unsigned long timebase_period_ns;
  32 *    timebase_period_ns = 1000000000 / bd->bi_tbfreq;
  33 */
  34        .data
  35        .globl timebase_period_ns
  36timebase_period_ns:
  37        .long   60
  38
  39        .text
  40/*
  41 * Delay for a number of microseconds
  42 */
  43        .globl  udelay
  44udelay:
  45        mfspr   r4,SPRN_PVR
  46        srwi    r4,r4,16
  47        cmpwi   0,r4,1          /* 601 ? */
  48        bne     .Ludelay_not_601
  4900:     li      r0,86   /* Instructions / microsecond? */
  50        mtctr   r0
  5110:     addi    r0,r0,0 /* NOP */
  52        bdnz    10b
  53        subic.  r3,r3,1
  54        bne     00b
  55        blr
  56
  57.Ludelay_not_601:
  58        mulli   r4,r3,1000      /* nanoseconds */
  59        /*  Change r4 to be the number of ticks using:
  60         *      (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
  61         *  timebase_period_ns defaults to 60 (16.6MHz) */
  62        mflr    r5
  63        bl      0f
  640:      mflr    r6
  65        mtlr    r5
  66        lis     r5,0b@ha
  67        addi    r5,r5,0b@l
  68        subf    r5,r5,r6        /* In case we're relocated */
  69        addis   r5,r5,timebase_period_ns@ha
  70        lwz     r5,timebase_period_ns@l(r5)
  71        add     r4,r4,r5
  72        addi    r4,r4,-1
  73        divw    r4,r4,r5        /* BUS ticks */
  741:      MFTBU(r5)
  75        MFTBL(r6)
  76        MFTBU(r7)
  77        cmpw    0,r5,r7
  78        bne     1b              /* Get [synced] base time */
  79        addc    r9,r6,r4        /* Compute end time */
  80        addze   r8,r5
  812:      MFTBU(r5)
  82        cmpw    0,r5,r8
  83        blt     2b
  84        bgt     3f
  85        MFTBL(r6)
  86        cmpw    0,r6,r9
  87        blt     2b
  883:      blr
  89