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