1 /* 2 * Copyright (C) 2015 3 * Purna Chandra Mandal <purna.mandal@microchip.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 * 7 */ 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <mach/pic32.h> 12 #include <mach/ddr.h> 13 #include <dt-bindings/clock/microchip,clock.h> 14 15 /* Flash prefetch */ 16 #define PRECON 0x00 17 18 /* Flash ECCCON */ 19 #define ECC_MASK 0x03 20 #define ECC_SHIFT 4 21 22 #define CLK_MHZ(x) ((x) / 1000000) 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 static ulong rate(int id) 27 { 28 int ret; 29 struct udevice *dev; 30 struct clk clk; 31 ulong rate; 32 33 ret = uclass_get_device(UCLASS_CLK, 0, &dev); 34 if (ret) { 35 printf("clk-uclass not found\n"); 36 return 0; 37 } 38 39 clk.id = id; 40 ret = clk_request(dev, &clk); 41 if (ret < 0) 42 return ret; 43 44 rate = clk_get_rate(&clk); 45 46 clk_free(&clk); 47 48 return rate; 49 } 50 51 static ulong clk_get_cpu_rate(void) 52 { 53 return rate(PB7CLK); 54 } 55 56 /* initialize prefetch module related to cpu_clk */ 57 static void prefetch_init(void) 58 { 59 struct pic32_reg_atomic *regs; 60 const void __iomem *base; 61 int v, nr_waits; 62 ulong rate; 63 64 /* cpu frequency in MHZ */ 65 rate = clk_get_cpu_rate() / 1000000; 66 67 /* get flash ECC type */ 68 base = pic32_get_syscfg_base(); 69 v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK; 70 71 if (v < 2) { 72 if (rate < 66) 73 nr_waits = 0; 74 else if (rate < 133) 75 nr_waits = 1; 76 else 77 nr_waits = 2; 78 } else { 79 if (rate <= 83) 80 nr_waits = 0; 81 else if (rate <= 166) 82 nr_waits = 1; 83 else 84 nr_waits = 2; 85 } 86 87 regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs)); 88 writel(nr_waits, ®s->raw); 89 90 /* Enable prefetch for all */ 91 writel(0x30, ®s->set); 92 iounmap(regs); 93 } 94 95 /* arch specific CPU init after DM */ 96 int arch_cpu_init_dm(void) 97 { 98 /* flash prefetch */ 99 prefetch_init(); 100 return 0; 101 } 102 103 /* Un-gate DDR2 modules (gated by default) */ 104 static void ddr2_pmd_ungate(void) 105 { 106 void __iomem *regs; 107 108 regs = pic32_get_syscfg_base(); 109 writel(0, regs + PMD7); 110 } 111 112 /* initialize the DDR2 Controller and DDR2 PHY */ 113 int dram_init(void) 114 { 115 ddr2_pmd_ungate(); 116 ddr2_phy_init(); 117 ddr2_ctrl_init(); 118 gd->ram_size = ddr2_calculate_size(); 119 120 return 0; 121 } 122 123 int misc_init_r(void) 124 { 125 set_io_port_base(0); 126 return 0; 127 } 128 129 #ifdef CONFIG_DISPLAY_BOARDINFO 130 const char *get_core_name(void) 131 { 132 u32 proc_id; 133 const char *str; 134 135 proc_id = read_c0_prid(); 136 switch (proc_id) { 137 case 0x19e28: 138 str = "PIC32MZ[DA]"; 139 break; 140 default: 141 str = "UNKNOWN"; 142 } 143 144 return str; 145 } 146 #endif 147 #ifdef CONFIG_CMD_CLK 148 149 int soc_clk_dump(void) 150 { 151 int i; 152 153 printf("PLL Speed: %lu MHz\n", 154 CLK_MHZ(rate(PLLCLK))); 155 156 printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); 157 158 printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); 159 160 for (i = PB1CLK; i <= PB7CLK; i++) 161 printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, 162 CLK_MHZ(rate(i))); 163 164 for (i = REF1CLK; i <= REF5CLK; i++) 165 printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, 166 CLK_MHZ(rate(i))); 167 return 0; 168 } 169 #endif 170