diff options
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/armv7/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/s5p-common/Makefile | 13 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/s5p-common/pwm.c | 57 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/s5p4418/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/s5p4418/cpu.c | 121 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/bcmns3/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/bcmns3/lowlevel.S | 98 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 28 |
9 files changed, 299 insertions, 32 deletions
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 8c955d0d52..0e83e394d5 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -42,3 +42,5 @@ obj-$(CONFIG_RMOBILE) += rmobile/ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_VF610) += vf610/ +obj-$(CONFIG_ARCH_S5P4418) += s5p4418/ +obj-$(CONFIG_ARCH_NEXELL) += s5p-common/ diff --git a/arch/arm/cpu/armv7/s5p-common/Makefile b/arch/arm/cpu/armv7/s5p-common/Makefile index 12cf804e88..bfe02389cd 100644 --- a/arch/arm/cpu/armv7/s5p-common/Makefile +++ b/arch/arm/cpu/armv7/s5p-common/Makefile @@ -3,9 +3,14 @@ # Copyright (C) 2009 Samsung Electronics # Minkyu Kang <mk7.kang@samsung.com> -obj-y += cpu_info.o +ifdef CONFIG_ARCH_NEXELL +obj-$(CONFIG_PWM_NX) += pwm.o +obj-$(CONFIG_S5P4418_ONEWIRE) += pwm.o +else +obj-y += cpu_info.o ifndef CONFIG_SPL_BUILD -obj-y += timer.o -obj-y += sromc.o -obj-$(CONFIG_PWM) += pwm.o +obj-y += timer.o +obj-y += sromc.o +obj-$(CONFIG_PWM) += pwm.o +endif endif diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c index 6b9e865803..aef2e5574b 100644 --- a/arch/arm/cpu/armv7/s5p-common/pwm.c +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c @@ -15,7 +15,11 @@ int pwm_enable(int pwm_id) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long tcon; tcon = readl(&pwm->tcon); @@ -29,7 +33,11 @@ int pwm_enable(int pwm_id) void pwm_disable(int pwm_id) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long tcon; tcon = readl(&pwm->tcon); @@ -43,14 +51,43 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq) unsigned long tin_parent_rate; unsigned int div; +#if defined(CONFIG_ARCH_NEXELL) + unsigned int pre_div; + const struct s5p_timer *pwm = + (struct s5p_timer *)PHY_BASEADDR_PWM; + unsigned int val; + struct clk *clk = clk_get(CORECLK_NAME_PCLK); + + tin_parent_rate = clk_get_rate(clk); +#else tin_parent_rate = get_pwm_clk(); +#endif + +#if defined(CONFIG_ARCH_NEXELL) + writel(0, &pwm->tcfg0); + val = readl(&pwm->tcfg0); + + if (pwm_id < 2) + div = ((val >> 0) & 0xff) + 1; + else + div = ((val >> 8) & 0xff) + 1; + writel(0, &pwm->tcfg1); + val = readl(&pwm->tcfg1); + val = (val >> MUX_DIV_SHIFT(pwm_id)) & 0xF; + pre_div = (1UL << val); + + freq = tin_parent_rate / div / pre_div; + + return freq; +#else for (div = 2; div <= 16; div *= 2) { if ((tin_parent_rate / (div << 16)) < freq) return tin_parent_rate / div; } return tin_parent_rate / 16; +#endif } #define NS_IN_SEC 1000000000UL @@ -58,7 +95,11 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq) int pwm_config(int pwm_id, int duty_ns, int period_ns) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned int offset; unsigned long tin_rate; unsigned long tin_ns; @@ -84,7 +125,12 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns) tin_rate = pwm_calc_tin(pwm_id, frequency); tin_ns = NS_IN_SEC / tin_rate; - tcnt = period_ns / tin_ns; + + if (IS_ENABLED(CONFIG_ARCH_NEXELL)) + /* The counter starts at zero. */ + tcnt = (period_ns / tin_ns) - 1; + else + tcnt = period_ns / tin_ns; /* Note, counters count down */ tcmp = duty_ns / tin_ns; @@ -115,7 +161,11 @@ int pwm_init(int pwm_id, int div, int invert) { u32 val; const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long ticks_per_period; unsigned int offset, prescaler; @@ -148,7 +198,12 @@ int pwm_init(int pwm_id, int div, int invert) ticks_per_period = -1UL; } else { const unsigned long pwm_hz = 1000; +#if defined(CONFIG_ARCH_NEXELL) + struct clk *clk = clk_get(CORECLK_NAME_PCLK); + unsigned long timer_rate_hz = clk_get_rate(clk) / +#else unsigned long timer_rate_hz = get_pwm_clk() / +#endif ((prescaler + 1) * (1 << div)); ticks_per_period = timer_rate_hz / pwm_hz; diff --git a/arch/arm/cpu/armv7/s5p4418/Makefile b/arch/arm/cpu/armv7/s5p4418/Makefile new file mode 100644 index 0000000000..321b257b6d --- /dev/null +++ b/arch/arm/cpu/armv7/s5p4418/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2016 Nexell +# Hyunseok, Jung <hsjung@nexell.co.kr> + +obj-y += cpu.o diff --git a/arch/arm/cpu/armv7/s5p4418/cpu.c b/arch/arm/cpu/armv7/s5p4418/cpu.c new file mode 100644 index 0000000000..8add9474ad --- /dev/null +++ b/arch/arm/cpu/armv7/s5p4418/cpu.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <asm/cache.h> +#include <asm/sections.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/clk.h> +#include <asm/arch/reset.h> +#include <asm/arch/tieoff.h> +#include <cpu_func.h> +#include <linux/delay.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_ARCH_CPU_INIT +#error must be define the macro "CONFIG_ARCH_CPU_INIT" +#endif + +void s_init(void) +{ +} + +static void cpu_soc_init(void) +{ + /* + * NOTE> ALIVE Power Gate must enable for Alive register access. + * must be clear wfi jump address + */ + writel(1, ALIVEPWRGATEREG); + writel(0xFFFFFFFF, SCR_ARM_SECOND_BOOT); + + /* write 0xf0 on alive scratchpad reg for boot success check */ + writel(readl(SCR_SIGNAGURE_READ) | 0xF0, (SCR_SIGNAGURE_SET)); + + /* set l2 cache tieoff */ + nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_0, 1); + nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_1, 1); +} + +#ifdef CONFIG_PL011_SERIAL +static void serial_device_init(void) +{ + char dev[10]; + int id; + + sprintf(dev, "nx-uart.%d", CONFIG_CONS_INDEX); + id = RESET_ID_UART0 + CONFIG_CONS_INDEX; + + struct clk *clk = clk_get((const char *)dev); + + /* reset control: Low active ___|--- */ + nx_rstcon_setrst(id, RSTCON_ASSERT); + udelay(10); + nx_rstcon_setrst(id, RSTCON_NEGATE); + udelay(10); + + /* set clock */ + clk_disable(clk); + clk_set_rate(clk, CONFIG_PL011_CLOCK); + clk_enable(clk); +} +#endif + +int arch_cpu_init(void) +{ + flush_dcache_all(); + cpu_soc_init(); + clk_init(); + + if (IS_ENABLED(CONFIG_PL011_SERIAL)) + serial_device_init(); + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + return 0; +} +#endif + +void reset_cpu(ulong ignored) +{ + void *clkpwr_reg = (void *)PHY_BASEADDR_CLKPWR; + const u32 sw_rst_enb_bitpos = 3; + const u32 sw_rst_enb_mask = 1 << sw_rst_enb_bitpos; + const u32 sw_rst_bitpos = 12; + const u32 sw_rst_mask = 1 << sw_rst_bitpos; + int pwrcont = 0x224; + int pwrmode = 0x228; + u32 read_value; + + read_value = readl((void *)(clkpwr_reg + pwrcont)); + + read_value &= ~sw_rst_enb_mask; + read_value |= 1 << sw_rst_enb_bitpos; + + writel(read_value, (void *)(clkpwr_reg + pwrcont)); + writel(sw_rst_mask, (void *)(clkpwr_reg + pwrmode)); +} + +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index 2e48df0eb9..7e33a183d5 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_S32V234) += s32v234/ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/ obj-$(CONFIG_ARMV8_PSCI) += psci.o obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o +obj-$(CONFIG_TARGET_BCMNS3) += bcmns3/ diff --git a/arch/arm/cpu/armv8/bcmns3/Makefile b/arch/arm/cpu/armv8/bcmns3/Makefile new file mode 100644 index 0000000000..a35e29d11a --- /dev/null +++ b/arch/arm/cpu/armv8/bcmns3/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2020 Broadcom. + +obj-y += lowlevel.o diff --git a/arch/arm/cpu/armv8/bcmns3/lowlevel.S b/arch/arm/cpu/armv8/bcmns3/lowlevel.S new file mode 100644 index 0000000000..bf1a17ab03 --- /dev/null +++ b/arch/arm/cpu/armv8/bcmns3/lowlevel.S @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Broadcom. + * + */ + +#include <asm/macro.h> +#include <linux/linkage.h> + +hnf_pstate_poll: + /* x0 has the desired status, return 0 for success, 1 for timeout + * clobber x1, x2, x3, x4, x6, x7 + */ + mov x1, x0 + mov x7, #0 /* flag for timeout */ + mrs x3, cntpct_el0 /* read timer */ + mov w0, #600 + mov w6, #1000 + mul w0, w0, w6 + add x3, x3, x0 /* timeout after 100 microseconds */ + mov x0, #0x18 + movk x0, #0x6120, lsl #16 /* HNF0_PSTATE_STATUS */ + mov w6, #4 /* HN-F node count */ +1: + ldr x2, [x0] + cmp x2, x1 /* check status */ + b.eq 2f + mrs x4, cntpct_el0 + cmp x4, x3 + b.ls 1b + mov x7, #1 /* timeout */ + b 3f +2: + add x0, x0, #0x10000 /* move to next node */ + subs w6, w6, #1 + cbnz w6, 1b +3: + mov x0, x7 + ret + +hnf_set_pstate: + /* x0 has the desired state, clobber x1, x2, x6 */ + mov x1, x0 + /* power state to SFONLY */ + mov w6, #4 /* HN-F node count */ + mov x0, #0x10 + movk x0, #0x6120, lsl #16 /* HNF0_PSTATE_REQ */ +1: /* set pstate to sfonly */ + ldr x2, [x0] + and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */ + orr x2, x2, x1 + str x2, [x0] + add x0, x0, #0x10000 /* move to next node */ + subs w6, w6, #1 + cbnz w6, 1b + + ret + +ENTRY(__asm_flush_l3_dcache) + /* + * Return status in x0 + * success 0 + * timeout 1 for setting SFONLY, 2 for FAM, 3 for both + */ + mov x29, lr + mov x8, #0 + + dsb sy + mov x0, #0x1 /* HNFPSTAT_SFONLY */ + bl hnf_set_pstate + + mov x0, #0x4 /* SFONLY status */ + bl hnf_pstate_poll + cbz x0, 1f + mov x8, #1 /* timeout */ +1: + dsb sy + mov x0, #0x3 /* HNFPSTAT_FAM */ + bl hnf_set_pstate + + mov x0, #0xc /* FAM status */ + bl hnf_pstate_poll + cbz x0, 1f + add x8, x8, #0x2 +1: + mov x0, x8 + mov lr, x29 + ret +ENDPROC(__asm_flush_l3_dcache) + +ENTRY(save_boot_params) +/* + * void set_boot_params(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) + */ + adr x4, bl33_info + str x0, [x4] + b save_boot_params_ret +ENDPROC(save_boot_params) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 0cd8e92e81..fde893e8c9 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -41,37 +41,11 @@ DECLARE_GLOBAL_DATA_PTR; #endif #ifdef CONFIG_GIC_V3_ITS -#define PENDTABLE_MAX_SZ ALIGN(BIT(ITS_MAX_LPI_NRBITS), SZ_64K) -#define PROPTABLE_MAX_SZ ALIGN(BIT(ITS_MAX_LPI_NRBITS) / 8, SZ_64K) -#define GIC_LPI_SIZE ALIGN(cpu_numcores() * PENDTABLE_MAX_SZ + \ - PROPTABLE_MAX_SZ, SZ_1M) -static int fdt_add_resv_mem_gic_rd_tables(void *blob, u64 base, size_t size) -{ - u32 phandle; - int err; - struct fdt_memory gic_rd_tables; - - gic_rd_tables.start = base; - gic_rd_tables.end = base + size - 1; - err = fdtdec_add_reserved_memory(blob, "gic-rd-tables", &gic_rd_tables, - &phandle); - if (err < 0) - debug("%s: failed to add reserved memory: %d\n", __func__, err); - - return err; -} - int ls_gic_rd_tables_init(void *blob) { - u64 gic_lpi_base; int ret; - gic_lpi_base = ALIGN(gd->arch.resv_ram - GIC_LPI_SIZE, SZ_64K); - ret = fdt_add_resv_mem_gic_rd_tables(blob, gic_lpi_base, GIC_LPI_SIZE); - if (ret) - return ret; - - ret = gic_lpi_tables_init(gic_lpi_base, cpu_numcores()); + ret = gic_lpi_tables_init(); if (ret) debug("%s: failed to init gic-lpi-tables\n", __func__); |