diff mbox

[U-Boot,v1,06/18] MIPS: Add support for Microchip PIC32MZ[DA] SoC family.

Message ID 5672F125.50705@microchip.com
State Superseded
Delegated to: Daniel Schwierzeck
Headers show

Commit Message

Purna Chandra Mandal Dec. 17, 2015, 5:30 p.m. UTC
Signed-off-by: Purna Chandra Mandal <purna.mandal@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

Comments

Daniel Schwierzeck Dec. 19, 2015, 11:55 p.m. UTC | #1
Am 17.12.2015 um 18:30 schrieb Purna Chandra Mandal:
> 
> Signed-off-by: Purna Chandra Mandal <purna.mandal@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@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@0 {
> +            compatible = "mips,mips14kc";
> +        };
> +    };
> +
> +    clock: clk@1f801200 {
> +        compatible = "microchip,pic32mzda_clk";
> +        reg = <0xbf801200 0x1000>;

as mentioned in patch 02/18 the register base address should be a
physical address

> +    };
> +
> +    uart1: serial@1f822000 {
> +        compatible = "microchip,pic32mzda-uart";
> +        reg = <0xbf822000 0x50>;
> +        interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
> +        status = "disabled";
> +    };
> +
> +    uart2: serial@1f822200 {
> +        compatible = "microchip,pic32mzda-uart";
> +        reg = <0xbf822200 0x50>;
> +        interrupts = <145 IRQ_TYPE_LEVEL_HIGH>;
> +        status = "disabled";
> +    };
> +
> +    uart6: serial@1f822a00 {
> +        compatible = "microchip,pic32mzda-uart";
> +        reg = <0xbf822a00 0x50>;
> +        interrupts = <188 IRQ_TYPE_LEVEL_HIGH>;
> +        status = "disabled";
> +    };
> +
> +    evic: interrupt-controller@1f810000 {
> +        compatible = "microchip,pic32mzda-evic";
> +        interrupt-controller;
> +        #interrupt-cells = <2>;
> +        reg = <0xbf810000 0x1000>;
> +    };
> +
> +    pinctrl: pinctrl@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 *

> +
>  #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.

>  
>  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.

> +
> +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 *

> +
> +    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@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)

> +
> +    /*
> +     * 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?

> +
> +    /*
> +     * 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

> +
> +    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@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.

> +    (void) readl(RSWRST);
> +
> +    while (1)
> +        ;
> +}
>
Purna Chandra Mandal Dec. 22, 2015, 1:32 p.m. UTC | #2
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@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@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@0 {
>> +            compatible = "mips,mips14kc";
>> +        };
>> +    };
>> +
>> +    clock: clk@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?

>> +    };
>> +
>> +    uart1: serial@1f822000 {
>> +        compatible = "microchip,pic32mzda-uart";
>> +        reg = <0xbf822000 0x50>;
>> +        interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
>> +        status = "disabled";
>> +    };
>> +
>> +    uart2: serial@1f822200 {
>> +        compatible = "microchip,pic32mzda-uart";
>> +        reg = <0xbf822200 0x50>;
>> +        interrupts = <145 IRQ_TYPE_LEVEL_HIGH>;
>> +        status = "disabled";
>> +    };
>> +
>> +    uart6: serial@1f822a00 {
>> +        compatible = "microchip,pic32mzda-uart";
>> +        reg = <0xbf822a00 0x50>;
>> +        interrupts = <188 IRQ_TYPE_LEVEL_HIGH>;
>> +        status = "disabled";
>> +    };
>> +
>> +    evic: interrupt-controller@1f810000 {
>> +        compatible = "microchip,pic32mzda-evic";
>> +        interrupt-controller;
>> +        #interrupt-cells = <2>;
>> +        reg = <0xbf810000 0x1000>;
>> +    };
>> +
>> +    pinctrl: pinctrl@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.

>> +
>> +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@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@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 Schwierzeck Dec. 22, 2015, 2:11 p.m. UTC | #3
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@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@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@0 {
>>> +            compatible = "mips,mips14kc";
>>> +        };
>>> +    };
>>> +
>>> +    clock: clk@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@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@1f822000 {
>>> +        compatible = "microchip,pic32mzda-uart";
>>> +        reg = <0xbf822000 0x50>;
>>> +        interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
>>> +        status = "disabled";
>>> +    };
>>> +
>>> +    uart2: serial@1f822200 {
>>> +        compatible = "microchip,pic32mzda-uart";
>>> +        reg = <0xbf822200 0x50>;
>>> +        interrupts = <145 IRQ_TYPE_LEVEL_HIGH>;
>>> +        status = "disabled";
>>> +    };
>>> +
>>> +    uart6: serial@1f822a00 {
>>> +        compatible = "microchip,pic32mzda-uart";
>>> +        reg = <0xbf822a00 0x50>;
>>> +        interrupts = <188 IRQ_TYPE_LEVEL_HIGH>;
>>> +        status = "disabled";
>>> +    };
>>> +
>>> +    evic: interrupt-controller@1f810000 {
>>> +        compatible = "microchip,pic32mzda-evic";
>>> +        interrupt-controller;
>>> +        #interrupt-cells = <2>;
>>> +        reg = <0xbf810000 0x1000>;
>>> +    };
>>> +
>>> +    pinctrl: pinctrl@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@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@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)
>>> +        ;
>>> +}
>>>
>
diff mbox

Patch

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@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@0 {
+            compatible = "mips,mips14kc";
+        };
+    };
+
+    clock: clk@1f801200 {
+        compatible = "microchip,pic32mzda_clk";
+        reg = <0xbf801200 0x1000>;
+    };
+
+    uart1: serial@1f822000 {
+        compatible = "microchip,pic32mzda-uart";
+        reg = <0xbf822000 0x50>;
+        interrupts = <112 IRQ_TYPE_LEVEL_HIGH>;
+        status = "disabled";
+    };
+
+    uart2: serial@1f822200 {
+        compatible = "microchip,pic32mzda-uart";
+        reg = <0xbf822200 0x50>;
+        interrupts = <145 IRQ_TYPE_LEVEL_HIGH>;
+        status = "disabled";
+    };
+
+    uart6: serial@1f822a00 {
+        compatible = "microchip,pic32mzda-uart";
+        reg = <0xbf822a00 0x50>;
+        interrupts = <188 IRQ_TYPE_LEVEL_HIGH>;
+        status = "disabled";
+    };
+
+    evic: interrupt-controller@1f810000 {
+        compatible = "microchip,pic32mzda-evic";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0xbf810000 0x1000>;
+    };
+
+    pinctrl: pinctrl@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);
+
 #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
 
 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;
 }
+
+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;
+
+    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@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:
+
+    /*
+     * Establish Status Register
+     * (set BEV, clear ERL, clear EXL, clear IE)
+     */
+    li    t1, 0x00400000
+    mtc0    t1, CP0_STATUS
+
+    /*
+     * 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
+
+    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@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);
+    (void) readl(RSWRST);
+
+    while (1)
+        ;
+}