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 phys_size_t initdram(int board_type) 114 { 115 ddr2_pmd_ungate(); 116 ddr2_phy_init(); 117 ddr2_ctrl_init(); 118 return ddr2_calculate_size(); 119 } 120 121 int misc_init_r(void) 122 { 123 set_io_port_base(0); 124 return 0; 125 } 126 127 #ifdef CONFIG_DISPLAY_BOARDINFO 128 const char *get_core_name(void) 129 { 130 u32 proc_id; 131 const char *str; 132 133 proc_id = read_c0_prid(); 134 switch (proc_id) { 135 case 0x19e28: 136 str = "PIC32MZ[DA]"; 137 break; 138 default: 139 str = "UNKNOWN"; 140 } 141 142 return str; 143 } 144 #endif 145 #ifdef CONFIG_CMD_CLK 146 147 int soc_clk_dump(void) 148 { 149 int i; 150 151 printf("PLL Speed: %lu MHz\n", 152 CLK_MHZ(rate(PLLCLK))); 153 154 printf("CPU Speed: %lu MHz\n", CLK_MHZ(rate(PB7CLK))); 155 156 printf("MPLL Speed: %lu MHz\n", CLK_MHZ(rate(MPLL))); 157 158 for (i = PB1CLK; i <= PB7CLK; i++) 159 printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, 160 CLK_MHZ(rate(i))); 161 162 for (i = REF1CLK; i <= REF5CLK; i++) 163 printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, 164 CLK_MHZ(rate(i))); 165 return 0; 166 } 167 #endif 168