1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * board.c
4  *
5  * Board functions for Phytec phyCORE-AM335x R2 (PCL060 / PCM060) based boards
6  *
7  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
8  * Copyright (C) 2013 Lars Poeschel, Lemonage Software GmbH
9  * Copyright (C) 2015 Wadim Egorov, PHYTEC Messtechnik GmbH
10  * Copyright (C) 2019 DENX Software Engineering GmbH
11  */
12 
13 #include <common.h>
14 #include <init.h>
15 #include <spl.h>
16 #include <asm/arch/cpu.h>
17 #include <asm/arch/ddr_defs.h>
18 #include <asm/arch/clock.h>
19 #include <asm/arch/sys_proto.h>
20 #include <asm/global_data.h>
21 #include <power/tps65910.h>
22 #include <jffs2/load_kernel.h>
23 #include <mtd_node.h>
24 #include <fdt_support.h>
25 #include "board.h"
26 
27 DECLARE_GLOBAL_DATA_PTR;
28 
29 #ifdef CONFIG_SPL_BUILD
30 
31 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
32 
33 /* DDR RAM defines */
34 #if defined(CONFIG_TARGET_PCM051)
35 #define DDR_CLK_MHZ		303 /* DDR_DPLL_MULT value */
36 #else
37 #define DDR_CLK_MHZ		400 /* DDR_DPLL_MULT value */
38 #endif
39 
40 #define OSC	(V_OSCK / 1000000)
41 const struct dpll_params dpll_ddr = {
42 		DDR_CLK_MHZ, OSC - 1, 1, -1, -1, -1, -1};
43 
get_dpll_ddr_params(void)44 const struct dpll_params *get_dpll_ddr_params(void)
45 {
46 	return &dpll_ddr;
47 }
48 
49 const struct ctrl_ioregs ioregs = {
50 	.cm0ioctl		= 0x18B,
51 	.cm1ioctl		= 0x18B,
52 	.cm2ioctl		= 0x18B,
53 	.dt0ioctl		= 0x18B,
54 	.dt1ioctl		= 0x18B,
55 };
56 
57 static const struct cmd_control ddr3_cmd_ctrl_data = {
58 	.cmd0csratio = 0x80,
59 	.cmd0iclkout = 0x0,
60 
61 	.cmd1csratio = 0x80,
62 	.cmd1iclkout = 0x0,
63 
64 	.cmd2csratio = 0x80,
65 	.cmd2iclkout = 0x0,
66 };
67 
68 enum {
69 	PHYCORE_R2_MT41K128M16JT_256MB,
70 	PHYCORE_R2_MT41K256M16TW107IT_512MB,
71 	PHYCORE_R2_MT41K512M16HA125IT_1024MB,
72 	PHYCORE_R13_MT41K256M16HA125E_256MB,
73 };
74 
75 struct am335x_sdram_timings {
76 	struct emif_regs ddr3_emif_reg_data;
77 	struct ddr_data ddr3_data;
78 };
79 
80 static struct am335x_sdram_timings physom_timings[] = {
81 	[PHYCORE_R2_MT41K128M16JT_256MB] = {
82 		.ddr3_emif_reg_data = {
83 			.sdram_config = 0x61C052B2,
84 			.ref_ctrl = 0x00000C30,
85 			.sdram_tim1 = 0x0AAAD4DB,
86 			.sdram_tim2 = 0x26437FDA,
87 			.sdram_tim3 = 0x501F83FF,
88 			.zq_config = 0x50074BE4,
89 			.emif_ddr_phy_ctlr_1 = 0x7,
90 			.ocp_config = 0x003d3d3d,
91 		},
92 		.ddr3_data = {
93 			.datardsratio0 = 0x36,
94 			.datawdsratio0 = 0x38,
95 			.datafwsratio0 = 0x99,
96 			.datawrsratio0 = 0x73,
97 		},
98 	},
99 	[PHYCORE_R2_MT41K256M16TW107IT_512MB] = {
100 		.ddr3_emif_reg_data = {
101 			.sdram_config = 0x61C05332,
102 			.ref_ctrl = 0x00000C30,
103 			.sdram_tim1 = 0x0AAAD4DB,
104 			.sdram_tim2 = 0x266B7FDA,
105 			.sdram_tim3 = 0x501F867F,
106 			.zq_config = 0x50074BE4,
107 			.emif_ddr_phy_ctlr_1 = 0x7,
108 			.ocp_config = 0x003d3d3d,
109 		},
110 		.ddr3_data = {
111 			.datardsratio0 = 0x37,
112 			.datawdsratio0 = 0x38,
113 			.datafwsratio0 = 0x92,
114 			.datawrsratio0 = 0x72,
115 		},
116 	},
117 	[PHYCORE_R2_MT41K512M16HA125IT_1024MB] = {
118 		.ddr3_emif_reg_data = {
119 			.sdram_config = 0x61C053B2,
120 			.ref_ctrl = 0x00000C30,
121 			.sdram_tim1 = 0x0AAAD4DB,
122 			.sdram_tim2 = 0x268F7FDA,
123 			.sdram_tim3 = 0x501F88BF,
124 			.zq_config = 0x50074BE4,
125 			.emif_ddr_phy_ctlr_1 = 0x7,
126 			.ocp_config = 0x003d3d3d,
127 		},
128 		.ddr3_data = {
129 			.datardsratio0 = 0x38,
130 			.datawdsratio0 = 0x4d,
131 			.datafwsratio0 = 0x9d,
132 			.datawrsratio0 = 0x82,
133 		},
134 	},
135 	[PHYCORE_R13_MT41K256M16HA125E_256MB] = {
136 		.ddr3_emif_reg_data = {
137 			.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
138 			.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
139 			.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
140 			.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
141 			.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
142 			.zq_config = MT41K256M16HA125E_ZQ_CFG,
143 			.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY | PHY_EN_DYN_PWRDN,
144 		},
145 		.ddr3_data = {
146 			.datardsratio0 = MT41K256M16HA125E_RD_DQS,
147 			.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
148 			.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
149 			.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
150 		},
151 	},
152 };
153 
sdram_init(void)154 void sdram_init(void)
155 {
156 #if defined(CONFIG_TARGET_PCM051)
157 	int ram_type_index = PHYCORE_R13_MT41K256M16HA125E_256MB;
158 #else
159 	/* Configure memory to maximum supported size for detection */
160 	int ram_type_index = PHYCORE_R2_MT41K512M16HA125IT_1024MB;
161 
162 	config_ddr(DDR_CLK_MHZ, &ioregs,
163 		   &physom_timings[ram_type_index].ddr3_data,
164 		   &ddr3_cmd_ctrl_data,
165 		   &physom_timings[ram_type_index].ddr3_emif_reg_data,
166 		   0);
167 
168 	/* Detect memory physically present */
169 	gd->ram_size = get_ram_size((void *)CFG_SYS_SDRAM_BASE,
170 				    CFG_MAX_RAM_BANK_SIZE);
171 
172 	/* Reconfigure memory for actual detected size */
173 	switch (gd->ram_size) {
174 	case SZ_1G:
175 		ram_type_index = PHYCORE_R2_MT41K512M16HA125IT_1024MB;
176 		break;
177 	case SZ_512M:
178 		ram_type_index = PHYCORE_R2_MT41K256M16TW107IT_512MB;
179 		break;
180 	case SZ_256M:
181 	default:
182 		ram_type_index = PHYCORE_R2_MT41K128M16JT_256MB;
183 		break;
184 	}
185 #endif
186 	config_ddr(DDR_CLK_MHZ, &ioregs,
187 		   &physom_timings[ram_type_index].ddr3_data,
188 		   &ddr3_cmd_ctrl_data,
189 		   &physom_timings[ram_type_index].ddr3_emif_reg_data,
190 		   0);
191 }
192 
get_dpll_mpu_params(void)193 const struct dpll_params *get_dpll_mpu_params(void)
194 {
195 	int ind = get_sys_clk_index();
196 	int freq = am335x_get_efuse_mpu_max_freq(cdev);
197 
198 	switch (freq) {
199 	case MPUPLL_M_1000:
200 		return &dpll_mpu_opp[ind][5];
201 	case MPUPLL_M_800:
202 		return &dpll_mpu_opp[ind][4];
203 	case MPUPLL_M_720:
204 		return &dpll_mpu_opp[ind][3];
205 	case MPUPLL_M_600:
206 		return &dpll_mpu_opp[ind][2];
207 	case MPUPLL_M_500:
208 		return &dpll_mpu_opp100;
209 	case MPUPLL_M_300:
210 		return &dpll_mpu_opp[ind][0];
211 	}
212 
213 	return &dpll_mpu_opp[ind][0];
214 }
215 
scale_vcores_generic(int freq)216 static void scale_vcores_generic(int freq)
217 {
218 	int sil_rev, mpu_vdd;
219 
220 	/*
221 	 * We use a TPS65910 PMIC. For all  MPU frequencies we support we use a
222 	 * CORE voltage of 1.10V. For MPU voltage we need to switch based on
223 	 * the frequency we are running at.
224 	 */
225 	if (power_tps65910_init(0))
226 		return;
227 
228 	/*
229 	 * Depending on MPU clock and PG we will need a different
230 	 * VDD to drive at that speed.
231 	 */
232 	sil_rev = readl(&cdev->deviceid) >> 28;
233 	mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev, freq);
234 
235 	/* Tell the TPS65910 to use i2c */
236 	tps65910_set_i2c_control();
237 
238 	/* First update MPU voltage. */
239 	if (tps65910_voltage_update(MPU, mpu_vdd))
240 		return;
241 
242 	/* Second, update the CORE voltage. */
243 	if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_0))
244 		return;
245 }
246 
scale_vcores(void)247 void scale_vcores(void)
248 {
249 	int freq;
250 
251 	freq = am335x_get_efuse_mpu_max_freq(cdev);
252 	scale_vcores_generic(freq);
253 }
254 
set_uart_mux_conf(void)255 void set_uart_mux_conf(void)
256 {
257 	enable_uart0_pin_mux();
258 }
259 
set_mux_conf_regs(void)260 void set_mux_conf_regs(void)
261 {
262 	enable_i2c0_pin_mux();
263 	enable_board_pin_mux();
264 }
265 #endif
266 
267 /*
268  * Basic board specific setup.  Pinmux has been handled already.
269  */
board_init(void)270 int board_init(void)
271 {
272 	gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
273 	return 0;
274 }
275 
276 #ifdef CONFIG_OF_BOARD_SETUP
ft_board_setup(void * blob,struct bd_info * bd)277 int ft_board_setup(void *blob, struct bd_info *bd)
278 {
279 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
280 	static const struct node_info nodes[] = {
281 		{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
282 	};
283 
284 	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
285 #endif
286 	return 0;
287 }
288 #endif
289