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