diff options
Diffstat (limited to 'arch/arm/cpu/armv7/zynq/slcr.c')
-rw-r--r-- | arch/arm/cpu/armv7/zynq/slcr.c | 87 |
1 files changed, 83 insertions, 4 deletions
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index d7c1882332..934ccc31c8 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -8,26 +8,75 @@ #include <asm/io.h> #include <malloc.h> #include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> #include <asm/arch/clk.h> #define SLCR_LOCK_MAGIC 0x767B #define SLCR_UNLOCK_MAGIC 0xDF0D +#define SLCR_USB_L1_SEL 0x04 + #define SLCR_IDCODE_MASK 0x1F000 #define SLCR_IDCODE_SHIFT 12 +/* + * zynq_slcr_mio_get_status - Get the status of MIO peripheral. + * + * @peri_name: Name of the peripheral for checking MIO status + * @get_pins: Pointer to array of get pin for this peripheral + * @num_pins: Number of pins for this peripheral + * @mask: Mask value + * @check_val: Required check value to get the status of periph + */ +struct zynq_slcr_mio_get_status { + const char *peri_name; + const int *get_pins; + int num_pins; + u32 mask; + u32 check_val; +}; + +static const int usb0_pins[] = { + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 +}; + +static const int usb1_pins[] = { + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 +}; + +static const struct zynq_slcr_mio_get_status mio_periphs[] = { + { + "usb0", + usb0_pins, + ARRAY_SIZE(usb0_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, + { + "usb1", + usb1_pins, + ARRAY_SIZE(usb1_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, +}; + static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ void zynq_slcr_lock(void) { - if (!slcr_lock) + if (!slcr_lock) { writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); + slcr_lock = 1; + } } void zynq_slcr_unlock(void) { - if (slcr_lock) + if (slcr_lock) { writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); + slcr_lock = 0; + } } /* Reset the entire system */ @@ -82,7 +131,7 @@ void zynq_slcr_devcfg_disable(void) { zynq_slcr_unlock(); - /* Disable AXI interface */ + /* Disable AXI interface by asserting FPGA resets */ writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl); /* Set Level Shifters DT618760 */ @@ -98,7 +147,7 @@ void zynq_slcr_devcfg_enable(void) /* Set Level Shifters DT618760 */ writel(0xF, &slcr_base->lvl_shftr_en); - /* Disable AXI interface */ + /* Enable AXI interface by de-asserting FPGA resets */ writel(0x0, &slcr_base->fpga_rst_ctrl); zynq_slcr_lock(); @@ -115,3 +164,33 @@ u32 zynq_slcr_get_idcode(void) return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> SLCR_IDCODE_SHIFT; } + +/* + * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral. + * + * @periph: Name of the peripheral + * + * Returns count to indicate the number of pins configured for the + * given @periph. + */ +int zynq_slcr_get_mio_pin_status(const char *periph) +{ + const struct zynq_slcr_mio_get_status *mio_ptr; + int val, i, j; + int mio = 0; + + for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) { + if (strcmp(periph, mio_periphs[i].peri_name) == 0) { + mio_ptr = &mio_periphs[i]; + for (j = 0; j < mio_ptr->num_pins; j++) { + val = readl(&slcr_base->mio_pin + [mio_ptr->get_pins[j]]); + if ((val & mio_ptr->mask) == mio_ptr->check_val) + mio++; + } + break; + } + } + + return mio; +} |