diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2016-07-11 07:58:33 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-07-11 07:58:33 +0200 |
commit | e54183d6d4eb575051e67a020094787c113f238d (patch) | |
tree | 3525f2ed456f71250abec15aa2f1a0d47e0c14be | |
parent | e2da792a523bf4366943545217fee574219b263f (diff) | |
parent | ad30a80ddb1bc2e7090768e575bb97f9f7be1255 (diff) | |
download | barebox-e54183d6d4eb575051e67a020094787c113f238d.tar.gz barebox-e54183d6d4eb575051e67a020094787c113f238d.tar.xz |
Merge branch 'for-next/mips'
-rw-r--r-- | arch/mips/boards/black-swift/include/board/board_pbl_start.h | 2 | ||||
-rw-r--r-- | arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h | 2 | ||||
-rw-r--r-- | arch/mips/lib/csrc-r4k.c | 24 | ||||
-rw-r--r-- | arch/mips/mach-ath79/include/mach/ar71xx_regs.h | 14 | ||||
-rw-r--r-- | arch/mips/mach-ath79/include/mach/pbl_macros.h | 63 | ||||
-rw-r--r-- | drivers/of/base.c | 86 | ||||
-rw-r--r-- | include/of.h | 10 |
7 files changed, 199 insertions, 2 deletions
diff --git a/arch/mips/boards/black-swift/include/board/board_pbl_start.h b/arch/mips/boards/black-swift/include/board/board_pbl_start.h index ee21a85ac9..4c2ab2ef0f 100644 --- a/arch/mips/boards/black-swift/include/board/board_pbl_start.h +++ b/arch/mips/boards/black-swift/include/board/board_pbl_start.h @@ -26,6 +26,8 @@ mips_barebox_10h + pbl_ar9331_wmac_enable + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 diff --git a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h index ef0d36dc38..3a7b560a05 100644 --- a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h +++ b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h @@ -26,6 +26,8 @@ mips_barebox_10h + pbl_ar9331_wmac_enable + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 diff --git a/arch/mips/lib/csrc-r4k.c b/arch/mips/lib/csrc-r4k.c index 5c3f18ff24..6f6e18c8e8 100644 --- a/arch/mips/lib/csrc-r4k.c +++ b/arch/mips/lib/csrc-r4k.c @@ -21,6 +21,8 @@ */ #include <init.h> +#include <of.h> +#include <linux/clk.h> #include <clock.h> #include <io.h> #include <asm/mipsregs.h> @@ -37,8 +39,26 @@ static struct clocksource cs = { static int clocksource_init(void) { - cs.mult = clocksource_hz2mult(100000000, cs.shift); + unsigned int mips_hpt_frequency; + struct device_node *np; + struct clk *clk; + + /* default rate: 100 MHz */ + mips_hpt_frequency = 100000000; + + if (IS_ENABLED(CONFIG_OFTREE)) { + np = of_get_cpu_node(0, NULL); + if (np) { + clk = of_clk_get(np, 0); + if (!IS_ERR(clk)) { + mips_hpt_frequency = clk_get_rate(clk) / 2; + } + } + } + + clocks_calc_mult_shift(&cs.mult, &cs.shift, + mips_hpt_frequency, NSEC_PER_SEC, 10); return init_clock(&cs); } -core_initcall(clocksource_init); +postcore_initcall(clocksource_init); diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h index 4cbe94a487..de96c565a6 100644 --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h @@ -31,11 +31,25 @@ #define AR71XX_PLL_SIZE 0x100 #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) #define AR71XX_RESET_SIZE 0x100 +#define AR71XX_RTC_BASE (AR71XX_APB_BASE + 0x00107000) +#define AR71XX_RTC_SIZE 0x100 #define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) #define AR933X_UART_SIZE 0x14 /* + * RTC block + */ +#define AR933X_RTC_REG_RESET 0x40 +#define AR933X_RTC_REG_STATUS 0x44 +#define AR933X_RTC_REG_DERIVED 0x48 +#define AR933X_RTC_REG_FORCE_WAKE 0x4c +#define AR933X_RTC_REG_INT_CAUSE 0x50 +#define AR933X_RTC_REG_CAUSE_CLR 0x50 +#define AR933X_RTC_REG_INT_ENABLE 0x54 +#define AR933X_RTC_REG_INT_MASKE 0x58 + +/* * DDR_CTRL block */ #define AR933X_DDR_CONFIG 0x00 diff --git a/arch/mips/mach-ath79/include/mach/pbl_macros.h b/arch/mips/mach-ath79/include/mach/pbl_macros.h index 8f4d09aec4..680fcbb867 100644 --- a/arch/mips/mach-ath79/include/mach/pbl_macros.h +++ b/arch/mips/mach-ath79/include/mach/pbl_macros.h @@ -274,4 +274,67 @@ normal_path: .set pop .endm +.macro pbl_ar9331_wmac_enable + .set push + .set noreorder + + /* These three WLAN_RESET will avoid original issue */ + li t3, 0x03 +1: + li t0, CKSEG1ADDR(AR71XX_RESET_BASE) + lw t1, AR933X_RESET_REG_RESET_MODULE(t0) + ori t1, t1, 0x0800 + sw t1, AR933X_RESET_REG_RESET_MODULE(t0) + nop + lw t1, AR933X_RESET_REG_RESET_MODULE(t0) + li t2, 0xfffff7ff + and t1, t1, t2 + sw t1, AR933X_RESET_REG_RESET_MODULE(t0) + nop + addi t3, t3, -1 + bnez t3, 1b + nop + + li t2, 0x20 +2: + beqz t2, 1b + nop + addi t2, t2, -1 + lw t5, AR933X_RESET_REG_BOOTSTRAP(t0) + andi t1, t5, 0x10 + bnez t1, 2b + nop + + li t1, 0x02110E + sw t1, AR933X_RESET_REG_BOOTSTRAP(t0) + nop + + /* RTC Force Wake */ + li t0, CKSEG1ADDR(AR71XX_RTC_BASE) + li t1, 0x03 + sw t1, AR933X_RTC_REG_FORCE_WAKE(t0) + nop + nop + + /* RTC Reset */ + li t1, 0x00 + sw t1, AR933X_RTC_REG_RESET(t0) + nop + nop + + li t1, 0x01 + sw t1, AR933X_RTC_REG_RESET(t0) + nop + nop + + /* Wait for RTC in on state */ +1: + lw t1, AR933X_RTC_REG_STATUS(t0) + andi t1, t1, 0x02 + beqz t1, 1b + nop + + .set pop +.endm + #endif /* __ASM_MACH_ATH79_PBL_MACROS_H */ diff --git a/drivers/of/base.c b/drivers/of/base.c index 3099c91579..1e6c33dbf2 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -380,6 +380,92 @@ const void *of_get_property(const struct device_node *np, const char *name, } EXPORT_SYMBOL(of_get_property); +/* + * arch_match_cpu_phys_id - Match the given logical CPU and physical id + * + * @cpu: logical cpu index of a core/thread + * @phys_id: physical identifier of a core/thread + * + * Returns true if the physical identifier and the logical cpu index + * correspond to the same core/thread, false otherwise. + */ +static bool arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return (u32)phys_id == cpu; +} + +/** + * Checks if the given "prop_name" property holds the physical id of the + * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not + * NULL, local thread number within the core is returned in it. + */ +static bool __of_find_n_match_cpu_property(struct device_node *cpun, + const char *prop_name, int cpu, unsigned int *thread) +{ + const __be32 *cell; + int ac, prop_len, tid; + u64 hwid; + + ac = of_n_addr_cells(cpun); + cell = of_get_property(cpun, prop_name, &prop_len); + if (!cell || !ac) + return false; + prop_len /= sizeof(*cell) * ac; + for (tid = 0; tid < prop_len; tid++) { + hwid = of_read_number(cell, ac); + if (arch_match_cpu_phys_id(cpu, hwid)) { + if (thread) + *thread = tid; + return true; + } + cell += ac; + } + return false; +} + +/* + * arch_find_n_match_cpu_physical_id - See if the given device node is + * for the cpu corresponding to logical cpu 'cpu'. Return true if so, + * else false. If 'thread' is non-NULL, the local thread number within the + * core is returned in it. + */ +static bool arch_find_n_match_cpu_physical_id(struct device_node *cpun, + int cpu, unsigned int *thread) +{ + return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread); +} + +/** + * of_get_cpu_node - Get device node associated with the given logical CPU + * + * @cpu: CPU number(logical index) for which device node is required + * @thread: if not NULL, local thread number within the physical core is + * returned + * + * The main purpose of this function is to retrieve the device node for the + * given logical CPU index. It should be used to initialize the of_node in + * cpu device. Once of_node in cpu device is populated, all the further + * references can use that instead. + * + * CPU logical to physical index mapping is architecture specific and is built + * before booting secondary cores. This function uses arch_match_cpu_phys_id + * which can be overridden by architecture specific implementation. + * + * Returns a node pointer for the logical cpu with refcount incremented, use + * of_node_put() on it when done. Returns NULL if not found. + */ +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) +{ + struct device_node *cpun; + + for_each_node_by_type(cpun, "cpu") { + if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) + return cpun; + } + return NULL; +} +EXPORT_SYMBOL(of_get_cpu_node); + /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ diff --git a/include/of.h b/include/of.h index 8c8f57a7cc..ed6e870473 100644 --- a/include/of.h +++ b/include/of.h @@ -111,6 +111,7 @@ extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); extern const void *of_get_property(const struct device_node *np, const char *name, int *lenp); +extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); extern int of_set_property(struct device_node *node, const char *p, const void *val, int len, int create); @@ -347,6 +348,12 @@ static inline const void *of_get_property(const struct device_node *np, return NULL; } +static inline struct device_node *of_get_cpu_node(int cpu, + unsigned int *thread) +{ + return NULL; +} + static inline int of_set_property(struct device_node *node, const char *p, const void *val, int len, int create) { @@ -639,6 +646,9 @@ static inline struct device_node *of_find_node_by_path_or_alias( #define for_each_node_by_name(dn, name) \ for (dn = of_find_node_by_name(NULL, name); dn; \ dn = of_find_node_by_name(dn, name)) +#define for_each_node_by_type(dn, type) \ + for (dn = of_find_node_by_type(NULL, type); dn; \ + dn = of_find_node_by_type(dn, type)) #define for_each_node_by_name_from(dn, root, name) \ for (dn = of_find_node_by_name(root, name); dn; \ dn = of_find_node_by_name(dn, name)) |