|
@@ -98,3 +98,76 @@ unsigned int zynqmp_get_silicon_version(void)
|
|
|
|
|
|
return ZYNQMP_CSU_VERSION_SILICON;
|
|
|
}
|
|
|
+
|
|
|
+#define ZYNQMP_MMIO_READ 0xC2000014
|
|
|
+#define ZYNQMP_MMIO_WRITE 0xC2000013
|
|
|
+
|
|
|
+#ifndef CONFIG_SPL_BUILD
|
|
|
+int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
|
|
|
+ u32 *ret_payload)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Added SIP service call Function Identifier
|
|
|
+ * Make sure to stay in x0 register
|
|
|
+ */
|
|
|
+ struct pt_regs regs;
|
|
|
+
|
|
|
+ regs.regs[0] = pm_api_id;
|
|
|
+ regs.regs[1] = ((u64)arg1 << 32) | arg0;
|
|
|
+ regs.regs[2] = ((u64)arg3 << 32) | arg2;
|
|
|
+
|
|
|
+ smc_call(®s);
|
|
|
+
|
|
|
+ if (ret_payload != NULL) {
|
|
|
+ ret_payload[0] = (u32)regs.regs[0];
|
|
|
+ ret_payload[1] = upper_32_bits(regs.regs[0]);
|
|
|
+ ret_payload[2] = (u32)regs.regs[1];
|
|
|
+ ret_payload[3] = upper_32_bits(regs.regs[1]);
|
|
|
+ ret_payload[4] = (u32)regs.regs[2];
|
|
|
+ }
|
|
|
+
|
|
|
+ return regs.regs[0];
|
|
|
+}
|
|
|
+
|
|
|
+int zynqmp_mmio_write(const u32 address,
|
|
|
+ const u32 mask,
|
|
|
+ const u32 value)
|
|
|
+{
|
|
|
+ return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask, value, 0, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+int zynqmp_mmio_read(const u32 address, u32 *value)
|
|
|
+{
|
|
|
+ u32 ret_payload[PAYLOAD_ARG_CNT];
|
|
|
+ u32 ret;
|
|
|
+
|
|
|
+ if (!value)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0, 0, ret_payload);
|
|
|
+ *value = ret_payload[1];
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+#else
|
|
|
+int zynqmp_mmio_write(const u32 address,
|
|
|
+ const u32 mask,
|
|
|
+ const u32 value)
|
|
|
+{
|
|
|
+ u32 data;
|
|
|
+ u32 value_local = value;
|
|
|
+
|
|
|
+ zynqmp_mmio_read(address, &data);
|
|
|
+ data &= ~mask;
|
|
|
+ value_local &= mask;
|
|
|
+ value_local |= data;
|
|
|
+ writel(value_local, (ulong)address);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int zynqmp_mmio_read(const u32 address, u32 *value)
|
|
|
+{
|
|
|
+ *value = readl((ulong)address);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|