1
2
3
4
5
6
7
8
9
10#include <common.h>
11#include <asm/io.h>
12#include <asm/arch/sys_proto.h>
13
14
15#define IPI_BIT_MASK_APU 0x00001
16#define IPI_BIT_MASK_PMU0 0x10000
17#define IPI_REG_BASE_APU 0xFF300000
18#define IPI_REG_BASE_PMU0 0xFF330000
19#define IPI_REG_OFFSET_TRIG 0x00
20#define IPI_REG_OFFSET_OBR 0x04
21
22
23#define IPI_BUF_BASE_APU 0xFF990400
24#define IPI_BUF_OFFSET_TARGET_PMU 0x1C0
25#define IPI_BUF_OFFSET_REQ 0x00
26#define IPI_BUF_OFFSET_RESP 0x20
27
28#define PMUFW_PAYLOAD_ARG_CNT 8
29
30
31#define PMUFW_CMD_SET_CONFIGURATION 2
32
33static void pmu_ipc_send_request(const u32 *req, size_t req_len)
34{
35 u32 *mbx = (u32 *)(IPI_BUF_BASE_APU +
36 IPI_BUF_OFFSET_TARGET_PMU +
37 IPI_BUF_OFFSET_REQ);
38 size_t i;
39
40 for (i = 0; i < req_len; i++)
41 writel(req[i], &mbx[i]);
42}
43
44static void pmu_ipc_read_response(unsigned int *value, size_t count)
45{
46 u32 *mbx = (u32 *)(IPI_BUF_BASE_APU +
47 IPI_BUF_OFFSET_TARGET_PMU +
48 IPI_BUF_OFFSET_RESP);
49 size_t i;
50
51 for (i = 0; i < count; i++)
52 value[i] = readl(&mbx[i]);
53}
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68static int pmu_ipc_request(const u32 *req, size_t req_len,
69 u32 *res, size_t res_maxlen)
70{
71 u32 status;
72
73 if (req_len > PMUFW_PAYLOAD_ARG_CNT ||
74 res_maxlen > PMUFW_PAYLOAD_ARG_CNT)
75 return -EINVAL;
76
77 pmu_ipc_send_request(req, req_len);
78
79
80 writel(IPI_BIT_MASK_PMU0, IPI_REG_BASE_APU + IPI_REG_OFFSET_TRIG);
81 do {
82 status = readl(IPI_REG_BASE_APU + IPI_REG_OFFSET_OBR);
83 } while (status & IPI_BIT_MASK_PMU0);
84
85 pmu_ipc_read_response(res, res_maxlen);
86
87 return 0;
88}
89
90
91
92
93
94
95
96void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
97{
98 const u32 request[] = {
99 PMUFW_CMD_SET_CONFIGURATION,
100 (u32)((u64)cfg_obj)
101 };
102 u32 response;
103 int err;
104
105 printf("Loading PMUFW cfg obj (%ld bytes)\n", size);
106
107 err = pmu_ipc_request(request, ARRAY_SIZE(request), &response, 1);
108 if (err)
109 panic("Cannot load PMUFW configuration object (%d)\n", err);
110 if (response != 0)
111 panic("PMUFW returned 0x%08x status!\n", response);
112}
113