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 clk_get_cpu_rate(void) 27 { 28 int ret; 29 struct udevice *dev; 30 31 ret = uclass_get_device(UCLASS_CLK, 0, &dev); 32 if (ret) { 33 panic("uclass-clk: device not found\n"); 34 return 0; 35 } 36 37 return clk_get_rate(dev); 38 } 39 40 /* initialize prefetch module related to cpu_clk */ 41 static void prefetch_init(void) 42 { 43 struct pic32_reg_atomic *regs; 44 const void __iomem *base; 45 int v, nr_waits; 46 ulong rate; 47 48 /* cpu frequency in MHZ */ 49 rate = clk_get_cpu_rate() / 1000000; 50 51 /* get flash ECC type */ 52 base = pic32_get_syscfg_base(); 53 v = (readl(base + CFGCON) >> ECC_SHIFT) & ECC_MASK; 54 55 if (v < 2) { 56 if (rate < 66) 57 nr_waits = 0; 58 else if (rate < 133) 59 nr_waits = 1; 60 else 61 nr_waits = 2; 62 } else { 63 if (rate <= 83) 64 nr_waits = 0; 65 else if (rate <= 166) 66 nr_waits = 1; 67 else 68 nr_waits = 2; 69 } 70 71 regs = ioremap(PREFETCH_BASE + PRECON, sizeof(*regs)); 72 writel(nr_waits, ®s->raw); 73 74 /* Enable prefetch for all */ 75 writel(0x30, ®s->set); 76 iounmap(regs); 77 } 78 79 /* arch specific CPU init after DM */ 80 int arch_cpu_init_dm(void) 81 { 82 /* flash prefetch */ 83 prefetch_init(); 84 return 0; 85 } 86 87 /* Un-gate DDR2 modules (gated by default) */ 88 static void ddr2_pmd_ungate(void) 89 { 90 void __iomem *regs; 91 92 regs = pic32_get_syscfg_base(); 93 writel(0, regs + PMD7); 94 } 95 96 /* initialize the DDR2 Controller and DDR2 PHY */ 97 phys_size_t initdram(int board_type) 98 { 99 ddr2_pmd_ungate(); 100 ddr2_phy_init(); 101 ddr2_ctrl_init(); 102 return ddr2_calculate_size(); 103 } 104 105 int misc_init_r(void) 106 { 107 set_io_port_base(0); 108 return 0; 109 } 110 111 #ifdef CONFIG_DISPLAY_BOARDINFO 112 const char *get_core_name(void) 113 { 114 u32 proc_id; 115 const char *str; 116 117 proc_id = read_c0_prid(); 118 switch (proc_id) { 119 case 0x19e28: 120 str = "PIC32MZ[DA]"; 121 break; 122 default: 123 str = "UNKNOWN"; 124 } 125 126 return str; 127 } 128 #endif 129 #ifdef CONFIG_CMD_CLK 130 int soc_clk_dump(void) 131 { 132 int i, ret; 133 struct udevice *dev; 134 135 ret = uclass_get_device(UCLASS_CLK, 0, &dev); 136 if (ret) { 137 printf("clk-uclass not found\n"); 138 return ret; 139 } 140 141 printf("PLL Speed: %lu MHz\n", 142 CLK_MHZ(clk_get_periph_rate(dev, PLLCLK))); 143 printf("CPU Speed: %lu MHz\n", CLK_MHZ(clk_get_rate(dev))); 144 printf("MPLL Speed: %lu MHz\n", 145 CLK_MHZ(clk_get_periph_rate(dev, MPLL))); 146 147 for (i = PB1CLK; i <= PB7CLK; i++) 148 printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, 149 CLK_MHZ(clk_get_periph_rate(dev, i))); 150 151 for (i = REF1CLK; i <= REF5CLK; i++) 152 printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, 153 CLK_MHZ(clk_get_periph_rate(dev, i))); 154 return 0; 155 } 156 #endif 157