132c1a6eeSPurna Chandra Mandal /* 232c1a6eeSPurna Chandra Mandal * Copyright (C) 2015 332c1a6eeSPurna Chandra Mandal * Purna Chandra Mandal <purna.mandal@microchip.com> 432c1a6eeSPurna Chandra Mandal * 532c1a6eeSPurna Chandra Mandal * SPDX-License-Identifier: GPL-2.0+ 632c1a6eeSPurna Chandra Mandal * 732c1a6eeSPurna Chandra Mandal */ 832c1a6eeSPurna Chandra Mandal #include <common.h> 9be961fa1SPurna Chandra Mandal #include <clk.h> 10be961fa1SPurna Chandra Mandal #include <dm.h> 11be961fa1SPurna Chandra Mandal #include <mach/pic32.h> 12be961fa1SPurna Chandra Mandal #include <mach/ddr.h> 13be961fa1SPurna Chandra Mandal #include <dt-bindings/clock/microchip,clock.h> 1432c1a6eeSPurna Chandra Mandal 15be961fa1SPurna Chandra Mandal /* Flash prefetch */ 16be961fa1SPurna Chandra Mandal #define PRECON 0x00 17be961fa1SPurna Chandra Mandal 18be961fa1SPurna Chandra Mandal /* Flash ECCCON */ 19be961fa1SPurna Chandra Mandal #define ECC_MASK 0x03 20be961fa1SPurna Chandra Mandal #define ECC_SHIFT 4 21be961fa1SPurna Chandra Mandal 22be961fa1SPurna Chandra Mandal #define CLK_MHZ(x) ((x) / 1000000) 23be961fa1SPurna Chandra Mandal 24be961fa1SPurna Chandra Mandal DECLARE_GLOBAL_DATA_PTR; 25be961fa1SPurna Chandra Mandal 26135aa950SStephen Warren static ulong rate(int id) 2732c1a6eeSPurna Chandra Mandal { 28be961fa1SPurna Chandra Mandal int ret; 29be961fa1SPurna Chandra Mandal struct udevice *dev; 30135aa950SStephen Warren struct clk clk; 31135aa950SStephen Warren ulong rate; 32be961fa1SPurna Chandra Mandal 33be961fa1SPurna Chandra Mandal ret = uclass_get_device(UCLASS_CLK, 0, &dev); 34be961fa1SPurna Chandra Mandal if (ret) { 35135aa950SStephen Warren printf("clk-uclass not found\n"); 3632c1a6eeSPurna Chandra Mandal return 0; 3732c1a6eeSPurna Chandra Mandal } 38be961fa1SPurna Chandra Mandal 39135aa950SStephen Warren clk.id = id; 40135aa950SStephen Warren ret = clk_request(dev, &clk); 41135aa950SStephen Warren if (ret < 0) 42135aa950SStephen Warren return ret; 43135aa950SStephen Warren 44135aa950SStephen Warren rate = clk_get_rate(&clk); 45135aa950SStephen Warren 46135aa950SStephen Warren clk_free(&clk); 47135aa950SStephen Warren 48135aa950SStephen Warren return rate; 49135aa950SStephen Warren } 50135aa950SStephen Warren 51135aa950SStephen Warren static ulong clk_get_cpu_rate(void) 52135aa950SStephen Warren { 53135aa950SStephen Warren return rate(PB7CLK); 54be961fa1SPurna Chandra Mandal } 55be961fa1SPurna Chandra Mandal 56be961fa1SPurna Chandra Mandal /* initialize prefetch module related to cpu_clk */ 57be961fa1SPurna Chandra Mandal static void prefetch_init(void) 58be961fa1SPurna Chandra Mandal { 59be961fa1SPurna Chandra Mandal struct pic32_reg_atomic *regs; 60be961fa1SPurna Chandra Mandal const void __iomem *base; 61be961fa1SPurna Chandra Mandal int v, nr_waits; 62be961fa1SPurna Chandra Mandal ulong rate; 63be961fa1SPurna Chandra Mandal 64be961fa1SPurna Chandra Mandal /* cpu frequency in MHZ */ 65be961fa1SPurna Chandra Mandal rate = clk_get_cpu_rate() / 1000000; 66be961fa1SPurna Chandra Mandal 67be961fa1SPurna Chandra Mandal /* get flash ECC type */ 68be961fa1SPurna Chandra Mandal base = pic32_get_syscfg_base(); 69be961fa1SPurna Chandra Mandal v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK; 70be961fa1SPurna Chandra Mandal 71be961fa1SPurna Chandra Mandal if (v < 2) { 72be961fa1SPurna Chandra Mandal if (rate < 66) 73be961fa1SPurna Chandra Mandal nr_waits = 0; 74be961fa1SPurna Chandra Mandal else if (rate < 133) 75be961fa1SPurna Chandra Mandal nr_waits = 1; 76be961fa1SPurna Chandra Mandal else 77be961fa1SPurna Chandra Mandal nr_waits = 2; 78be961fa1SPurna Chandra Mandal } else { 79be961fa1SPurna Chandra Mandal if (rate <= 83) 80be961fa1SPurna Chandra Mandal nr_waits = 0; 81be961fa1SPurna Chandra Mandal else if (rate <= 166) 82be961fa1SPurna Chandra Mandal nr_waits = 1; 83be961fa1SPurna Chandra Mandal else 84be961fa1SPurna Chandra Mandal nr_waits = 2; 85be961fa1SPurna Chandra Mandal } 86be961fa1SPurna Chandra Mandal 87be961fa1SPurna Chandra Mandal regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs)); 88be961fa1SPurna Chandra Mandal writel(nr_waits, ®s->raw); 89be961fa1SPurna Chandra Mandal 90be961fa1SPurna Chandra Mandal /* Enable prefetch for all */ 91be961fa1SPurna Chandra Mandal writel(0x30, ®s->set); 92be961fa1SPurna Chandra Mandal iounmap(regs); 93be961fa1SPurna Chandra Mandal } 94be961fa1SPurna Chandra Mandal 95be961fa1SPurna Chandra Mandal /* arch specific CPU init after DM */ 96be961fa1SPurna Chandra Mandal int arch_cpu_init_dm(void) 97be961fa1SPurna Chandra Mandal { 98be961fa1SPurna Chandra Mandal /* flash prefetch */ 99be961fa1SPurna Chandra Mandal prefetch_init(); 100be961fa1SPurna Chandra Mandal return 0; 101be961fa1SPurna Chandra Mandal } 102be961fa1SPurna Chandra Mandal 103be961fa1SPurna Chandra Mandal /* Un-gate DDR2 modules (gated by default) */ 104be961fa1SPurna Chandra Mandal static void ddr2_pmd_ungate(void) 105be961fa1SPurna Chandra Mandal { 106be961fa1SPurna Chandra Mandal void __iomem *regs; 107be961fa1SPurna Chandra Mandal 108be961fa1SPurna Chandra Mandal regs = pic32_get_syscfg_base(); 109be961fa1SPurna Chandra Mandal writel(0, regs + PMD7); 110be961fa1SPurna Chandra Mandal } 111be961fa1SPurna Chandra Mandal 112be961fa1SPurna Chandra Mandal /* initialize the DDR2 Controller and DDR2 PHY */ 113*088454cdSSimon Glass int initdram(void) 114be961fa1SPurna Chandra Mandal { 115be961fa1SPurna Chandra Mandal ddr2_pmd_ungate(); 116be961fa1SPurna Chandra Mandal ddr2_phy_init(); 117be961fa1SPurna Chandra Mandal ddr2_ctrl_init(); 118*088454cdSSimon Glass gd->ram_size = ddr2_calculate_size(); 119*088454cdSSimon Glass 120*088454cdSSimon Glass return 0; 121be961fa1SPurna Chandra Mandal } 122be961fa1SPurna Chandra Mandal 123be961fa1SPurna Chandra Mandal int misc_init_r(void) 124be961fa1SPurna Chandra Mandal { 125be961fa1SPurna Chandra Mandal set_io_port_base(0); 126be961fa1SPurna Chandra Mandal return 0; 127be961fa1SPurna Chandra Mandal } 128be961fa1SPurna Chandra Mandal 129be961fa1SPurna Chandra Mandal #ifdef CONFIG_DISPLAY_BOARDINFO 130be961fa1SPurna Chandra Mandal const char *get_core_name(void) 131be961fa1SPurna Chandra Mandal { 132be961fa1SPurna Chandra Mandal u32 proc_id; 133be961fa1SPurna Chandra Mandal const char *str; 134be961fa1SPurna Chandra Mandal 135be961fa1SPurna Chandra Mandal proc_id = read_c0_prid(); 136be961fa1SPurna Chandra Mandal switch (proc_id) { 137be961fa1SPurna Chandra Mandal case 0x19e28: 138be961fa1SPurna Chandra Mandal str = "PIC32MZ[DA]"; 139be961fa1SPurna Chandra Mandal break; 140be961fa1SPurna Chandra Mandal default: 141be961fa1SPurna Chandra Mandal str = "UNKNOWN"; 142be961fa1SPurna Chandra Mandal } 143be961fa1SPurna Chandra Mandal 144be961fa1SPurna Chandra Mandal return str; 145be961fa1SPurna Chandra Mandal } 146be961fa1SPurna Chandra Mandal #endif 147be961fa1SPurna Chandra Mandal #ifdef CONFIG_CMD_CLK 148135aa950SStephen Warren 149be961fa1SPurna Chandra Mandal int soc_clk_dump(void) 150be961fa1SPurna Chandra Mandal { 151135aa950SStephen Warren int i; 152be961fa1SPurna Chandra Mandal 153be961fa1SPurna Chandra Mandal printf("PLL Speed: %lu MHz\n", 154135aa950SStephen Warren CLK_MHZ(rate(PLLCLK))); 155135aa950SStephen Warren 156135aa950SStephen Warren printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); 157135aa950SStephen Warren 158135aa950SStephen Warren printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); 159be961fa1SPurna Chandra Mandal 160be961fa1SPurna Chandra Mandal for (i = PB1CLK; i <= PB7CLK; i++) 161be961fa1SPurna Chandra Mandal printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, 162135aa950SStephen Warren CLK_MHZ(rate(i))); 163be961fa1SPurna Chandra Mandal 164be961fa1SPurna Chandra Mandal for (i = REF1CLK; i <= REF5CLK; i++) 165be961fa1SPurna Chandra Mandal printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, 166135aa950SStephen Warren CLK_MHZ(rate(i))); 167be961fa1SPurna Chandra Mandal return 0; 168be961fa1SPurna Chandra Mandal } 169be961fa1SPurna Chandra Mandal #endif 170