[U-Boot] [PATCH v1 06/18] MIPS: Add support for Microchip PIC32MZ[DA] SoC family.
Daniel Schwierzeck
daniel.schwierzeck at gmail.com
Tue Dec 22 15:11:41 CET 2015
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 <purna.mandal at microchip.com>
>>> ---
>>>
>>> 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, <purna.mandal at microchip.com>
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0+
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>> +#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 <common.h>
>>> +#include <dm.h>
>>> +#include <clk.h>
>>> +#include <debug_uart.h>
>>> +#include <linux/compiler.h>
>>> +#include <asm/io.h>
>>> +#include <asm/mipsregs.h>
>>> +#include <asm/arch-pic32/pic32.h>
>>> +#include <asm/arch-pic32/clock.h>
>>>
>>> -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 <purna.mandal at microchip.com>
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0+
>>> + *
>>> +*/
>>> +
>>> +#include <config.h>
>>> +#include <asm/regdef.h>
>>> +#include <asm/mipsregs.h>
>>> +
>>> + .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 <purna.mandal at microchip.com>
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0+
>>> + *
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <asm/io.h>
>>> +#include <asm/arch-pic32/pic32.h>
>>> +
>>> +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
More information about the U-Boot
mailing list