tegra132: Fix clock apis
Instead of directly using the clk_src_id based on enum for clock source, every device needs to have its own set of clk source ids defined. This prevents accidentally selecting a wrong clk source if the ids are different from host1x's. Also, clk_src_id is separated from clk_src_freq_id. clk_src_id is the clk src id represented in CLK_SOURCE_<dev> registers, whereas clk_src_freq_id is used for handling the common clock sources based on id to get the proper frequency in software. [pg: integrated a later commit to fix the build] BUG=chrome-os-partner:31821 BRANCH=None TEST=Compiles successfully and boots to kernel prompt Change-Id: I5d40fb49b81e8838b2be071d32c466213215e0d6 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 27d5d6a34d1c826c6095c18368efb78c228d4ca8 Original-Change-Id: I5c88bed62841ebd81665cf8ffd82b0d88255f927 Original-Signed-off-by: Furquan Shaikh <furquan@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/216761 Original-Tested-by: Furquan Shaikh <furquan@chromium.org> Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org> Original-Commit-Id: 13c30c50a9e8a7f3c48673a2f6c144ba546129b6 Original-Change-Id: I6659858c24e925aec9495bf64344c0000ad19b4c Original-Signed-off-by: Tom Warren <twarren@nvidia.com> Original-Reviewed-on: https://chromium-review.googlesource.com/217342 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/9033 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
c913a9c076
commit
8fdcf3287c
|
@ -400,7 +400,8 @@ clock_display(u32 frequency)
|
||||||
* been determined through trial and error (must lead to div 13 at 24MHz). */
|
* been determined through trial and error (must lead to div 13 at 24MHz). */
|
||||||
void clock_early_uart(void)
|
void clock_early_uart(void)
|
||||||
{
|
{
|
||||||
write32(CLK_M << CLK_SOURCE_SHIFT | CLK_UART_DIV_OVERRIDE |
|
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);
|
CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900), &clk_rst->clk_src_uarta);
|
||||||
setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
|
setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
|
||||||
udelay(2);
|
udelay(2);
|
||||||
|
|
|
@ -98,11 +98,11 @@ static const struct funit_cfg_data funit_data[] = {
|
||||||
_Static_assert(ARRAY_SIZE(funit_data) == FUNIT_INDEX_MAX,
|
_Static_assert(ARRAY_SIZE(funit_data) == FUNIT_INDEX_MAX,
|
||||||
"funit_cfg_data array not filled out!");
|
"funit_cfg_data array not filled out!");
|
||||||
|
|
||||||
static inline uint32_t get_clk_src_freq(uint32_t clk_src)
|
static inline uint32_t get_clk_src_freq(uint32_t clk_src_freq_id)
|
||||||
{
|
{
|
||||||
uint32_t freq = 0;
|
uint32_t freq = 0;
|
||||||
|
|
||||||
switch(clk_src) {
|
switch (clk_src_freq_id) {
|
||||||
case CLK_M:
|
case CLK_M:
|
||||||
freq = TEGRA_CLK_M_KHZ;
|
freq = TEGRA_CLK_M_KHZ;
|
||||||
break;
|
break;
|
||||||
|
@ -111,7 +111,7 @@ static inline uint32_t get_clk_src_freq(uint32_t clk_src)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(BIOS_SPEW, "%s ERROR: Unknown clk_src %d\n",
|
printk(BIOS_SPEW, "%s ERROR: Unknown clk_src %d\n",
|
||||||
__func__,clk_src);
|
__func__, clk_src_freq_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
|
@ -125,7 +125,7 @@ static void configure_clock(const struct funit_cfg * const entry,
|
||||||
uint32_t clk_div_mask;
|
uint32_t clk_div_mask;
|
||||||
uint32_t clk_src_freq;
|
uint32_t clk_src_freq;
|
||||||
|
|
||||||
clk_src_freq = get_clk_src_freq(entry->clk_src_id);
|
clk_src_freq = get_clk_src_freq(entry->clk_src_freq_id);
|
||||||
|
|
||||||
if (strncmp(funit->name, funit_i2c, strlen(funit_i2c)) == 0) {
|
if (strncmp(funit->name, funit_i2c, strlen(funit_i2c)) == 0) {
|
||||||
/* I2C funit */
|
/* I2C funit */
|
||||||
|
|
|
@ -176,6 +176,52 @@ enum {
|
||||||
CLK_X_SPARE = 0x1 << 0,
|
CLK_X_SPARE = 0x1 << 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PLLP = 0,
|
||||||
|
PLLC2 = 1,
|
||||||
|
PLLC = 2,
|
||||||
|
PLLC3 = 3,
|
||||||
|
PLLM = 4,
|
||||||
|
CLK_M = 5,
|
||||||
|
CLK_S = 6,
|
||||||
|
PLLE = 7,
|
||||||
|
PLLA = 8,
|
||||||
|
UNUSED = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLK_SRC_DEV_ID(dev, src) CLK_SRC_##dev##_##src
|
||||||
|
#define CLK_SRC_FREQ_ID(dev, src) CLK_SRC_FREQ_##dev##_##src
|
||||||
|
|
||||||
|
#define CLK_SRC_DEVICE(dev, a, b, c, d, e, f, g) \
|
||||||
|
CLK_SRC_DEV_ID(dev, a) = 0, \
|
||||||
|
CLK_SRC_DEV_ID(dev, b) = 1, \
|
||||||
|
CLK_SRC_DEV_ID(dev, c) = 2, \
|
||||||
|
CLK_SRC_DEV_ID(dev, d) = 3, \
|
||||||
|
CLK_SRC_DEV_ID(dev, e) = 4, \
|
||||||
|
CLK_SRC_DEV_ID(dev, f) = 5, \
|
||||||
|
CLK_SRC_DEV_ID(dev, g) = 6, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, a) = a, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, b) = b, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, c) = c, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, d) = d, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, e) = e, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, f) = f, \
|
||||||
|
CLK_SRC_FREQ_ID(dev, g) = g
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CLK_SRC_DEVICE(host1x, PLLM, PLLC2, PLLC, PLLC3, PLLP, UNUSED, PLLA),
|
||||||
|
CLK_SRC_DEVICE(I2C2, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(I2C3, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(I2C5, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(I2C6, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(mselect, PLLP, PLLC2, PLLC, PLLC3, PLLM, CLK_S, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(SBC1, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(SBC4, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(SDMMC3, PLLP, PLLC2, PLLC, PLLC3, PLLM, PLLE, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(SDMMC4, PLLP, PLLC2, PLLC, PLLC3, PLLM, PLLE, CLK_M),
|
||||||
|
CLK_SRC_DEVICE(UARTA, PLLP, PLLC2, PLLC, PLLC3, PLLM, UNUSED, CLK_M),
|
||||||
|
};
|
||||||
|
|
||||||
/* PLL stabilization delay in usec */
|
/* PLL stabilization delay in usec */
|
||||||
#define CLOCK_PLL_STABLE_DELAY_US 300
|
#define CLOCK_PLL_STABLE_DELAY_US 300
|
||||||
|
|
||||||
|
@ -242,38 +288,10 @@ static inline void _clock_set_div(u32 *reg, const char *name, u32 div,
|
||||||
#define CLK_DIV_MASK 0xff
|
#define CLK_DIV_MASK 0xff
|
||||||
#define CLK_DIV_MASK_I2C 0xffff
|
#define CLK_DIV_MASK_I2C 0xffff
|
||||||
|
|
||||||
#define clock_configure_irregular_source(device, src, freq, src_id) \
|
#define clock_configure_source(device, src, freq) \
|
||||||
_clock_set_div(&clk_rst->clk_src_##device, #device, \
|
_clock_set_div(&clk_rst->clk_src_##device, #device, \
|
||||||
get_clk_div(TEGRA_##src##_KHZ, freq), CLK_DIV_MASK, src_id)
|
get_clk_div(TEGRA_##src##_KHZ, freq), CLK_DIV_MASK, \
|
||||||
|
CLK_SRC_DEV_ID(device, src))
|
||||||
/* Warning: Some devices just use different bits for the same sources for no
|
|
||||||
* apparent reason. *Always* double-check the TRM before trusting this macro. */
|
|
||||||
#define clock_configure_source(device, src, freq) \
|
|
||||||
clock_configure_irregular_source(device, src, freq, src)
|
|
||||||
|
|
||||||
/* The I2C divisors are not 7.1 divisors like the others, they divide by n + 1
|
|
||||||
* directly. Also, there are internal divisors in the I2C controller itself.
|
|
||||||
* We can deal with those here and make it easier to select what the actual
|
|
||||||
* bus frequency will be. The 0x19 value is the default divisor in the
|
|
||||||
* clk_divisor register in the controller, and 8 is just a magic number in the
|
|
||||||
* documentation.
|
|
||||||
*/
|
|
||||||
#define clock_configure_i2c_scl_freq(device, src, freq) \
|
|
||||||
_clock_set_div(&clk_rst->clk_src_##device, #device, \
|
|
||||||
get_i2c_clk_div(TEGRA_##src##_KHZ, freq), \
|
|
||||||
CLK_DIV_MASK_I2C, src)
|
|
||||||
|
|
||||||
enum clock_source { /* Careful: Not true for all sources, always check TRM! */
|
|
||||||
PLLP = 0,
|
|
||||||
PLLC2 = 1,
|
|
||||||
PLLC = 2,
|
|
||||||
PLLD = 2,
|
|
||||||
PLLC3 = 3,
|
|
||||||
PLLA = 3,
|
|
||||||
PLLM = 4,
|
|
||||||
PLLD2 = 5,
|
|
||||||
CLK_M = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* soc-specific */
|
/* soc-specific */
|
||||||
#define TEGRA_CLK_M_KHZ clock_get_osc_khz()
|
#define TEGRA_CLK_M_KHZ clock_get_osc_khz()
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum {
|
||||||
struct funit_cfg {
|
struct funit_cfg {
|
||||||
uint32_t funit_index;
|
uint32_t funit_index;
|
||||||
uint32_t clk_src_id;
|
uint32_t clk_src_id;
|
||||||
|
uint32_t clk_src_freq_id;
|
||||||
uint32_t clk_dev_freq_khz;
|
uint32_t clk_dev_freq_khz;
|
||||||
struct pad_config const* pad_cfg;
|
struct pad_config const* pad_cfg;
|
||||||
size_t pad_cfg_size;
|
size_t pad_cfg_size;
|
||||||
|
@ -69,7 +70,8 @@ struct funit_cfg {
|
||||||
#define FUNIT_CFG(_funit,_clk_src,_clk_freq,_cfg,_cfg_size) \
|
#define FUNIT_CFG(_funit,_clk_src,_clk_freq,_cfg,_cfg_size) \
|
||||||
{ \
|
{ \
|
||||||
.funit_index = FUNIT_INDEX(_funit), \
|
.funit_index = FUNIT_INDEX(_funit), \
|
||||||
.clk_src_id = _clk_src, \
|
.clk_src_id = CLK_SRC_DEV_ID(_funit, _clk_src), \
|
||||||
|
.clk_src_freq_id = CLK_SRC_FREQ_ID(_funit, _clk_src), \
|
||||||
.clk_dev_freq_khz = _clk_freq, \
|
.clk_dev_freq_khz = _clk_freq, \
|
||||||
.pad_cfg = _cfg, \
|
.pad_cfg = _cfg, \
|
||||||
.pad_cfg_size = _cfg_size, \
|
.pad_cfg_size = _cfg_size, \
|
||||||
|
|
Loading…
Reference in New Issue