diff --git a/hal/armv7a/zynq7000/zynq.c b/hal/armv7a/zynq7000/zynq.c index d7f00d132..56a6a4dcf 100644 --- a/hal/armv7a/zynq7000/zynq.c +++ b/hal/armv7a/zynq7000/zynq.c @@ -524,6 +524,37 @@ static void zynq_softRst(void) } +static int _zynq_setSDWpCd(char dev, unsigned char wpPin, unsigned char cdPin) +{ + if ((dev != 0) && (dev != 1)) { + return -1; + } + + if ((cdPin > 63) || (wpPin > 63)) { + return -1; + } + + _zynq_slcrUnlock(); + *(zynq_common.slcr + slcr_sd0_wp_cd_sel + dev) = ((u32)cdPin << 16) | (wpPin); + _zynq_slcrLock(); + return 0; +} + + +static int _zynq_getSDWpCd(char dev, unsigned char *wpPin, unsigned char *cdPin) +{ + u32 val = 0; + if ((dev != 0) && (dev != 1)) { + return -1; + } + + val = *(zynq_common.slcr + slcr_sd0_wp_cd_sel + dev); + *wpPin = val & 0x3f; + *cdPin = (val >> 16) & 0x3f; + return 0; +} + + void hal_cpuReboot(void) { zynq_softRst(); @@ -597,6 +628,14 @@ int hal_platformctl(void *ptr) zynq_softRst(); break; + case pctl_sdwpcd: + if (data->action == pctl_set) { + ret = _zynq_setSDWpCd(data->SDWpCd.dev, data->SDWpCd.wpPin, data->SDWpCd.cdPin); + } + else { /* data->action == pctl_get */ + ret = _zynq_getSDWpCd(data->SDWpCd.dev, &data->SDWpCd.wpPin, &data->SDWpCd.cdPin); + } + default: break; } diff --git a/include/arch/zynq7000.h b/include/arch/zynq7000.h index 8dfd47248..4c267ff92 100644 --- a/include/arch/zynq7000.h +++ b/include/arch/zynq7000.h @@ -16,6 +16,7 @@ #ifndef _PHOENIX_ARCH_ZYNQ7000_H_ #define _PHOENIX_ARCH_ZYNQ7000_H_ +/* clang-format off */ /* AMBA peripherals */ enum { @@ -52,8 +53,10 @@ enum { typedef struct { enum { pctl_set = 0, pctl_get } action; - enum { pctl_ambaclock = 0, pctl_devclock, pctl_mioclock, pctl_mio, pctl_devreset, pctl_reboot } type; + enum { pctl_ambaclock = 0, pctl_devclock, pctl_mioclock, + pctl_mio, pctl_devreset, pctl_reboot, pctl_sdwpcd } type; + /* clang-format on */ union { struct { int dev; @@ -99,6 +102,12 @@ typedef struct { unsigned int magic; unsigned int reason; } reboot; + + struct { + char dev; + unsigned char wpPin; + unsigned char cdPin; + } SDWpCd; }; } __attribute__((packed)) platformctl_t;