Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / arch / powerpc / boot / util.S
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
31 timebase_period_ns:
32         .long   60
33
34         .text
35 /*
36  * Delay for a number of microseconds
37  */
38         .globl  udelay
39 udelay:
40         mfspr   r4,SPRN_PVR
41         srwi    r4,r4,16
42         cmpwi   0,r4,1          /* 601 ? */
43         bne     .Ludelay_not_601
44 00:     li      r0,86   /* Instructions / microsecond? */
45         mtctr   r0
46 10:     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
59 0:      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 */
69 1:      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
76 2:      MFTBU(r5)
77         cmpw    0,r5,r8
78         blt     2b
79         bgt     3f
80         MFTBL(r6)
81         cmpw    0,r6,r9
82         blt     2b
83 3:      blr