2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Imagination Technologies
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
19 #include <soc/clocks.h>
23 #define PADS_FUNCTION_SELECT0_ADDR (0xB8101C00 + 0xC0)
25 #define GPIO_BIT_EN_ADDR(bank) (0xB8101C00 + 0x200 + (0x24 * (bank)))
26 #define PAD_DRIVE_STRENGTH_ADDR(bank) (0xB8101C00 + 0x120 + (0x4 * (bank)))
27 #define MAX_NO_MFIOS 89
28 #define PAD_DRIVE_STRENGTH_LENGTH 2
29 #define PAD_DRIVE_STRENGTH_MASK 0x3
32 DRIVE_STRENGTH_2mA
= 0,
33 DRIVE_STRENGTH_4mA
= 1,
34 DRIVE_STRENGTH_8mA
= 2,
35 DRIVE_STRENGTH_12mA
= 3
38 /* MFIO definitions for UART1 */
39 #define UART1_RXD_MFIO 59
40 #define UART1_TXD_MFIO 60
42 /* MFIO definitions for SPIM */
43 #define SPIM1_D0_TXD_MFIO 5
44 #define SPIM1_D1_RXD_MFIO 4
45 #define SPIM1_MCLK_MFIO 3
46 #define SPIM1_D2_MFIO 6
47 #define SPIM1_D3_MFIO 7
48 #define SPIM1_CS0_MFIO 0
50 /* MFIO definitions for I2C */
51 #define I2C_DATA_MFIO(i) (28 + (2*(i)))
52 #define I2C_CLK_MFIO(i) (29 + (2*(i)))
53 #define I2C_DATA_FUNCTION_OFFSET(i) (20 + (2*(i)))
54 #define I2C_CLK_FUNCTION_OFFSET(i) (21 + (2*(i)))
55 #define I2C_DATA_FUNCTION_MASK 0x1
56 #define I2C_CLK_FUNCTION_MASK 0x1
58 static void pad_drive_strength(u32 pad
, drive_strength strength
)
60 u32 reg
, drive_strength_shift
;
62 assert(pad
<= MAX_NO_MFIOS
);
63 assert(!(strength
& ~(PAD_DRIVE_STRENGTH_MASK
)));
65 /* Set drive strength value */
66 drive_strength_shift
= (pad
% 16) * PAD_DRIVE_STRENGTH_LENGTH
;
67 reg
= read32(PAD_DRIVE_STRENGTH_ADDR(pad
/ 16));
68 reg
&= ~(PAD_DRIVE_STRENGTH_MASK
<< drive_strength_shift
);
69 reg
|= strength
<< drive_strength_shift
;
70 write32(PAD_DRIVE_STRENGTH_ADDR(pad
/ 16), reg
);
73 static void uart1_mfio_setup(void)
78 * Disable GPIO for UART1 MFIOs
79 * All UART MFIOs have MFIO/16 = 3, therefore we use GPIO pad 3
80 * This is the only function (0) of these MFIOs and therfore there
81 * is no need to set up a function number in the corresponding
82 * function select register.
84 reg
= read32(GPIO_BIT_EN_ADDR(3));
85 mfio_mask
= 1 << (UART1_RXD_MFIO
% 16);
86 mfio_mask
|= 1 << (UART1_TXD_MFIO
% 16);
87 /* Clear relevant bits */
90 * Set corresponding bits in the upper half word
91 * in order to be able to modify the chosen pins
93 reg
|= mfio_mask
<< 16;
94 write32(GPIO_BIT_EN_ADDR(3), reg
);
97 static void spim1_mfio_setup(void)
101 * Disable GPIO for SPIM1 MFIOs
102 * All SPFI1 MFIOs have MFIO/16 = 0, therefore we use GPIO pad 0
103 * This is the only function (0) of these MFIOs and therfore there
104 * is no need to set up a function number in the corresponding
105 * function select register.
107 reg
= read32(GPIO_BIT_EN_ADDR(0));
109 /* Disable GPIO for SPIM1 MFIOs */
110 mfio_mask
= 1 << (SPIM1_D0_TXD_MFIO
% 16);
111 mfio_mask
|= 1 << (SPIM1_D1_RXD_MFIO
% 16);
112 mfio_mask
|= 1 << (SPIM1_MCLK_MFIO
% 16);
113 mfio_mask
|= 1 << (SPIM1_D2_MFIO
% 16);
114 mfio_mask
|= 1 << (SPIM1_D3_MFIO
% 16);
115 mfio_mask
|= 1 << (SPIM1_CS0_MFIO
% 16);
117 /* Clear relevant bits */
120 * Set corresponding bits in the upper half word
121 * in order to be able to modify the chosen pins
123 reg
|= mfio_mask
<< 16;
124 write32(GPIO_BIT_EN_ADDR(0), reg
);
126 /* Set drive strength to maximum for these MFIOs */
127 pad_drive_strength(SPIM1_CS0_MFIO
, DRIVE_STRENGTH_12mA
);
128 pad_drive_strength(SPIM1_D1_RXD_MFIO
, DRIVE_STRENGTH_12mA
);
129 pad_drive_strength(SPIM1_D0_TXD_MFIO
, DRIVE_STRENGTH_12mA
);
130 pad_drive_strength(SPIM1_D2_MFIO
, DRIVE_STRENGTH_12mA
);
131 pad_drive_strength(SPIM1_D3_MFIO
, DRIVE_STRENGTH_12mA
);
132 pad_drive_strength(SPIM1_MCLK_MFIO
, DRIVE_STRENGTH_12mA
);
135 static void i2c_mfio_setup(int interface
)
139 assert(interface
< 4);
141 * Disable GPIO for I2C MFIOs
143 reg
= read32(GPIO_BIT_EN_ADDR(I2C_DATA_MFIO(interface
) / 16));
144 mfio_mask
= 1 << (I2C_DATA_MFIO(interface
) % 16);
145 mfio_mask
|= 1 << (I2C_CLK_MFIO(interface
) % 16);
146 /* Clear relevant bits */
149 * Set corresponding bits in the upper half word
150 * in order to be able to modify the chosen pins
152 reg
|= mfio_mask
<< 16;
153 write32(GPIO_BIT_EN_ADDR(I2C_DATA_MFIO(interface
) / 16), reg
);
155 /* for I2C0 and I2C1:
156 * Set bits to 0 (clear) which is the primary function
157 * for these MFIOs; those bits will all be set to 1 by
159 * There is no need to do that for I2C2 and I2C3
163 reg
= read32(PADS_FUNCTION_SELECT0_ADDR
);
164 reg
&= ~(I2C_DATA_FUNCTION_MASK
<<
165 I2C_DATA_FUNCTION_OFFSET(interface
));
166 reg
&= ~(I2C_CLK_FUNCTION_MASK
<<
167 I2C_CLK_FUNCTION_OFFSET(interface
));
168 write32(PADS_FUNCTION_SELECT0_ADDR
, reg
);
171 static void bootblock_mainboard_init(void)
175 /* System PLL divided by 2 -> 400 MHz */
176 /* The same frequency will be the input frequency for the SPFI block */
179 /* MIPS CPU dividers: division by 1 -> 546 MHz
180 * This is set up as we cannot make any assumption about
181 * the values set or not by the boot ROM code */
182 mips_clk_setup(0, 0);
184 /* Setup system PLL at 800 MHz */
185 ret
= sys_pll_setup(2, 1);
186 if (ret
!= CLOCKS_OK
)
188 /* Setup MIPS PLL at 546 MHz */
189 ret
= mips_pll_setup(2, 1, 1, 21);
190 if (ret
!= CLOCKS_OK
)
193 /* Setup SPIM1 MFIOs */
195 /* Setup UART1 clock and MFIOs
196 * System PLL divided by 7 divided by 62 -> 1.8433 Mhz
198 uart1_clk_setup(6, 61);
203 static int init_extra_hardware(void)
205 const struct board_hw
*hardware
;
207 /* Obtain information about current board */
208 hardware
= board_get_hw();
210 printk(BIOS_ERR
, "%s: Invalid hardware information.\n",
216 * System clock divided by 8 -> 50 MHz
218 if (usb_clk_setup(7, 2, 7) != CLOCKS_OK
) {
219 printk(BIOS_ERR
, "%s: Failed to set up USB clock.\n",
224 /* Setup I2C clocks and MFIOs
225 * System PLL divided by 4 divided by 3 -> 33.33 MHz
227 i2c_clk_setup(3, 2, hardware
->i2c_interface
);
228 i2c_mfio_setup(hardware
->i2c_interface
);
230 /* Ethernet clocks setup: ENET as clock source */
232 /* ROM clock setup: system clock divided by 2 -> 200 MHz */
233 /* Hash accelerator is driven from the ROM clock */