[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