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