1 /* 2 * Copyright (c) 2013 Xilinx Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <asm/io.h> 9 #include <malloc.h> 10 #include <asm/arch/hardware.h> 11 #include <asm/arch/sys_proto.h> 12 #include <asm/arch/clk.h> 13 14 #define SLCR_LOCK_MAGIC 0x767B 15 #define SLCR_UNLOCK_MAGIC 0xDF0D 16 17 #define SLCR_NAND_L2_SEL 0x10 18 #define SLCR_NAND_L2_SEL_MASK 0x1F 19 20 #define SLCR_USB_L1_SEL 0x04 21 22 #define SLCR_IDCODE_MASK 0x1F000 23 #define SLCR_IDCODE_SHIFT 12 24 25 /* 26 * zynq_slcr_mio_get_status - Get the status of MIO peripheral. 27 * 28 * @peri_name: Name of the peripheral for checking MIO status 29 * @get_pins: Pointer to array of get pin for this peripheral 30 * @num_pins: Number of pins for this peripheral 31 * @mask: Mask value 32 * @check_val: Required check value to get the status of periph 33 */ 34 struct zynq_slcr_mio_get_status { 35 const char *peri_name; 36 const int *get_pins; 37 int num_pins; 38 u32 mask; 39 u32 check_val; 40 }; 41 42 static const int nand8_pins[] = { 43 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 44 }; 45 46 static const int nand16_pins[] = { 47 16, 17, 18, 19, 20, 21, 22, 23 48 }; 49 50 static const int usb0_pins[] = { 51 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 52 }; 53 54 static const int usb1_pins[] = { 55 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 56 }; 57 58 static const struct zynq_slcr_mio_get_status mio_periphs[] = { 59 { 60 "nand8", 61 nand8_pins, 62 ARRAY_SIZE(nand8_pins), 63 SLCR_NAND_L2_SEL_MASK, 64 SLCR_NAND_L2_SEL, 65 }, 66 { 67 "nand16", 68 nand16_pins, 69 ARRAY_SIZE(nand16_pins), 70 SLCR_NAND_L2_SEL_MASK, 71 SLCR_NAND_L2_SEL, 72 }, 73 { 74 "usb0", 75 usb0_pins, 76 ARRAY_SIZE(usb0_pins), 77 SLCR_USB_L1_SEL, 78 SLCR_USB_L1_SEL, 79 }, 80 { 81 "usb1", 82 usb1_pins, 83 ARRAY_SIZE(usb1_pins), 84 SLCR_USB_L1_SEL, 85 SLCR_USB_L1_SEL, 86 }, 87 }; 88 89 static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ 90 91 void zynq_slcr_lock(void) 92 { 93 if (!slcr_lock) { 94 writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); 95 slcr_lock = 1; 96 } 97 } 98 99 void zynq_slcr_unlock(void) 100 { 101 if (slcr_lock) { 102 writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); 103 slcr_lock = 0; 104 } 105 } 106 107 /* Reset the entire system */ 108 void zynq_slcr_cpu_reset(void) 109 { 110 /* 111 * Unlock the SLCR then reset the system. 112 * Note that this seems to require raw i/o 113 * functions or there's a lockup? 114 */ 115 zynq_slcr_unlock(); 116 117 /* 118 * Clear 0x0F000000 bits of reboot status register to workaround 119 * the FSBL not loading the bitstream after soft-reboot 120 * This is a temporary solution until we know more. 121 */ 122 clrbits_le32(&slcr_base->reboot_status, 0xF000000); 123 124 writel(1, &slcr_base->pss_rst_ctrl); 125 } 126 127 /* Setup clk for network */ 128 void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate) 129 { 130 int ret; 131 132 zynq_slcr_unlock(); 133 134 if (gem_id > 1) { 135 printf("Non existing GEM id %d\n", gem_id); 136 goto out; 137 } 138 139 ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate); 140 if (ret) 141 goto out; 142 143 if (gem_id) { 144 /* Configure GEM_RCLK_CTRL */ 145 writel(1, &slcr_base->gem1_rclk_ctrl); 146 } else { 147 /* Configure GEM_RCLK_CTRL */ 148 writel(1, &slcr_base->gem0_rclk_ctrl); 149 } 150 udelay(100000); 151 out: 152 zynq_slcr_lock(); 153 } 154 155 void zynq_slcr_devcfg_disable(void) 156 { 157 u32 reg_val; 158 159 zynq_slcr_unlock(); 160 161 /* Disable AXI interface by asserting FPGA resets */ 162 writel(0xF, &slcr_base->fpga_rst_ctrl); 163 164 /* Disable Level shifters before setting PS-PL */ 165 reg_val = readl(&slcr_base->lvl_shftr_en); 166 reg_val &= ~0xF; 167 writel(reg_val, &slcr_base->lvl_shftr_en); 168 169 /* Set Level Shifters DT618760 */ 170 writel(0xA, &slcr_base->lvl_shftr_en); 171 172 zynq_slcr_lock(); 173 } 174 175 void zynq_slcr_devcfg_enable(void) 176 { 177 zynq_slcr_unlock(); 178 179 /* Set Level Shifters DT618760 */ 180 writel(0xF, &slcr_base->lvl_shftr_en); 181 182 /* Enable AXI interface by de-asserting FPGA resets */ 183 writel(0x0, &slcr_base->fpga_rst_ctrl); 184 185 zynq_slcr_lock(); 186 } 187 188 u32 zynq_slcr_get_boot_mode(void) 189 { 190 /* Get the bootmode register value */ 191 return readl(&slcr_base->boot_mode); 192 } 193 194 u32 zynq_slcr_get_idcode(void) 195 { 196 return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> 197 SLCR_IDCODE_SHIFT; 198 } 199 200 /* 201 * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral. 202 * 203 * @periph: Name of the peripheral 204 * 205 * Returns count to indicate the number of pins configured for the 206 * given @periph. 207 */ 208 int zynq_slcr_get_mio_pin_status(const char *periph) 209 { 210 const struct zynq_slcr_mio_get_status *mio_ptr; 211 int val, i, j; 212 int mio = 0; 213 214 for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) { 215 if (strcmp(periph, mio_periphs[i].peri_name) == 0) { 216 mio_ptr = &mio_periphs[i]; 217 for (j = 0; j < mio_ptr->num_pins; j++) { 218 val = readl(&slcr_base->mio_pin 219 [mio_ptr->get_pins[j]]); 220 if ((val & mio_ptr->mask) == mio_ptr->check_val) 221 mio++; 222 } 223 break; 224 } 225 } 226 227 return mio; 228 } 229