Re: [PATCH v3] clk/axs10x: introduce AXS10X pll driver
On 04/21, Vlad Zakharov wrote: > diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c > new file mode 100644 > index 000..e242df0 > --- /dev/null > +++ b/drivers/clk/axs10x/pll_clock.c > @@ -0,0 +1,334 @@ > +/* > + * Synopsys AXS10X SDP Generic PLL clock driver > + * > + * Copyright (C) 2017 Synopsys > + * > + * This file is licensed under the terms of the GNU General Public > + * License version 2. This program is licensed "as is" without any > + * warranty of any kind, whether express or implied. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* PLL registers addresses */ > +#define PLL_REG_IDIV 0x0 > +#define PLL_REG_FBDIV0x4 > +#define PLL_REG_ODIV 0x8 > + > +/* > + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: > + * > + * |3115|14| 13 | 12 |11 6|5 0| > + * |---RESRVED--|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| > + * ||__||__||___| > + * > + * Following macros determine the way of access to these registers > + * They should be set up only using the macros. > + * reg should be an u32 variable. > + */ > + > +#define PLL_REG_GET_LOW(reg) \ > + (((reg) & (0x3F << 0)) >> 0) > +#define PLL_REG_GET_HIGH(reg)\ > + (((reg) & (0x3F << 6)) >> 6) > +#define PLL_REG_GET_EDGE(reg)\ > + (((reg) & (BIT(12))) ? 1 : 0) > +#define PLL_REG_GET_BYPASS(reg) \ > + (((reg) & (BIT(13))) ? 1 : 0) > +#define PLL_REG_GET_NOUPD(reg) \ > + (((reg) & (BIT(14))) ? 1 : 0) > +#define PLL_REG_GET_PAD(reg) \ > + (((reg) & (0x1 << 15)) >> 15) > + > +#define PLL_REG_SET_LOW(reg, value) \ > + { reg |= (((value) & 0x3F) << 0); } > +#define PLL_REG_SET_HIGH(reg, value) \ > + { reg |= (((value) & 0x3F) << 6); } > +#define PLL_REG_SET_EDGE(reg, value) \ > + { reg |= (((value) & 0x01) << 12); } > +#define PLL_REG_SET_BYPASS(reg, value) \ > + { reg |= (((value) & 0x01) << 13); } > +#define PLL_REG_SET_NOUPD(reg, value)\ > + { reg |= (((value) & 0x01) << 14); } > +#define PLL_REG_SET_PAD(reg, value) \ > + { reg |= (((value) & 0x1) << 15); } > + > +#define PLL_LOCK BIT(0) > +#define PLL_ERRORBIT(1) > +#define PLL_MAX_LOCK_TIME 100 /* 100 us */ > + > +struct pll_cfg { > + u32 rate; > + u32 idiv; > + u32 fbdiv; > + u32 odiv; > +}; > + > +static const struct pll_cfg arc_pll_cfg[] = { > + { , 1, 1, 1 }, > + { 5000, 1, 30, 20 }, > + { 7500, 2, 45, 10 }, > + { 9000, 2, 54, 10 }, > + { 1, 1, 30, 10 }, > + { 12500, 2, 45, 6 }, > + {}, Style nitpick, please leave off trailing commas on array terminators so that we can't put more lines after them. > +}; > + > +static const struct pll_cfg pgu_pll_cfg[] = { > + { 2520, 1, 84, 90 }, > + { 5000, 1, 100, 54 }, > + { 7425, 1, 44, 16 }, > + {}, > +}; > + > +struct pll_clk { > + struct clk_hw hw; > + void __iomem *base; > + void __iomem *lock; > + const struct pll_cfg *pll_cfg; > + struct device *dev; > +}; > + > +static inline void pll_write(struct pll_clk *clk, unsigned int reg, > + unsigned int val) > +{ > + iowrite32(val, clk->base + reg); > +} > + > +static inline u32 pll_read(struct pll_clk *clk, unsigned int reg) axs10x_pll_read()? > +{ > + return ioread32(clk->base + reg); > +} > + > +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw) > +{ > + return container_of(hw, struct pll_clk, hw); > +} > + > +static inline u32 div_get_value(unsigned int reg) > +{ > + if (PLL_REG_GET_BYPASS(reg)) > + return 1; > + > + return PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg); > +} > + > +static inline u32 encode_div(unsigned int id, int upd) > +{ > + u32 div = 0; > + > + PLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1); Please add space around id % 2. > + PLL_REG_SET_HIGH(div, id >> 1); > + PLL_REG_SET_EDGE(div, id%2); ditto. > + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); > + PLL_REG_SET_NOUPD(div, !upd); > + > + return div; > +} > + > +static unsigned long pll_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + u64 rate; > + u32 idiv, fbdiv, odiv; > + struct pll_clk *clk = to_pll_clk(hw); > + > + idiv = div_get_value(pll_read(clk, PLL_REG_IDIV)); > + fbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV)); > + odiv = div_get_value(pll_read(clk, PLL_REG_ODIV)); > + > + rate = (u64)parent_rate * fbdiv; > + do_div(rate, idiv * odiv); > + > + return rate; > +}
Re: [PATCH v3] hsdk: initial port for HSDK board
On 06/01/2017 03:41 AM, Alexey Brodkin wrote: This initial port adds support of ARC HS Development Kit board with some basic features such serial port, USB, SD/MMC and Ethernet. Essentially we run Linux kernel on all 4 cores (i.e. utilize SMP) and heavily use IO Coherency for speeding-up DMA-aware peripherals. Note as opposed to other ARC boards we link Linux kernel to 0x9000_ intentionally because cores 1 and 3 configured with DCCM situated at our more usual link base 0x8000_. Signed-off-by: Eugeniy Paltsev Signed-off-by: Alexey Brodkin Cc: Vineet Gupta Cc: Rob Herring --- Changes v2 -> v3: * Added Rob to Cc-list for DT binding approval * Removed mention of prerequsite patch from commit message * Removed hsdk_early_init() as hsdk_init_per_cpu() is executed on all cores anyways including master * Cleaned-up board's .dts a little bit * Removed CONFIG_DP83867_PHY from defconfig as it was only used on FPGA prototype, on real board we use MICREL PHY which is still selected Changes v1 -> v2: * Update copyright year from 2016 to more up to date 2017 * Merge early UART clock with AXS10x as in both cases that's 33.3 MHz * Bump memory to 1Gb, we don't use more for now because it requires trickier IOC setup and usage * Update early platform init code: - Added missing fixup_pae_regs() to per-cpu init - Mark most of functions as "static __init" - Use writel_relaxed() for setting CREG_PAE, CREG_PAE_UPDATE is still written with stronger writel() since we don't want reordering to happen, otherwise value written to CREG_PAE won't be applied +/* + * By default ICCM is mapped to 0x7z while this area is used for + * Virtual kernel mappings, so move it to currently unused area. + */ +static void __init relocate_iccm(void) +{ + if (cpuinfo_arc700[smp_processor_id()].iccm.sz) + write_aux_reg(ARC_REG_AUX_ICCM, 0x6000); +} + +/* + * Default configuration of PAE regs doesn't work for us causing + * problems with DMA to/from peripherals even if PAE40 is not used. + */ +static void __init fixup_pae_regs(void) +{ +#define ARC_PERIPHERAL_BASE0xf000 +#defineCREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) +#defineCREG_PAE(CREG_BASE + 0x180) +#defineCREG_PAE_UPDATE (CREG_BASE + 0x194) + + /* Default is 1, which means "PAE offset = 4GByte" */ + writel_relaxed(0, (void __iomem *) CREG_PAE); + + /* Really apply settings made above */ + writel(1, (void __iomem *) CREG_PAE_UPDATE); +} + +static void __init hsdk_init_per_cpu(unsigned int cpu) +{ + relocate_iccm(); + fixup_pae_regs(); +} + A couple of things. Is the PAE register banked/replicated for each CPU. If not it only needs to be done once by the master. Now anything master does (iccm relocation specially) preferably needs to be done really early. For master, machine_desc->init_per_cpu is called pretty late in the game so better do it in init_eary. P.S. You don't need to respin, I can fix up the patch here if you agree ! +MACHINE_START(SIMULATION, "hsdk") + .dt_compat = hsdk_compat, + .init_per_cpu = hsdk_init_per_cpu, +MACHINE_END ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH v2 08/11] ARC: [plat-eznps] spinlock aware for MTM
On 05/27/2017 11:52 PM, Noam Camus wrote: From: Noam Camus This way when we execute "ex" during trying to hold lock we can switch to other HW thread and utilize the core intead of just spinning on a lock. We noticed about 10% improvement of execution time with hackbench test. Signed-off-by: Noam Camus --- arch/arc/include/asm/spinlock.h |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h index 233d5ff..0a54ce7 100644 --- a/arch/arc/include/asm/spinlock.h +++ b/arch/arc/include/asm/spinlock.h @@ -252,9 +252,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1:ex %0, [%1]\n" +#ifdef CONFIG_EZNPS_MTM_EXT + " .word %3\n" +#endif " breq %0, %2, 1b\n" : "+&r" (val) : "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__) +#ifdef CONFIG_EZNPS_MTM_EXT + , "i"(CTOP_INST_SCHD_RW) +#endif : "memory"); /* This is ugly - I will fix it up here to create an NPS version of arch_spin_lock ! -Vineet ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH v2 11/11] ARC: [plat-eznps] Handle memory error as an exception
On 05/27/2017 11:52 PM, Noam Camus wrote: From: Noam Camus This commit adds the configuration CONFIG_EZNPS_MEM_ERROR. If set, it will cause the kernel to handle user memory error as a machine check exception. It is required in order to align the NPS simulator memory error handling to the one of the NPS400 real chip behavior. We override weak symbole of mem_service to achieve that. Signed-off-by: Elad Kanfi Signed-off-by: Noam Camus --- arch/arc/plat-eznps/Kconfig | 11 +++ arch/arc/plat-eznps/entry.S | 14 ++ 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig index feaa471..c5f946c 100644 --- a/arch/arc/plat-eznps/Kconfig +++ b/arch/arc/plat-eznps/Kconfig @@ -32,3 +32,14 @@ config EZNPS_MTM_EXT any of them seem like CPU from Linux point of view. All threads within same core share the execution unit of the core and HW scheduler round robin between them. + +config EZNPS_MEM_ERROR + bool "ARC-EZchip Memory error as an exception" + depends on ARC_PLAT_EZNPS + default n + help + On the real chip of the NPS, user memory errors are handled + as a machine check exception, whereas on simulator platform + for NPS, it handled as an interrupt level 2 (like legacy arc + real chip architecture).This configuration will cause the kernel + to handle memory error as a machine check exception. Do you really need a Kconfig option here. AFAIKR you guys had some magic in platform code to determine whether running on sim or hw - can that be not used ? diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S index 328261c..03e2892 100644 --- a/arch/arc/plat-eznps/entry.S +++ b/arch/arc/plat-eznps/entry.S @@ -68,3 +68,17 @@ ENTRY(res_service) j stext END(res_service) + +#if defined(CONFIG_EZNPS_MEM_ERROR) +ENTRY(mem_service) + ; SW workaround to cover up on a difference between + ; NPS real chip and simulator behaviors. + ; NPS real chip will activate a machine check exception + ; in case of memory error, while the simulator will + ; trigger a level 2 interrupt. Therefor this code section + ; should be reached only in simulation mode. + ; DEAD END: display Regs and HALT + + j EV_MachineCheck +END(mem_service) +#endif Just squash the weak symbol patch in here - not worth a separate patch ! -Vineet ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc