From 68a672c2c268295136e1ca186cab390494088490 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Sat, 20 Sep 2014 15:07:52 -0700 Subject: tegra132: Clean up clock register writes Clean up functions to write to clk_enb and rst_dev registers and add clock_disable and clock_set_reset functions to provide a complete API for updating the registers. BUG=chrome-os-partner:31821 BRANCH=None TEST=Compiles successfully and boots to kernel prompt on ryu. Compiles successfully on rush Change-Id: Ib0b7e3fc322f18be396ecf3b02b2399d4ba33e9b Signed-off-by: Patrick Georgi Original-Commit-Id: 1bb222adc22c7e26077dfb2ba6e4d41a4965d183 Original-Change-Id: Icb8081fe3d80174c920eaaecf5cbb0aa912d5b19 Original-Signed-off-by: Furquan Shaikh Original-Reviewed-on: https://chromium-review.googlesource.com/219191 Original-Tested-by: Furquan Shaikh Original-Reviewed-by: Aaron Durbin Original-Commit-Queue: Furquan Shaikh Reviewed-on: http://review.coreboot.org/9099 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/soc/nvidia/tegra132/ccplex.c | 13 +-- src/soc/nvidia/tegra132/clk_rst.h | 8 +- src/soc/nvidia/tegra132/clock.c | 130 ++++++++++++++++++---------- src/soc/nvidia/tegra132/funitcfg.c | 3 - src/soc/nvidia/tegra132/i2c6.c | 11 +-- src/soc/nvidia/tegra132/include/soc/clock.h | 72 ++++++++++++++- 6 files changed, 166 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/soc/nvidia/tegra132/ccplex.c b/src/soc/nvidia/tegra132/ccplex.c index 1085b285ad..258fbea3ab 100644 --- a/src/soc/nvidia/tegra132/ccplex.c +++ b/src/soc/nvidia/tegra132/ccplex.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "clk_rst.h" @@ -109,16 +110,8 @@ int ccplex_load_mts(void) static void enable_cpu_clocks(void) { - struct clk_rst_ctlr * const clk_rst = CLK_RST_REGS; - uint32_t reg; - - reg = read32(&clk_rst->clk_enb_l_set); - reg |= CLK_ENB_CPU; - write32(reg, &clk_rst->clk_enb_l_set); - - reg = read32(&clk_rst->clk_enb_v_set); - reg |= SET_CLK_ENB_CPUG_ENABLE | SET_CLK_ENB_CPULP_ENABLE; - write32(reg, &clk_rst->clk_enb_v_set); + clock_enable(CLK_ENB_CPU, 0, 0, SET_CLK_ENB_CPUG_ENABLE | + SET_CLK_ENB_CPULP_ENABLE, 0, 0); } static void enable_cpu_power_partitions(void) diff --git a/src/soc/nvidia/tegra132/clk_rst.h b/src/soc/nvidia/tegra132/clk_rst.h index 485910586a..bde2b56fd3 100644 --- a/src/soc/nvidia/tegra132/clk_rst.h +++ b/src/soc/nvidia/tegra132/clk_rst.h @@ -151,7 +151,7 @@ struct __attribute__ ((__packed__)) clk_rst_ctlr { u32 clk_enb_h_set; /* _CLK_ENB_H_SET 0x328 */ u32 clk_enb_h_clr; /* _CLK_ENB_H_CLR 0x32c */ u32 clk_enb_u_set; /* _CLK_ENB_U_SET 0x330 */ - u32 clk_enb_u_clk; /* _CLK_ENB_U_CLR 0x334 */ + u32 clk_enb_u_clr; /* _CLK_ENB_U_CLR 0x334 */ u32 _rsv22; /* 0x338 */ u32 ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD, 0x33c */ u32 rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET, 0x340 */ @@ -301,6 +301,12 @@ struct __attribute__ ((__packed__)) clk_rst_ctlr { }; check_member(clk_rst_ctlr, clk_src_i2c6, 0x65C); +#define CLK_RST_REG(field_) \ + (&(((struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE)->field_)) + +/* L, H, U, V, W, X */ +#define DEV_CONFIG_BLOCKS 6 + #define TEGRA_DEV_L 0 #define TEGRA_DEV_H 1 #define TEGRA_DEV_U 2 diff --git a/src/soc/nvidia/tegra132/clock.c b/src/soc/nvidia/tegra132/clock.c index 1dbec797ef..d811fd85d8 100644 --- a/src/soc/nvidia/tegra132/clock.c +++ b/src/soc/nvidia/tegra132/clock.c @@ -403,9 +403,8 @@ void clock_early_uart(void) write32(CLK_SRC_DEV_ID(UARTA, CLK_M) << CLK_SOURCE_SHIFT | CLK_UART_DIV_OVERRIDE | CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900), &clk_rst->clk_src_uarta); - setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA); - udelay(2); - clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA); + + clock_enable_clear_reset_l(CLK_L_UARTA); } /* Enable output clock (CLK1~3) for external peripherals. */ @@ -593,36 +592,70 @@ void clock_grp_enable_clear_reset(u32 val, u32* clk_enb_set_reg, writel(val, rst_dev_clr_reg); } -void clock_enable(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x) +static u32 * const clk_enb_set_arr[DEV_CONFIG_BLOCKS] = { + CLK_RST_REG(clk_enb_l_set), + CLK_RST_REG(clk_enb_h_set), + CLK_RST_REG(clk_enb_u_set), + CLK_RST_REG(clk_enb_v_set), + CLK_RST_REG(clk_enb_w_set), + CLK_RST_REG(clk_enb_x_set), +}; + +static u32 * const clk_enb_clr_arr[DEV_CONFIG_BLOCKS] = { + CLK_RST_REG(clk_enb_l_clr), + CLK_RST_REG(clk_enb_h_clr), + CLK_RST_REG(clk_enb_u_clr), + CLK_RST_REG(clk_enb_v_clr), + CLK_RST_REG(clk_enb_w_clr), + CLK_RST_REG(clk_enb_x_clr), +}; + +static u32 * const rst_dev_set_arr[DEV_CONFIG_BLOCKS] = { + CLK_RST_REG(rst_dev_l_set), + CLK_RST_REG(rst_dev_h_set), + CLK_RST_REG(rst_dev_u_set), + CLK_RST_REG(rst_dev_v_set), + CLK_RST_REG(rst_dev_w_set), + CLK_RST_REG(rst_dev_x_set), +}; + +static u32 * const rst_dev_clr_arr[DEV_CONFIG_BLOCKS] = { + CLK_RST_REG(rst_dev_l_clr), + CLK_RST_REG(rst_dev_h_clr), + CLK_RST_REG(rst_dev_u_clr), + CLK_RST_REG(rst_dev_v_clr), + CLK_RST_REG(rst_dev_w_clr), + CLK_RST_REG(rst_dev_x_clr), +}; + +static void clock_write_regs(u32 * const regs[DEV_CONFIG_BLOCKS], + u32 bits[DEV_CONFIG_BLOCKS]) +{ + int i = 0; + + for (; i < DEV_CONFIG_BLOCKS; i++) + if (bits[i]) + writel(bits[i], regs[i]); +} + +void clock_enable_regs(u32 bits[DEV_CONFIG_BLOCKS]) +{ + clock_write_regs(clk_enb_set_arr, bits); +} + +void clock_disable_regs(u32 bits[DEV_CONFIG_BLOCKS]) { - if (l) - writel(l, &clk_rst->clk_enb_l_set); - if (h) - writel(h, &clk_rst->clk_enb_h_set); - if (u) - writel(u, &clk_rst->clk_enb_u_set); - if (v) - writel(v, &clk_rst->clk_enb_v_set); - if (w) - writel(w, &clk_rst->clk_enb_w_set); - if (x) - writel(x, &clk_rst->clk_enb_x_set); + clock_write_regs(clk_enb_clr_arr, bits); } -void clock_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x) +void clock_set_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]) { - if (l) - writel(l, &clk_rst->rst_dev_l_clr); - if (h) - writel(h, &clk_rst->rst_dev_h_clr); - if (u) - writel(u, &clk_rst->rst_dev_u_clr); - if (v) - writel(v, &clk_rst->rst_dev_v_clr); - if (w) - writel(w, &clk_rst->rst_dev_w_clr); - if (x) - writel(x, &clk_rst->rst_dev_x_clr); + clock_write_regs(rst_dev_set_arr, bits); +} + +void clock_clr_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]) +{ + clock_write_regs(rst_dev_clr_arr, bits); } void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x) @@ -632,47 +665,48 @@ void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x) /* Give clocks time to stabilize. */ udelay(IO_STABILIZATION_DELAY); - clock_clear_reset(l, h, u, v, w, x); + clock_clr_reset(l, h, u, v, w, x); +} + +static void clock_reset_dev(u32 *setaddr, u32 *clraddr, u32 bit) +{ + writel(bit, setaddr); + udelay(LOGIC_STABILIZATION_DELAY); + writel(bit, clraddr); } void clock_reset_l(u32 bit) { - writel(bit, &clk_rst->rst_dev_l_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_l_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_l_set), CLK_RST_REG(rst_dev_l_clr), + bit); } void clock_reset_h(u32 bit) { - writel(bit, &clk_rst->rst_dev_h_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_h_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_h_set), CLK_RST_REG(rst_dev_h_clr), + bit); } void clock_reset_u(u32 bit) { - writel(bit, &clk_rst->rst_dev_u_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_u_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_u_set), CLK_RST_REG(rst_dev_u_clr), + bit); } void clock_reset_v(u32 bit) { - writel(bit, &clk_rst->rst_dev_v_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_v_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_v_set), CLK_RST_REG(rst_dev_v_clr), + bit); } void clock_reset_w(u32 bit) { - writel(bit, &clk_rst->rst_dev_w_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_w_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_w_set), CLK_RST_REG(rst_dev_w_clr), + bit); } void clock_reset_x(u32 bit) { - writel(bit, &clk_rst->rst_dev_x_set); - udelay(1); - writel(bit, &clk_rst->rst_dev_x_clr); + clock_reset_dev(CLK_RST_REG(rst_dev_x_set), CLK_RST_REG(rst_dev_x_clr), + bit); } diff --git a/src/soc/nvidia/tegra132/funitcfg.c b/src/soc/nvidia/tegra132/funitcfg.c index 41bbc4ad8a..662849fd51 100644 --- a/src/soc/nvidia/tegra132/funitcfg.c +++ b/src/soc/nvidia/tegra132/funitcfg.c @@ -47,9 +47,6 @@ enum { CLK_X_SET = 5, }; -#define CLK_RST_REG(field_) \ - &(((struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE)->field_) - #define CLK_SET_REGS(x) \ { \ CLK_RST_REG(clk_enb_##x##_set), \ diff --git a/src/soc/nvidia/tegra132/i2c6.c b/src/soc/nvidia/tegra132/i2c6.c index af015057b3..887e2bb4b5 100644 --- a/src/soc/nvidia/tegra132/i2c6.c +++ b/src/soc/nvidia/tegra132/i2c6.c @@ -53,8 +53,7 @@ static void remove_clamps(int id) static void enable_sor_periph_clocks(void) { - setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_HOST1X); - setbits_le32(&clk_rst->clk_out_enb_x, CLK_X_DPAUX); + clock_enable(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX); /* Give clocks time to stabilize. */ udelay(IO_STABILIZATION_DELAY); @@ -62,8 +61,7 @@ static void enable_sor_periph_clocks(void) static void disable_sor_periph_clocks(void) { - clrbits_le32(&clk_rst->clk_out_enb_l, CLK_L_HOST1X); - clrbits_le32(&clk_rst->clk_out_enb_x, CLK_X_DPAUX); + clock_disable(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX); /* Give clocks time to stabilize. */ udelay(IO_STABILIZATION_DELAY); @@ -71,8 +69,7 @@ static void disable_sor_periph_clocks(void) static void unreset_sor_periphs(void) { - clrbits_le32(&clk_rst->rst_dev_l, CLK_L_HOST1X); - clrbits_le32(&clk_rst->rst_dev_x, CLK_X_DPAUX); + clock_clr_reset(CLK_L_HOST1X, 0, 0, 0, 0, CLK_X_DPAUX); } void soc_configure_i2c6pad(void) @@ -108,5 +105,5 @@ void soc_configure_i2c6pad(void) /* Stop Host1X/DPAUX clocks and reset Host1X */ disable_sor_periph_clocks(); - setbits_le32(&clk_rst->rst_dev_l, CLK_L_HOST1X); + clock_set_reset_l(CLK_L_HOST1X); } diff --git a/src/soc/nvidia/tegra132/include/soc/clock.h b/src/soc/nvidia/tegra132/include/soc/clock.h index 4f822e4a77..51e4f5f80c 100644 --- a/src/soc/nvidia/tegra132/include/soc/clock.h +++ b/src/soc/nvidia/tegra132/include/soc/clock.h @@ -226,6 +226,7 @@ enum { #define CLOCK_PLL_STABLE_DELAY_US 300 #define IO_STABILIZATION_DELAY (2) +#define LOGIC_STABILIZATION_DELAY (2) /* Calculate clock fractional divider value from ref and target frequencies. * This is for a U7.1 format. This is not well written up in the book and @@ -301,6 +302,71 @@ static inline void _clock_set_div(u32 *reg, const char *name, u32 div, #define TEGRA_PLLD_KHZ (925000) #define TEGRA_PLLU_KHZ (960000) +#define clock_enable(l, h, u, v, w, x) \ + do { \ + u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x}; \ + clock_enable_regs(bits); \ + } while (0) + +#define clock_disable(l, h, u, v, w, x) \ + do { \ + u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x}; \ + clock_disable_regs(bits); \ + } while (0) + +#define clock_set_reset(l, h, u, v, w, x) \ + do { \ + u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x}; \ + clock_set_reset_regs(bits); \ + } while (0) + +#define clock_clr_reset(l, h, u, v, w, x) \ + do { \ + u32 bits[DEV_CONFIG_BLOCKS] = {l, h, u, v, w, x}; \ + clock_clr_reset_regs(bits); \ + } while (0) + +#define clock_enable_l(l) clock_enable(l, 0, 0, 0, 0, 0) +#define clock_enable_h(h) clock_enable(0, h, 0, 0, 0, 0) +#define clock_enable_u(u) clock_enable(0, 0, u, 0, 0, 0) +#define clock_enable_v(v) clock_enable(0, 0, 0, v, 0, 0) +#define clock_enable_w(w) clock_enable(0, 0, 0, 0, w, 0) +#define clock_enable_x(x) clock_enable(0, 0, 0, 0, 0, x) + +#define clock_disable_l(l) clock_disable(l, 0, 0, 0, 0, 0) +#define clock_disable_h(h) clock_disable(0, h, 0, 0, 0, 0) +#define clock_disable_u(u) clock_disable(0, 0, u, 0, 0, 0) +#define clock_disable_v(v) clock_disable(0, 0, 0, v, 0, 0) +#define clock_disable_w(w) clock_disable(0, 0, 0, 0, w, 0) +#define clock_disable_x(x) clock_disable(0, 0, 0, 0, 0, x) + +#define clock_set_reset_l(l) clock_set_reset(l, 0, 0, 0, 0, 0) +#define clock_set_reset_h(h) clock_set_reset(0, h, 0, 0, 0, 0) +#define clock_set_reset_u(u) clock_set_reset(0, 0, u, 0, 0, 0) +#define clock_set_reset_v(v) clock_set_reset(0, 0, 0, v, 0, 0) +#define clock_set_reset_w(w) clock_set_reset(0, 0, 0, 0, w, 0) +#define clock_set_reset_x(x) clock_set_reset(0, 0, 0, 0, 0, x) + +#define clock_clr_reset_l(l) clock_clr_reset(l, 0, 0, 0, 0, 0) +#define clock_clr_reset_h(h) clock_clr_reset(0, h, 0, 0, 0, 0) +#define clock_clr_reset_u(u) clock_clr_reset(0, 0, u, 0, 0, 0) +#define clock_clr_reset_v(v) clock_clr_reset(0, 0, 0, v, 0, 0) +#define clock_clr_reset_w(w) clock_clr_reset(0, 0, 0, 0, w, 0) +#define clock_clr_reset_x(x) clock_clr_reset(0, 0, 0, 0, 0, x) + +#define clock_enable_clear_reset_l(l) \ + clock_enable_clear_reset(l, 0, 0, 0, 0, 0) +#define clock_enable_clear_reset_h(h) \ + clock_enable_clear_reset(0, h, 0, 0, 0, 0) +#define clock_enable_clear_reset_u(u) \ + clock_enable_clear_reset(0, 0, u, 0, 0, 0) +#define clock_enable_clear_reset_v(v) \ + clock_enable_clear_reset(0, 0, 0, v, 0, 0) +#define clock_enable_clear_reset_w(w) \ + clock_enable_clear_reset(0, 0, 0, 0, w, 0) +#define clock_enable_clear_reset_x(x) \ + clock_enable_clear_reset(0, 0, 0, 0, 0, x) + int clock_get_osc_khz(void); int clock_get_pll_input_khz(void); u32 clock_display(u32 frequency); @@ -311,8 +377,10 @@ void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90, u32 same_freq); void clock_cpu0_config(void); void clock_halt_avp(void); -void clock_enable(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x); -void clock_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x); +void clock_enable_regs(u32 bits[DEV_CONFIG_BLOCKS]); +void clock_disable_regs(u32 bits[DEV_CONFIG_BLOCKS]); +void clock_set_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]); +void clock_clr_reset_regs(u32 bits[DEV_CONFIG_BLOCKS]); void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x); void clock_grp_enable_clear_reset(u32 val, u32* clk_enb_set_reg, u32* rst_dev_clr_reg); void clock_reset_l(u32 l); -- cgit v1.2.3