1 // SPDX-License-Identifier: GPL-2.0-only
3 * Joshua Henderson <joshua.henderson@microchip.com>
4 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
6 #include <asm/mach-pic32/pic32.h>
10 /* Oscillators, PLL & clocks */
11 #define ICLK_MASK 0x00000080
12 #define PLLDIV_MASK 0x00000007
13 #define CUROSC_MASK 0x00000007
14 #define PLLMUL_MASK 0x0000007F
15 #define PB_MASK 0x00000007
20 #define FRC_CLK 8000000
22 #define PIC32_POSC_FREQ 24000000
25 #define SPLLCON 0x0020
28 u32
pic32_get_sysclk(void)
43 void __iomem
*osc_base
= ioremap(PIC32_BASE_OSC
, 0x200);
45 osccon
= __raw_readl(osc_base
+ OSCCON
);
46 spllcon
= __raw_readl(osc_base
+ SPLLCON
);
48 plliclk
= (spllcon
& ICLK_MASK
);
49 pllidiv
= ((spllcon
>> 8) & PLLDIV_MASK
) + 1;
50 pllodiv
= ((spllcon
>> 24) & PLLDIV_MASK
);
51 pllmult
= ((spllcon
>> 16) & PLLMUL_MASK
) + 1;
52 frcdiv
= ((osccon
>> 24) & PLLDIV_MASK
);
54 pllclk
= plliclk
? FRC_CLK
: PIC32_POSC_FREQ
;
55 frcdivn
= ((1 << frcdiv
) + 1) + (128 * (frcdiv
== 7));
60 pllodiv
= (1 << pllodiv
);
64 curr_osc
= (int)((osccon
>> 12) & CUROSC_MASK
);
69 osc_freq
= FRC_CLK
/ frcdivn
;
72 osc_freq
= ((pllclk
/ pllidiv
) * pllmult
) / pllodiv
;
75 osc_freq
= PIC32_POSC_FREQ
;
86 u32
pic32_get_pbclk(int bus
)
89 void __iomem
*osc_base
= ioremap(PIC32_BASE_OSC
, 0x200);
90 u32 pbxdiv
= PB1DIV
+ ((bus
- 1) * 0x10);
91 u32 pbdiv
= (__raw_readl(osc_base
+ pbxdiv
) & PB_MASK
) + 1;
95 clk_freq
= pic32_get_sysclk();
97 return clk_freq
/ pbdiv
;