blob: 93cef28e0a4c010babe7888b1fce48fb8cbbc003 [file] [log] [blame]
Googler25e92cf2023-12-13 10:05:01 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <config.h>
7#include <common.h>
8#include <asm/arch/io.h>
9#include <command.h>
10#include <malloc.h>
11#include <asm/arch/mailbox.h>
12#include <asm/arch/secure_apb.h>
13
14#define aml_writel32(value, reg) writel(value, reg)
15#define aml_readl32(reg) readl(reg)
16
17
18static inline void mbwrite(uint32_t to, void *from, long count)
19{
20 int i = 0;
21 int len = count / 4 + (count % 4);
22 uint32_t *p = from;
23
24 while (len > 0) {
25 aml_writel32(p[i], to + (4 * i));
26 len--;
27 i++;
28 }
29}
30
31static inline void mbclean(uint32_t to, long count)
32{
33 int i = 0;
34 int len = count / 4 + (count % 4);
35
36 while (len > 0) {
37 aml_writel32(0, to + (4 * i));
38 len--;
39 i++;
40 }
41}
42
43int mhu_get_addr(uint32_t chan, uint32_t *mboxset, uint32_t *mboxsts,
44 uintptr_t *mboxpl, uint32_t *mboxwr, uint32_t *mboxrd,
45 uint32_t *mboxirqclr, uint32_t *mboxid)
46{
47 int ret = 0;
48
49 switch (chan) {
50 case AOCPU_REE_CHANNEL:
51 *mboxset = REE2AO_SET_ADDR;
52 *mboxsts = REE2AO_STS_ADDR;
53 *mboxwr = REE2AO_WR_ADDR;
54 *mboxrd = REE2AO_RD_ADDR;
55 *mboxirqclr = REE2AO_IRQCLR_ADDR;
56 *mboxid = REE2AO_MBOX_ID;
57 break;
58 default:
59 printf("[BL33]: no support chan 0x%x\n", chan);
60 ret = -1;
61 break;
62 };
63 return ret;
64}
65
66void mhu_message_start(uint32_t mboxsts)
67{
68 /* Make sure any previous command has finished */
69 while (aml_readl32(mboxsts) != 0);
70}
71
72void mhu_build_payload(uintptr_t mboxpl, uint32_t mboxwr, void *message, uint32_t size)
73{
74 if (size > (MHU_PAYLOAD_SIZE - MHU_DATA_OFFSET)) {
75 printf("bl33: scpi send input size error\n");
76 return;
77 }
78 if (size == 0)
79 return;
80 mbwrite(mboxwr + MHU_DATA_OFFSET, message, size);
81}
82
83void mhu_get_payload(uintptr_t mboxpl, uint32_t mboxwr, void *message, uint32_t size)
84{
85 if (size > (MHU_PAYLOAD_SIZE - MHU_DATA_OFFSET)) {
86 printf("bl33: scpi send input size error\n");
87 return;
88 }
89 if (size == 0)
90 return;
91 printf("bl33: scpi no support get revmessage\n");
92}
93
94void mhu_message_send(uint32_t mboxset, uint32_t command, uint32_t size)
95{
96 uint32_t mbox_cmd;
97 mbox_cmd = MHU_CMD_BUILD(command, size + MHU_DATA_OFFSET);
98 aml_writel32(mbox_cmd, mboxset);
99}
100
101uint32_t mhu_message_wait(uint32_t mboxsts)
102{
103 /* Wait for response from HIFI */
104 uint32_t response;
105
106 while ((response = aml_readl32(mboxsts)));
107
108 return response;
109}
110
111void mhu_message_end(uintptr_t mboxpl, uint32_t mboxwr, uint32_t mboxirqclr, uint32_t mboxid)
112{
113 mbclean(mboxwr, MHU_PAYLOAD_SIZE);
114 /* Clear any response we got by writing all ones to the CLEAR register */
115 aml_writel32(MHU_ACK_MASK(mboxid), mboxirqclr);
116}
117
118void mhu_init(void)
119{
120 aml_writel32(0xffffffffu, REE2AO_CLR_ADDR);
121 printf("[BL33] mhu init done -v2\n");
122}
123int scpi_send_data(uint32_t chan, uint32_t command,
124 void *sendmessage, uint32_t sendsize,
125 void *revmessage, uint32_t revsize)
126{
127 uint32_t mboxset = 0;
128 uint32_t mboxsts = 0;
129 uintptr_t mboxpl = 0;
130 uint32_t mboxwr = 0;
131 uint32_t mboxrd = 0;
132 uint32_t mboxirq = 0;
133 uint32_t mboxid = 0;
134 int ret = 0;
135
136 ret = mhu_get_addr(chan, &mboxset, &mboxsts,
137 &mboxpl, &mboxwr, &mboxrd,
138 &mboxirq, &mboxid);
139 if (ret) {
140 printf("bl33: mhu get addr fail\n");
141 return ret;
142 }
143 mhu_message_start(mboxsts);
144 if (sendmessage != NULL && sendsize != 0)
145 mhu_build_payload(mboxpl, mboxwr, sendmessage, sendsize);
146 mhu_message_send(mboxset, command, sendsize);
147 mhu_message_wait(mboxsts);
148 if (revmessage != NULL && revsize != 0)
149 mhu_get_payload(mboxpl, mboxrd, revmessage, revsize);
150 mhu_message_end(mboxpl, mboxwr, mboxirq, mboxid);
151 return ret;
152}
153