Feat:Clock:Init!
OSC freq,PLLC,PLLX,PLLU,PLLP,UART clock bring up
This commit is contained in:
parent
b5d514cfac
commit
d4a5b5f87f
282
loader/clock.c
282
loader/clock.c
@ -22,6 +22,97 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OSC_FREQ_13 = 0,
|
||||||
|
OSC_FREQ_16P8 = 1,
|
||||||
|
OSC_FREQ_19P2 = 4,
|
||||||
|
OSC_FREQ_38P4 = 5,
|
||||||
|
OSC_FREQ_12 = 8,
|
||||||
|
OSC_FREQ_48 = 9,
|
||||||
|
OSC_FREQ_26 = 12
|
||||||
|
};
|
||||||
|
/* This table defines the frequency dividers for every PLL to turn the external
|
||||||
|
* OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
|
||||||
|
* All PLLs have three dividers (n, m and p), with the governing formula for
|
||||||
|
* the output frequency being CF = (IN / m), VCO = CF * n and OUT = VCO / (2^p).
|
||||||
|
* All divisor configurations must meet the PLL's constraints for VCO and CF:
|
||||||
|
* PLLX: 12 MHz < CF < 50 MHz, 700 MHz < VCO < 3000 MHz
|
||||||
|
* PLLC: 12 MHz < CF < 50 MHz, 600 MHz < VCO < 1400 MHz
|
||||||
|
* PLLM: 12 MHz < CF < 50 MHz, 400 MHz < VCO < 1066 MHz
|
||||||
|
* PLLP: 1 MHz < CF < 6 MHz, 200 MHz < VCO < 700 MHz
|
||||||
|
* PLLD: 1 MHz < CF < 6 MHz, 500 MHz < VCO < 1000 MHz
|
||||||
|
* PLLU: 1 MHz < CF < 6 MHz, 480 MHz < VCO < 960 MHz
|
||||||
|
* PLLDP: 12 MHz < CF < 38 MHz, 600 MHz < VCO < 1200 MHz
|
||||||
|
* (values taken from Linux' drivers/clk/tegra/clk-tegra124.c). */
|
||||||
|
struct {
|
||||||
|
int khz;
|
||||||
|
struct pllcx_dividers pllx; /* target: CONFIG_PLLX_KHZ */
|
||||||
|
struct pllcx_dividers pllc; /* target: 600 MHz */
|
||||||
|
/* PLLM is set up dynamically by clock_sdram(). */
|
||||||
|
/* PLLP is hardwired to 408 MHz in HW (unless we set BASE_OVRD). */
|
||||||
|
struct pllu_dividers pllu; /* target; 960 MHz */
|
||||||
|
struct pllcx_dividers plldp; /* target; 270 MHz */
|
||||||
|
/* PLLDP treats p differently (OUT = VCO / (p + 1) for p < 6). */
|
||||||
|
} static const osc_table[16] = {
|
||||||
|
[OSC_FREQ_12] = {
|
||||||
|
.khz = 12000,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 50, .m = 1, .p = 0},
|
||||||
|
.pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
|
||||||
|
.plldp = {.n = 90, .m = 1, .p = 3},
|
||||||
|
},
|
||||||
|
[OSC_FREQ_13] = {
|
||||||
|
.khz = 13000,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 13000, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 46, .m = 1, .p = 0}, /* 598.0 MHz */
|
||||||
|
.pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12, .lfcon = 2},
|
||||||
|
.plldp = {.n = 83, .m = 1, .p = 3}, /* 269.8 MHz */
|
||||||
|
},
|
||||||
|
[OSC_FREQ_16P8] = {
|
||||||
|
.khz = 16800,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 16800, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 71, .m = 1, .p = 1}, /* 596.4 MHz */
|
||||||
|
.pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 5, .lfcon = 2},
|
||||||
|
.plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
|
||||||
|
},
|
||||||
|
[OSC_FREQ_19P2] = {
|
||||||
|
.khz = 19200,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
|
||||||
|
.pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
|
||||||
|
.plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
|
||||||
|
},
|
||||||
|
[OSC_FREQ_26] = {
|
||||||
|
.khz = 26000,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 26000, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 23, .m = 1, .p = 0}, /* 598.0 MHz */
|
||||||
|
.pllu = {.n = 960, .m = 26, .p = 0, .cpcon = 12, .lfcon = 2},
|
||||||
|
.plldp = {.n = 83, .m = 2, .p = 3}, /* 269.8 MHz */
|
||||||
|
},
|
||||||
|
/* These oscillators get predivided as PLL inputs... n/m/p divisors for
|
||||||
|
* 38.4 should always match 19.2, and 48 should always match 12. */
|
||||||
|
[OSC_FREQ_38P4] = {
|
||||||
|
.khz = 38400,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
|
||||||
|
.pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
|
||||||
|
.plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
|
||||||
|
},
|
||||||
|
[OSC_FREQ_48] = {
|
||||||
|
.khz = 48000,
|
||||||
|
.pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
|
||||||
|
.pllc = {.n = 50, .m = 1, .p = 0},
|
||||||
|
.pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
|
||||||
|
.plldp = {.n = 90, .m = 1, .p = 3},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
SCLK_SYS_STATE_STDBY,
|
||||||
|
SCLK_SYS_STATE_IDLE,
|
||||||
|
SCLK_SYS_STATE_RUN,
|
||||||
|
SCLK_SYS_STATE_IRQ = 4U,
|
||||||
|
SCLK_SYS_STATE_FIQ = 8U,
|
||||||
|
};
|
||||||
void clock_enable(const clk_rst_t *clk)
|
void clock_enable(const clk_rst_t *clk)
|
||||||
{
|
{
|
||||||
// Put clock into reset.
|
// Put clock into reset.
|
||||||
@ -47,26 +138,179 @@ void clock_disable(const clk_rst_t *clk)
|
|||||||
CLOCK(clk->enable) &= ~BIT(clk->index);
|
CLOCK(clk->enable) &= ~BIT(clk->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
//For NS Switch
|
static void init_pll(u32 pll_base_offset, u32 pll_misc_offset, const union pll_fields pll, u32 lock)
|
||||||
/*
|
|
||||||
* CLK_OSC - 38.4 MHz crystal.
|
|
||||||
* CLK_M - 19.2 MHz (osc/2).
|
|
||||||
* CLK_S - 32.768 KHz (from PMIC).
|
|
||||||
* SCLK - 204MHz init (-> 408MHz -> OC).
|
|
||||||
* HCLK - 204MHz init (-> 408MHz -> OC).
|
|
||||||
* PCLK - 68MHz init (-> 136MHz -> OC/4).
|
|
||||||
*/
|
|
||||||
//For P1761(Ardbeg,Fuze F1)
|
|
||||||
/*
|
|
||||||
* CLK_OSC - 12 MHz crystal.
|
|
||||||
* CLK_M - 12 MHz (osc/2).
|
|
||||||
* CLK_S - 32.768 KHz (from PMIC).
|
|
||||||
* SCLK - 127.5MHz init (-> 408MHz -> OC).
|
|
||||||
* HCLK - 127.5MHz init (-> 408MHz -> OC).
|
|
||||||
* PCLK - 31.875?MHz init (-> 136MHz -> OC/4).
|
|
||||||
*/
|
|
||||||
void config_oscillators()
|
|
||||||
{
|
{
|
||||||
|
//TODO: rename
|
||||||
|
u32 dividers = pll.div.n << PLL_BASE_DIVN_SHIFT |
|
||||||
|
pll.div.m << PLL_BASE_DIVM_SHIFT |
|
||||||
|
pll.div.p << PLL_BASE_DIVP_SHIFT;
|
||||||
|
u32 misc_con = pll.div.cpcon << PLL_MISC_CPCON_SHIFT |
|
||||||
|
pll.div.lfcon << PLL_MISC_LFCON_SHIFT;
|
||||||
|
|
||||||
|
/* Write dividers but BYPASS the PLL while we're messing with it. */
|
||||||
|
CLOCK(pll_base_offset)=dividers | (1<<CLK_RST_CONTROLLER_PLLC_BASE_PLLC_BYPASS_SHIFT);
|
||||||
|
/*
|
||||||
|
* Set Lock bit, CPCON and LFCON fields (default to 0 if it doesn't
|
||||||
|
* exist for this PLL)
|
||||||
|
*/
|
||||||
|
CLOCK(pll_misc_offset)=(lock | misc_con);
|
||||||
|
|
||||||
|
/* Enable PLL and take it back out of BYPASS */
|
||||||
|
CLOCK(pll_base_offset)=dividers | (1 << CLK_RST_CONTROLLER_PLLC_BASE_PLLC_ENABLE_SHIFT);
|
||||||
|
|
||||||
|
/* Wait for lock ready */
|
||||||
|
while (!(CLOCK(pll_base_offset) & (1 << CLK_RST_CONTROLLER_PLLC_BASE_PLLC_LOCK_SHIFT)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From Coreboot */
|
||||||
|
/* Clock configuration. */
|
||||||
|
void config_oscillators()
|
||||||
|
{
|
||||||
|
// clock_get_osc_bits()
|
||||||
|
// Copied from coreboot
|
||||||
|
// OSC_FREQ_13 = 0,
|
||||||
|
// OSC_FREQ_16P8 = 1,
|
||||||
|
// OSC_FREQ_19P2 = 4,
|
||||||
|
// OSC_FREQ_38P4 = 5,
|
||||||
|
// OSC_FREQ_12 = 8,
|
||||||
|
// OSC_FREQ_48 = 9,
|
||||||
|
// OSC_FREQ_26 = 12
|
||||||
|
//
|
||||||
|
// 8 is 12mhz
|
||||||
|
//TODO other osc freq porting
|
||||||
|
u32 clk_osc_bit=(CLOCK(CLK_RST_CONTROLLER_OSC_CTRL)&CLK_OSC_FREQ_MASK)>>CLK_OSC_FREQ_SHIFT;
|
||||||
|
|
||||||
|
|
||||||
|
/* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC2)=(0x2b << 17 | 0xb << 9);
|
||||||
|
|
||||||
|
|
||||||
|
// static const osc_table[16] = {
|
||||||
|
// [OSC_FREQ_12] = {
|
||||||
|
// .khz = 12000,
|
||||||
|
// .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
|
||||||
|
// .pllc = {.n = 50, .m = 1, .p = 0},
|
||||||
|
// .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
|
||||||
|
// .plldp = {.n = 90, .m = 1, .p = 3},
|
||||||
|
// },
|
||||||
|
/* Max out the AVP clock before everything else (need PLLC for that). */
|
||||||
|
init_pll(CLK_RST_CONTROLLER_PLLC_BASE,CLK_RST_CONTROLLER_PLLC_MISC,osc_table[clk_osc_bit].pllc,(1 << CLK_RST_CONTROLLER_PLLC_MISC_PLLC_LOCK_ENABLE_SHIFT));
|
||||||
|
printf_("[x] PLLC setup\n");
|
||||||
|
|
||||||
|
/* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
|
||||||
|
* features section in the TRM). */
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE)=
|
||||||
|
TEGRA_HCLK_RATIO << CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_AHB_RATE_SHIFT |
|
||||||
|
TEGRA_PCLK_RATIO << CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_APB_RATE_SHIFT;
|
||||||
|
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT)=CLK_DIVIDER(TEGRA_PLLC_KHZ, TEGRA_SCLK_KHZ)
|
||||||
|
<< CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT);
|
||||||
|
|
||||||
|
/* sclk = 300 MHz */
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY)=
|
||||||
|
CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_RUN << CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_SHIFT |
|
||||||
|
CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLC_OUT1 <<CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_SHIFT;
|
||||||
|
printf_("[x] System Clock:300 Mhz\n");
|
||||||
|
|
||||||
|
// Read oscillator drive strength from OSC_EDPD_OVER.XOFS and copy
|
||||||
|
// to OSC_CTRL.XOFS and set XOE. --copied from lp0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ambiguous quote from u-boot. TODO: what's this mean?
|
||||||
|
* "should update same value in PMC_OSC_EDPD_OVER XOFS
|
||||||
|
* field for warmboot "
|
||||||
|
*/
|
||||||
|
u32 xofs = (PMC(APBDEV_PMC_OSC_EDPD_OVER) &
|
||||||
|
PMC_XOFS_MASK) >> PMC_XOFS_SHIFT;
|
||||||
|
|
||||||
|
/*Change the oscillator drive strength (from U-Boot -- why?) */
|
||||||
|
u32 osc_ctrl = CLOCK(CLK_RST_CONTROLLER_OSC_CTRL);
|
||||||
|
osc_ctrl &= ~CLK_OSC_XOFS_MASK;
|
||||||
|
osc_ctrl |= (xofs << CLK_OSC_XOFS_SHIFT);
|
||||||
|
osc_ctrl |= CLK_OSC_XOE;
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL)=osc_ctrl;
|
||||||
|
|
||||||
|
/* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ.
|
||||||
|
|
||||||
|
/* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
|
||||||
|
|
||||||
|
//pll2 ovr shift should be 18?
|
||||||
|
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTA)=((CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT) |
|
||||||
|
(1 << CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT)) << PLL_OUT1_SHIFT |
|
||||||
|
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT) |
|
||||||
|
(1 << CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT)) << PLL_OUT2_SHIFT);
|
||||||
|
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB)= ((CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT) |
|
||||||
|
(1 << CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT)) << PLL_OUT3_SHIFT |
|
||||||
|
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT) |
|
||||||
|
(1 << CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT) | (1 << CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT)) << PLL_OUT4_SHIFT);
|
||||||
|
|
||||||
|
init_pll(CLK_RST_CONTROLLER_PLLX_BASE,CLK_RST_CONTROLLER_PLLX_MISC,osc_table[clk_osc_bit].pllx,(1 << CLK_RST_CONTROLLER_PLLX_MISC_PLLX_LOCK_ENABLE_SHIFT));
|
||||||
|
|
||||||
|
init_pll(CLK_RST_CONTROLLER_PLLU_BASE,CLK_RST_CONTROLLER_PLLU_MISC,osc_table[clk_osc_bit].pllu,(1 << CLK_RST_CONTROLLER_PLLU_MISC_PLLU_LOCK_ENABLE_SHIFT));
|
||||||
|
|
||||||
|
|
||||||
|
//TODO usb device init later
|
||||||
|
|
||||||
|
|
||||||
|
/* Graphics just has to be different. There's a few more bits we
|
||||||
|
* need to set in here, but it makes sense just to restrict all the
|
||||||
|
* special bits to this one function. Imported form graphics_pll(void)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* the vendor code sets the dither bit (28)
|
||||||
|
* an undocumented bit (24)
|
||||||
|
* and clamp while we mess with it (22)
|
||||||
|
* Dither is pretty important to display port
|
||||||
|
* so we really do need to handle these bits.
|
||||||
|
* I'm not willing to not clamp it, even if
|
||||||
|
* it might "mostly work" with it not set,
|
||||||
|
* I don't want to find out in a few months
|
||||||
|
* that it is needed.
|
||||||
|
*/
|
||||||
|
u32 scfg = (1<<28) | (1<<24) | (1<<22);
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLDP_SS_CFG)=scfg;
|
||||||
|
|
||||||
|
init_pll(CLK_RST_CONTROLLER_PLLDP_BASE, CLK_RST_CONTROLLER_PLLDP_MISC,
|
||||||
|
osc_table[clk_osc_bit].plldp, (1 << CLK_RST_CONTROLLER_PLLDP_MISC_0_PLLDP_LOCK_ENABLE_SHIFT));
|
||||||
|
/* leave dither and undoc bits set, release clamp */
|
||||||
|
scfg = (1<<28) | (1<<24);
|
||||||
|
CLOCK(CLK_RST_CONTROLLER_PLLDP_SS_CFG)=scfg;
|
||||||
|
|
||||||
|
/* disp1 will be set when panel information (pixel clock) is
|
||||||
|
* retrieved (clock_display).
|
||||||
|
*/
|
||||||
|
printf_("[X] PLLP,PLLX,PLLU,PLLDP setup\n");
|
||||||
|
}
|
||||||
|
static const clk_rst_t _clock_uart[] = {
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||||
|
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
|
||||||
|
};
|
||||||
|
void clock_enable_uart(u32 idx)
|
||||||
|
{
|
||||||
|
clock_enable(&_clock_uart[idx]);
|
||||||
|
}
|
||||||
|
#define UART_SRC_CLK_DIV_EN BIT(24)
|
||||||
|
|
||||||
|
int clock_uart_use_src_div(u32 idx, u32 baud)
|
||||||
|
{
|
||||||
|
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
|
||||||
|
|
||||||
|
if (baud == 3000000)
|
||||||
|
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15;
|
||||||
|
else if (baud == 1000000)
|
||||||
|
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLOCK(_clock_uart[idx].source) = clk_src_div | 2;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
184
loader/clock.h
184
loader/clock.h
@ -26,12 +26,192 @@ typedef struct _clk_rst_t
|
|||||||
u8 clk_src;
|
u8 clk_src;
|
||||||
u8 clk_div;
|
u8 clk_div;
|
||||||
} clk_rst_t;
|
} clk_rst_t;
|
||||||
|
/* soc-specific */
|
||||||
|
#define TEGRA_CLK_M_KHZ 12000
|
||||||
|
#define TEGRA_PLLX_KHZ 2000000
|
||||||
|
#define TEGRA_PLLP_KHZ (408000)
|
||||||
|
#define TEGRA_PLLC_KHZ (600000)
|
||||||
|
#define TEGRA_PLLD_KHZ (925000)
|
||||||
|
#define TEGRA_PLLU_KHZ (960000)
|
||||||
|
|
||||||
|
#define TEGRA_SCLK_KHZ (300000)
|
||||||
|
#define TEGRA_HCLK_RATIO 1
|
||||||
|
#define TEGRA_HCLK_KHZ (TEGRA_SCLK_KHZ / (1 + TEGRA_HCLK_RATIO))
|
||||||
|
#define TEGRA_PCLK_RATIO 0
|
||||||
|
#define TEGRA_PCLK_KHZ (TEGRA_HCLK_KHZ / (1 + TEGRA_PCLK_RATIO))
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
|
||||||
|
#define CLK_OSC_DRIVE_STRENGTH 7
|
||||||
|
|
||||||
|
//PLLC
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_BASE 0x80
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_MISC 0x8c
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_MISC_PLLC_LOCK_ENABLE_SHIFT 24
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_MISC2 0x88
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_BYPASS_SHIFT 31
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_OUT 0x84
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_AHB_RATE_SHIFT 4
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_APB_RATE_SHIFT 0
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_SHIFT 28
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_IDLE 1
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_RUN 2
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLC_OUT1 1
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT4 2
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT3 3
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT2 4
|
||||||
|
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_SHIFT 4
|
||||||
|
//PLLP
|
||||||
|
#define CLK_RST_CONTROLLER_PLLP_OUTA 0xA4
|
||||||
|
#define CLK_RST_CONTROLLER_PLLP_OUTB 0xA8
|
||||||
|
#define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT 8
|
||||||
|
#define CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT 2
|
||||||
|
#define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT 1
|
||||||
|
#define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT 0
|
||||||
|
|
||||||
|
//PLLX
|
||||||
|
#define PLLX_MISC3_IDDQ (1U << 3)
|
||||||
|
#define CLK_RST_CONTROLLER_PLLX_BASE 0xe0
|
||||||
|
#define CLK_RST_CONTROLLER_PLLX_MISC 0xe4
|
||||||
|
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
|
||||||
|
#define CLK_RST_CONTROLLER_PLLX_MISC_PLLX_LOCK_ENABLE_SHIFT 18
|
||||||
|
|
||||||
|
//PLLU
|
||||||
|
#define CLK_RST_CONTROLLER_PLLU_BASE 0xc0
|
||||||
|
#define CLK_RST_CONTROLLER_PLLU_MISC 0xcc
|
||||||
|
#define CLK_RST_CONTROLLER_PLLU_MISC_PLLU_LOCK_ENABLE_SHIFT 22
|
||||||
|
|
||||||
|
//PLLDP (Graphis PLL)
|
||||||
|
#define CLK_RST_CONTROLLER_PLLDP_SS_CFG 0x598
|
||||||
|
#define CLK_RST_CONTROLLER_PLLDP_BASE 0x590
|
||||||
|
#define CLK_RST_CONTROLLER_PLLDP_MISC 0x594
|
||||||
|
#define CLK_RST_CONTROLLER_PLLDP_MISC_0_PLLDP_LOCK_ENABLE_SHIFT 30
|
||||||
|
|
||||||
|
#define PLL_OUT1_SHIFT 0
|
||||||
|
#define PLL_OUT2_SHIFT 16
|
||||||
|
#define PLL_OUT3_SHIFT 0
|
||||||
|
#define PLL_OUT4_SHIFT 16
|
||||||
|
|
||||||
|
#define PLL_BASE_DIVN_SHIFT 8
|
||||||
|
#define PLL_BASE_DIVM_SHIFT 0
|
||||||
|
#define PLL_BASE_DIVP_SHIFT 20
|
||||||
|
#define PLL_MISC_CPCON_SHIFT 8
|
||||||
|
#define PLL_MISC_LFCON_SHIFT 4
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_ENABLE_SHIFT 30
|
||||||
|
#define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_LOCK_SHIFT 27
|
||||||
|
|
||||||
|
|
||||||
|
#define PLLCX_BASE_LOCK BIT(27)
|
||||||
|
|
||||||
|
#define DIV_ROUND_UP(x, y) ({ \
|
||||||
|
__typeof__(x) _div_local_x = (x); \
|
||||||
|
__typeof__(y) _div_local_y = (y); \
|
||||||
|
(_div_local_x + _div_local_y - 1) / _div_local_y; \
|
||||||
|
})
|
||||||
|
#define CLK_DIVIDER(REF, FREQ) (DIV_ROUND_UP(((REF) * 2), (FREQ)) - 2)
|
||||||
|
|
||||||
|
//MC
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19c
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
|
||||||
|
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
|
||||||
|
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3a4
|
||||||
|
|
||||||
|
//Reset
|
||||||
|
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
|
||||||
|
#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8
|
||||||
|
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
|
||||||
|
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
|
||||||
|
|
||||||
|
//UART
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0
|
||||||
|
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTD 0x1C0
|
||||||
|
enum CLK_L_DEV
|
||||||
|
{
|
||||||
|
CLK_L_UARTA = 6,
|
||||||
|
CLK_L_UARTB = 7,
|
||||||
|
};
|
||||||
|
enum CLK_H_DEV
|
||||||
|
{
|
||||||
|
CLK_H_UARTC = 23,
|
||||||
|
};
|
||||||
|
enum CLK_U_DEV
|
||||||
|
{
|
||||||
|
CLK_U_UARTD = 1,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
CLK_OSC_XOE = 0x1 << 0,
|
||||||
|
CLK_OSC_XOFS_SHIFT = 4,
|
||||||
|
CLK_OSC_XOFS_MASK = 0x3f << CLK_OSC_XOFS_SHIFT,
|
||||||
|
CLK_OSC_FREQ_SHIFT = 28,
|
||||||
|
CLK_OSC_FREQ_MASK = 0xf << CLK_OSC_FREQ_SHIFT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct pll_dividers {
|
||||||
|
u32 n : 10;
|
||||||
|
u32 m : 8;
|
||||||
|
u32 p : 4;
|
||||||
|
u32 cpcon : 4;
|
||||||
|
u32 lfcon : 4;
|
||||||
|
u32 : 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Some PLLs have more restrictive divider bit lengths or are missing some
|
||||||
|
* fields. Make sure to use the right struct in the osc_table definition to get
|
||||||
|
* compile-time checking, but keep the bits aligned with struct pll_dividers so
|
||||||
|
* they can be used interchangeably at run time. Add new formats as required. */
|
||||||
|
struct pllcx_dividers {
|
||||||
|
u32 n : 8;
|
||||||
|
u32 : 2;
|
||||||
|
u32 m : 8;
|
||||||
|
u32 p : 4;
|
||||||
|
u32 : 10;
|
||||||
|
};
|
||||||
|
struct pllpad_dividers {
|
||||||
|
u32 n : 10;
|
||||||
|
u32 m : 5;
|
||||||
|
u32 : 3;
|
||||||
|
u32 p : 3;
|
||||||
|
u32 : 1;
|
||||||
|
u32 cpcon : 4;
|
||||||
|
u32 : 6;
|
||||||
|
};
|
||||||
|
struct pllu_dividers {
|
||||||
|
u32 n : 10;
|
||||||
|
u32 m : 5;
|
||||||
|
u32 : 3;
|
||||||
|
u32 p : 1;
|
||||||
|
u32 : 3;
|
||||||
|
u32 cpcon : 4;
|
||||||
|
u32 lfcon : 4;
|
||||||
|
u32 : 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
union __attribute__((transparent_union)) pll_fields {
|
||||||
|
u32 raw;
|
||||||
|
struct pll_dividers div;
|
||||||
|
struct pllcx_dividers cx;
|
||||||
|
struct pllpad_dividers pad;
|
||||||
|
struct pllu_dividers u;
|
||||||
|
};
|
||||||
|
|
||||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_0 0x19c
|
|
||||||
|
|
||||||
void clock_enable(const clk_rst_t *clk);
|
void clock_enable(const clk_rst_t *clk);
|
||||||
void clock_disable(const clk_rst_t *clk);
|
void clock_disable(const clk_rst_t *clk);
|
||||||
void clock_enable_cl_dvfs();
|
void clock_enable_cl_dvfs();
|
||||||
void clock_enable_i2c(u32 idx);
|
void clock_enable_i2c(u32 idx);
|
||||||
|
void clock_enable_uart(u32 idx);
|
||||||
void config_oscillators();
|
void config_oscillators();
|
||||||
|
int clock_uart_use_src_div(u32 idx, u32 baud);
|
@ -15,3 +15,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||||
|
enum {
|
||||||
|
PMC_XOFS_SHIFT = 1,
|
||||||
|
PMC_XOFS_MASK = 0x3f << PMC_XOFS_SHIFT
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user