123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- /*
- * Joshua Henderson <joshua.henderson@microchip.com>
- * Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
- #include <asm/mach-pic32/pic32.h>
- #include "pic32mzda.h"
- /* Oscillators, PLL & clocks */
- #define ICLK_MASK 0x00000080
- #define PLLDIV_MASK 0x00000007
- #define CUROSC_MASK 0x00000007
- #define PLLMUL_MASK 0x0000007F
- #define PB_MASK 0x00000007
- #define FRC1 0
- #define FRC2 7
- #define SPLL 1
- #define POSC 2
- #define FRC_CLK 8000000
- #define PIC32_POSC_FREQ 24000000
- #define OSCCON 0x0000
- #define SPLLCON 0x0020
- #define PB1DIV 0x0140
- u32 pic32_get_sysclk(void)
- {
- u32 osc_freq = 0;
- u32 pllclk;
- u32 frcdivn;
- u32 osccon;
- u32 spllcon;
- int curr_osc;
- u32 plliclk;
- u32 pllidiv;
- u32 pllodiv;
- u32 pllmult;
- u32 frcdiv;
- void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
- osccon = __raw_readl(osc_base + OSCCON);
- spllcon = __raw_readl(osc_base + SPLLCON);
- plliclk = (spllcon & ICLK_MASK);
- pllidiv = ((spllcon >> 8) & PLLDIV_MASK) + 1;
- pllodiv = ((spllcon >> 24) & PLLDIV_MASK);
- pllmult = ((spllcon >> 16) & PLLMUL_MASK) + 1;
- frcdiv = ((osccon >> 24) & PLLDIV_MASK);
- pllclk = plliclk ? FRC_CLK : PIC32_POSC_FREQ;
- frcdivn = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7));
- if (pllodiv < 2)
- pllodiv = 2;
- else if (pllodiv < 5)
- pllodiv = (1 << pllodiv);
- else
- pllodiv = 32;
- curr_osc = (int)((osccon >> 12) & CUROSC_MASK);
- switch (curr_osc) {
- case FRC1:
- case FRC2:
- osc_freq = FRC_CLK / frcdivn;
- break;
- case SPLL:
- osc_freq = ((pllclk / pllidiv) * pllmult) / pllodiv;
- break;
- case POSC:
- osc_freq = PIC32_POSC_FREQ;
- break;
- default:
- break;
- }
- iounmap(osc_base);
- return osc_freq;
- }
- u32 pic32_get_pbclk(int bus)
- {
- u32 clk_freq;
- void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200);
- u32 pbxdiv = PB1DIV + ((bus - 1) * 0x10);
- u32 pbdiv = (__raw_readl(osc_base + pbxdiv) & PB_MASK) + 1;
- iounmap(osc_base);
- clk_freq = pic32_get_sysclk();
- return clk_freq / pbdiv;
- }
|