From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Schwierzeck Date: Tue, 22 Dec 2015 15:11:41 +0100 Subject: [U-Boot] [PATCH v1 06/18] MIPS: Add support for Microchip PIC32MZ[DA] SoC family. In-Reply-To: <5679510B.10306@microchip.com> References: <5672F125.50705@microchip.com> <5675EE86.4010403@gmail.com> <5679510B.10306@microchip.com> Message-ID: <56795A1D.5000107@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Am 22.12.2015 um 14:32 schrieb Purna Chandra Mandal: > On 12/20/2015 05:25 AM, Daniel Schwierzeck wrote: > >> >> Am 17.12.2015 um 18:30 schrieb Purna Chandra Mandal: >>> Signed-off-by: Purna Chandra Mandal >>> --- >>> >>> arch/mips/dts/pic32mzda.dtsi | 59 +++++++++++++++ >>> arch/mips/include/asm/arch-pic32/pic32.h | 3 + >>> arch/mips/mach-pic32/Kconfig | 16 +++- >>> arch/mips/mach-pic32/Makefile | 2 +- >>> arch/mips/mach-pic32/cpu.c | 121 ++++++++++++++++++++++++++++++- >>> arch/mips/mach-pic32/lowlevel_init.S | 41 +++++++++++ >>> arch/mips/mach-pic32/reset.c | 22 ++++++ >>> 7 files changed, 261 insertions(+), 3 deletions(-) >>> create mode 100644 arch/mips/dts/pic32mzda.dtsi >>> create mode 100644 arch/mips/mach-pic32/lowlevel_init.S >>> create mode 100644 arch/mips/mach-pic32/reset.c >>> >>> diff --git a/arch/mips/dts/pic32mzda.dtsi b/arch/mips/dts/pic32mzda.dtsi >>> new file mode 100644 >>> index 0000000..1333573 >>> --- /dev/null >>> +++ b/arch/mips/dts/pic32mzda.dtsi >>> @@ -0,0 +1,59 @@ >>> +/* >>> + * Copyright 2015 Microchip Technology, Inc. >>> + * Purna Chandra Mandal, >>> + * >>> + * SPDX-License-Identifier: GPL-2.0+ >>> + */ >>> + >>> +#include >>> +#include "skeleton.dtsi" >>> + >>> +/ { >>> + compatible = "microchip,pic32mzda", "microchip,pic32mz"; >>> + >>> + cpus { >>> + cpu at 0 { >>> + compatible = "mips,mips14kc"; >>> + }; >>> + }; >>> + >>> + clock: clk at 1f801200 { >>> + compatible = "microchip,pic32mzda_clk"; >>> + reg = <0xbf801200 0x1000>; >> as mentioned in patch 02/18 the register base address should be a >> physical address > > ack. Will update. For reference do you have any example? the clk at 1f801200 already shows you the physical address. So you should use reg = <0x1f801200 0x1000>; maybe you could add a helper for drivers like this (until we have a proper ioremap implentation in U-Boot): static inline void __iomem *pic32_ioremap(fdt_addr_t addr) { return (void __iomem *) CKSEG1ADDR(addr); } in your driver probe function you could do something like this: fdt_addr_t addr; void __iomem *reg_base; addr = dev_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; reg_base = pic32_ioremap(addr); the dev_get_addr() would give you the value of 0x1f801200, which is then remapped to 0xbf801200 > >>> + }; >>> + >>> + uart1: serial at 1f822000 { >>> + compatible = "microchip,pic32mzda-uart"; >>> + reg = <0xbf822000 0x50>; >>> + interrupts = <112 IRQ_TYPE_LEVEL_HIGH>; >>> + status = "disabled"; >>> + }; >>> + >>> + uart2: serial at 1f822200 { >>> + compatible = "microchip,pic32mzda-uart"; >>> + reg = <0xbf822200 0x50>; >>> + interrupts = <145 IRQ_TYPE_LEVEL_HIGH>; >>> + status = "disabled"; >>> + }; >>> + >>> + uart6: serial at 1f822a00 { >>> + compatible = "microchip,pic32mzda-uart"; >>> + reg = <0xbf822a00 0x50>; >>> + interrupts = <188 IRQ_TYPE_LEVEL_HIGH>; >>> + status = "disabled"; >>> + }; >>> + >>> + evic: interrupt-controller at 1f810000 { >>> + compatible = "microchip,pic32mzda-evic"; >>> + interrupt-controller; >>> + #interrupt-cells = <2>; >>> + reg = <0xbf810000 0x1000>; >>> + }; >>> + >>> + pinctrl: pinctrl at 1f801400 { >>> + compatible = "microchip,pic32mzda-pinctrl"; >>> + reg = <0xbf801400 0x100>, /* in */ >>> + <0xbf801500 0x200>; /* out */ >>> + status = "disabled"; >>> + }; >>> +}; >>> diff --git a/arch/mips/include/asm/arch-pic32/pic32.h b/arch/mips/include/asm/arch-pic32/pic32.h >>> index 4f2084f..d3f428f 100644 >>> --- a/arch/mips/include/asm/arch-pic32/pic32.h >>> +++ b/arch/mips/include/asm/arch-pic32/pic32.h >>> @@ -142,4 +142,7 @@ struct pic32_reg_atomic { >>> u32 inv; >>> }; >>> >>> +/* Core */ >>> +char *get_core_name(void); >> this should be const char * > > ack. > >>> + >>> #endif /* __PIC32_REGS_H__ */ >>> diff --git a/arch/mips/mach-pic32/Kconfig b/arch/mips/mach-pic32/Kconfig >>> index e4eaf5c..9983131 100644 >>> --- a/arch/mips/mach-pic32/Kconfig >>> +++ b/arch/mips/mach-pic32/Kconfig >>> @@ -2,11 +2,23 @@ menu "Microchip PIC32 platforms" >>> depends on MACH_PIC32 >>> >>> config SYS_SOC >>> - default "none" >>> + default "pic32mzda" if SOC_PIC32MZDA >>> >>> choice >>> prompt "PIC32 SoC select" >>> >>> +config SOC_PIC32MZDA >>> + bool "Microchip PIC32MZ[DA] family" >>> + select SUPPORTS_LITTLE_ENDIAN >>> + select SUPPORTS_CPU_MIPS32_R1 >>> + select SUPPORTS_CPU_MIPS32_R2 >>> + select SYS_MIPS_CACHE_INIT_RAM_LOAD >>> + select DM_SERIAL >>> + select PIC32_SERIAL >>> + select PIC32_PINCTRL >>> + help >>> + This supports Microchip PIC32MZ[DA] family of microcontrollers. >>> + >>> endchoice >>> >>> choice >>> @@ -16,5 +28,7 @@ endchoice >>> >>> config PIC32_SUPPORTS_FDT_BOOT >>> bool "FDT Boot" >>> + select MIPS_BOOT_FDT >>> + select MIPS_BOOT_CMDLINE_LEGACY >> you do not need such a wrapper symbol. The kernel boot options are >> intended for an user. Such an option only make sense if you want to >> build different U-Boot images for booting from different media devices >> (Flash, RAM, SDHC, etc.). Then you need to pre-select some Kconfig options. > > ack. Will remove this. > >>> >>> endmenu >>> diff --git a/arch/mips/mach-pic32/Makefile b/arch/mips/mach-pic32/Makefile >>> index cb42607..03d5f27 100644 >>> --- a/arch/mips/mach-pic32/Makefile >>> +++ b/arch/mips/mach-pic32/Makefile >>> @@ -4,4 +4,4 @@ >>> # SPDX-License-Identifier: GPL-2.0+ >>> # >>> >>> -obj-y = cpu.o >>> +obj-y = cpu.o reset.o lowlevel_init.o >>> \ No newline at end of file >>> diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c >>> index 58fd3ab..f95beae 100644 >>> --- a/arch/mips/mach-pic32/cpu.c >>> +++ b/arch/mips/mach-pic32/cpu.c >>> @@ -6,8 +6,127 @@ >>> * >>> */ >>> #include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> >>> -phys_size_t initdram(int board_type) >>> +DECLARE_GLOBAL_DATA_PTR; >>> + >>> +static ulong clk_get_cpu_rate(void) >>> +{ >>> + int ret; >>> + struct udevice *dev; >>> + >>> + ret = uclass_get_device(UCLASS_CLK, 0, &dev); >>> + if (ret) { >>> + panic("uclass-clk: device not found\n"); >>> + return 0; >>> + } >>> + >>> + return clk_get_rate(dev); >>> +} >>> + >>> +/* initialize prefetch module related to cpu_clk */ >>> +static void init_prefetch(void) >>> +{ >>> + int v, nr_waits; >>> + ulong rate; >>> + >>> + rate = clk_get_cpu_rate(); >>> + >>> + /* calc and apply waits based on dynamic ECC */ >>> + v = (readl(CFGCON) >> 4) & 0x03; >>> + if (v < 2) { >>> + if (rate < 66000000) >>> + nr_waits = 0; >>> + else if (rate < 133000000) >>> + nr_waits = 1; >>> + else >>> + nr_waits = 2; >>> + } else { >>> + if (rate <= 83000000) >>> + nr_waits = 0; >>> + else if (rate <= 166000000) >>> + nr_waits = 1; >>> + else >>> + nr_waits = 2; >>> + } >>> + >>> + writel(nr_waits, PRECON); >>> + >>> + /* Enable prefetch for all */ >>> + writel(0x30, PRECONSET); >>> +} >>> + >>> +/* arch specific CPU init after DM */ >>> +int arch_cpu_init_dm(void) >>> +{ >>> + /* flash prefetch */ >>> + init_prefetch(); >>> + >>> + return 0; >>> +} >>> + >>> +/* initializes board before relocation */ >>> +__attribute__ ((weak)) int board_early_init_f(void) >>> { >>> return 0; >>> } >> that function is already declared as weak in common/board_f.c. If you >> want to implement it, you do not need to add __attribute__ ((weak)). But >> your function is empty so you can drop it entirely. > > Not able to find "weak" definition of board_early_init_f()" in common/board_f.c. > I'll remove both CONFIG_BOARD_EARLY_INIT_F from config/pic32mzdask.h and this empty definition. > you are right. This function is not weak at all and only enabled with CONFIG_BOARD_EARLY_INIT_F. >>> + >>> +int misc_init_r(void) >>> +{ >>> + set_io_port_base(0); >>> + return 0; >>> +} >>> + >>> +#ifdef CONFIG_DISPLAY_BOARDINFO >>> +char *get_core_name(void) >>> +{ >>> + u32 proc_id; >>> + char *str; >> const char * > > ack. > >>> + >>> + proc_id = read_c0_prid(); >>> + switch (proc_id) { >>> + case 0x19e28: >>> + str = "PIC32MZ[DA]"; >>> + break; >>> + default: >>> + str = "UNKNOWN"; >>> + } >>> + >>> + return str; >>> +} >>> +#endif >>> + >>> +#ifdef CONFIG_CMD_CLK >>> +int soc_clk_dump(void) >>> +{ >>> + int i, ret; >>> + struct udevice *dev; >>> + >>> + ret = uclass_get_device(UCLASS_CLK, 0, &dev); >>> + if (ret) { >>> + printf("clk-uclass not found\n"); >>> + return ret; >>> + } >>> + >>> + printf("PLL Speed: %lu MHz\n", >>> + clk_get_periph_rate(dev, PLLCLK) / 1000000); >>> + >>> + printf("CPU Clock Speed: %lu MHz\n", clk_get_rate(dev) / 1000000); >>> + >>> + for (i = PB1CLK; i <= PB7CLK; i++) >>> + printf("PB%d Clock Speed: %lu MHz\n", >>> + i - PB1CLK + 1, clk_get_periph_rate(dev, i) / 1000000); >>> + >>> + for (i = REF1CLK; i <= REF5CLK; i++) >>> + printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, >>> + clk_get_periph_rate(dev, i) / 1000000); >>> + return 0; >>> +} >>> +#endif >>> diff --git a/arch/mips/mach-pic32/lowlevel_init.S b/arch/mips/mach-pic32/lowlevel_init.S >>> new file mode 100644 >>> index 0000000..9c11761 >>> --- /dev/null >>> +++ b/arch/mips/mach-pic32/lowlevel_init.S >>> @@ -0,0 +1,41 @@ >>> +/* >>> + * (c) 2015 Purna Chandra Mandal >>> + * >>> + * SPDX-License-Identifier: GPL-2.0+ >>> + * >>> +*/ >>> + >>> +#include >>> +#include >>> +#include >>> + >>> + .text >>> + .set noreorder >>> + .set mips32 >>> + >>> + .globl lowlevel_init >>> +lowlevel_init: >> use macros LEAF(lowlevel_init) and END(lowlevel_init) > > ack. > >>> + >>> + /* >>> + * Establish Status Register >>> + * (set BEV, clear ERL, clear EXL, clear IE) >>> + */ >>> + li t1, 0x00400000 >>> + mtc0 t1, CP0_STATUS >> why do you need to set BEV? > > Good catch. There is no need to set BEV. > As ERL, EXL, IE are already cleared by start.S. So will remove above instructions completely. > >>> + >>> + /* >>> + * Establish Cause >>> + * (set IV bit) >>> + */ >>> + li t1, 0x00800000 >>> + mtc0 t1, CP0_CAUSE >>> + >>> + /* Establish Wired (and Random) */ >>> + mtc0 zero, CP0_WIRED >>> + nop >>> + >>> + /* Initialize 'boot_flags' to zero. */ >>> + li a0, 0x00000000 >> I think this could go in the common start.S before jumping to board_init_f > > Agree. > >>> + >>> + jr ra >>> + nop >>> diff --git a/arch/mips/mach-pic32/reset.c b/arch/mips/mach-pic32/reset.c >>> new file mode 100644 >>> index 0000000..0d1f8fe >>> --- /dev/null >>> +++ b/arch/mips/mach-pic32/reset.c >>> @@ -0,0 +1,22 @@ >>> +/* >>> + * (c) 2015 Purna Chandra Mandal >>> + * >>> + * SPDX-License-Identifier: GPL-2.0+ >>> + * >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> + >>> +void _machine_restart(void) >>> +{ >>> + writel(0, SYSKEY); >>> + writel(0xAA996655, SYSKEY); >>> + writel(0x556699AA, SYSKEY); >>> + writel(0x1, RSWRST); >> do not use magic values. Please add defines with descriptive names. > > Ack. > >>> + (void) readl(RSWRST); >>> + >>> + while (1) >>> + ; >>> +} >>> > -- - Daniel