blob: 0ab0de68312b28aaaafb7bc9dbf120bca4bec9ca [file] [log] [blame]
Googler695f9d92023-09-11 15:38:29 +08001/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2/*
3 * arch/arm/cpu/armv8/tm2/mailbox.c
4 *
5 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
6 *
7 */
8
9#include <config.h>
10#include <common.h>
11#include <asm/arch/io.h>
12#include <command.h>
13#include <malloc.h>
14#include <asm/arch/mailbox.h>
15#include <asm/arch/secure_apb.h>
16
17/* Bit position for size value in MHU header */
18#define SIZE_SHIFT 20
19/* Mask to extract size value in MHU header*/
20#define SIZE_MASK 0x1ff
21
22static unsigned int *ap_mb_stat[] = {
23 (unsigned int *)HIU_MAILBOX_STAT_4,
24 (unsigned int *)HIU_MAILBOX_STAT_5,
25};
26static unsigned int *ap_mb_set[] = {
27 (unsigned int *)HIU_MAILBOX_SET_4,
28 (unsigned int *)HIU_MAILBOX_SET_5,
29};
30static unsigned int *ap_mb_clear[] = {
31 (unsigned int *)HIU_MAILBOX_CLR_4,
32 (unsigned int *)HIU_MAILBOX_CLR_5,
33};
34static unsigned int *ap_mb_payload[] = {
35 (unsigned int *)(P_SHARE_SRAM_BASE + MHU_LOW_AP_TO_SCP_PAYLOAD),
36 (unsigned int *)(P_SHARE_SRAM_BASE + MHU_HIGH_AP_TO_SCP_PAYLOAD),
37};
38static unsigned int *scp_mb_stat[] = {
39 (unsigned int *)HIU_MAILBOX_STAT_1,
40 (unsigned int *)HIU_MAILBOX_STAT_2,
41};
42/*
43static unsigned int *scp_mb_set[] = {
44 (unsigned int *)HIU_MAILBOX_SET_1,
45 (unsigned int *)HIU_MAILBOX_SET_2,
46};
47*/
48static unsigned int *scp_mb_clear[] = {
49 (unsigned int *)HIU_MAILBOX_CLR_1,
50 (unsigned int *)HIU_MAILBOX_CLR_2,
51};
52static unsigned int *scp_mb_payload[] = {
53 (unsigned int *)(P_SHARE_SRAM_BASE + MHU_LOW_SCP_TO_AP_PAYLOAD),
54 (unsigned int *)(P_SHARE_SRAM_BASE + MHU_HIGH_SCP_TO_AP_PAYLOAD),
55};
56
57static void mb_message_start(unsigned int priority)
58{
59 while (readl(ap_mb_stat[priority]) != 0)
60 ;
61}
62static void mb_message_send(unsigned int command, unsigned int priority)
63{
64 writel(command, ap_mb_set[priority]);
65 while (readl(ap_mb_stat[priority]) != 0)
66 ;
67}
68static unsigned int mb_message_wait(unsigned int priority)
69{
70 unsigned int response;
71 while (!(response = readl(scp_mb_stat[priority])))
72 ;
73 return response;
74}
75static void mb_message_end(unsigned int priority)
76{
77 writel(0xffffffff, scp_mb_clear[priority]);
78}
79static unsigned int mb_message_receive(
80 void **message_out,
81 unsigned int *size_out,
82 unsigned int priority)
83{
84 unsigned int response = mb_message_wait(priority);
85 unsigned int size = (response >> SIZE_SHIFT) & SIZE_MASK;
86
87 response &= ~(SIZE_MASK << SIZE_SHIFT);
88
89 if (size_out)
90 *size_out = size;
91 if (message_out)
92 *message_out = (void *)(scp_mb_payload[priority]);
93
94 return response;
95}
96static void mb_init(unsigned int priority)
97{
98 writel(0xffffffff, ap_mb_clear[priority]);
99}
100
101static void scpi_send32(unsigned int command,
102 unsigned int message, unsigned int priority)
103{
104 mb_init(priority);
105 mb_message_start(priority);
106 writel(message, ap_mb_payload[priority]);
107 mb_message_send(command, priority);
108 mb_message_wait(priority);
109 mb_message_end(priority);
110}
111
112static void scpi_send_block(unsigned int command,
113 unsigned int *message, unsigned int message_size, unsigned int priority)
114{
115 mb_init(priority);
116 mb_message_start(priority);
117 memcpy(ap_mb_payload[priority], message, message_size);
118 mb_message_send(command, priority);
119 mb_message_wait(priority);
120 mb_message_end(priority);
121}
122
123void open_scp_log(unsigned int channel)
124{
125 scpi_send32(SCPI_CMD_OPEN_SCP_LOG, channel, LOW_PRIORITY);
126}
127
128int send_usr_data(unsigned int clinet_id, unsigned int *val, unsigned int size)
129{
130 unsigned long command;
131
132 if (size > 0x1fd)
133 return -1;
134
135 command = ((unsigned int)SCPI_CMD_SET_USR_DATA & 0xff) | ((clinet_id & 0xff) << 8) | ((size & 0x1ff) << 20);
136 scpi_send_block(command,val,size,0);
137
138 return 0;
139}
140
141/*
142* type:
143* 0: data; 1: version
144*/
145int thermal_calibration(unsigned int type, unsigned int data)
146{
147 unsigned int *appayload = ap_mb_payload[LOW_PRIORITY];
148 unsigned int *response;
149 unsigned int size;
150
151 mb_message_start(LOW_PRIORITY);
152 writel(type, appayload);
153 writel(data, appayload+1);
154 mb_message_send(
155 ((0x8 << SIZE_SHIFT) | SCPI_CMD_THERMAL_CALIB),
156 LOW_PRIORITY);
157 mb_message_receive((void *)&response, &size, LOW_PRIORITY);
158 mb_message_end(LOW_PRIORITY);
159
160 if (*response != SCPI_SUCCESS)
161 return -1;
162 else
163 return 0;
164}
165
166int thermal_get_value(unsigned int sensor_id, unsigned int *value)
167{
168 unsigned int *response;
169 unsigned int size;
170
171 mb_message_start(LOW_PRIORITY);
172 writel(sensor_id, ap_mb_payload[LOW_PRIORITY]);
173 mb_message_send(
174 ((0x4 << SIZE_SHIFT) | SCPI_CMD_SENSOR_VALUE),
175 LOW_PRIORITY);
176 mb_message_receive((void *)&response, &size, LOW_PRIORITY);
177 mb_message_end(LOW_PRIORITY);
178
179 *value = *(response+1);
180 if (*response != SCPI_SUCCESS)
181 return -1;
182 else
183 return 0;
184}
185
186
187void send_pwm_delt(int32_t vcck_delt, int32_t ee_delt)
188{
189 unsigned int *appayload = ap_mb_payload[LOW_PRIORITY];
190 mb_message_start(LOW_PRIORITY);
191 writel(vcck_delt, appayload);
192 writel(ee_delt, appayload+1);
193 mb_message_send(SCPI_CMD_REV_PWM_DELT, LOW_PRIORITY);
194 mb_message_wait(LOW_PRIORITY);
195 mb_message_end(LOW_PRIORITY);
196}
197
198void init_dsp(unsigned int id,unsigned int addr,unsigned int cfg0,unsigned int jtag_ctrl,unsigned int cfg1)
199{
200 mb_message_start(HIGH_PRIORITY);
201 writel(id, ap_mb_payload[HIGH_PRIORITY]);
202 writel(addr, (ap_mb_payload[HIGH_PRIORITY]+1));
203 writel(cfg0, (ap_mb_payload[HIGH_PRIORITY]+2));
204 writel(jtag_ctrl, (ap_mb_payload[HIGH_PRIORITY]+3));
205 writel(cfg1, (ap_mb_payload[HIGH_PRIORITY]+4));
206 mb_message_send(0x34, HIGH_PRIORITY);
207 mb_message_wait(HIGH_PRIORITY);
208 mb_message_end(HIGH_PRIORITY);
209}
210
211void init_dsp_jtag(unsigned int id)
212{
213 mb_message_start(HIGH_PRIORITY);
214 writel(id, ap_mb_payload[HIGH_PRIORITY]);
215 mb_message_send(0x35, HIGH_PRIORITY);
216 mb_message_wait(HIGH_PRIORITY);
217 mb_message_end(HIGH_PRIORITY);
218}
219
220void set_boot_first_timeout(unsigned int command)
221{
222 mb_message_start(LOW_PRIORITY);
223 writel(0, ap_mb_payload[LOW_PRIORITY]);
224 mb_message_send(command, LOW_PRIORITY);
225 mb_message_wait(LOW_PRIORITY);
226 mb_message_end(LOW_PRIORITY);
227}
228
229#ifdef CONFIG_RING
230int efuse_get_value(unsigned char *efuseinfo)
231{
232 struct {
233 unsigned int status;
234 unsigned char efuseinfo[12];
235 } *response;
236 unsigned int size;
237
238 mb_message_start(LOW_PRIORITY);
239 writel(0, ap_mb_payload[LOW_PRIORITY]);
240 mb_message_send(
241 ((0x4 << SIZE_SHIFT) | SCPI_CMD_OSCRING_VALUE),
242 LOW_PRIORITY);
243 mb_message_receive((void *)&response, &size, LOW_PRIORITY);
244 mb_message_end(LOW_PRIORITY);
245
246 memcpy(efuseinfo, &response->efuseinfo, sizeof(response->efuseinfo));
247 if (response->status != SCPI_SUCCESS)
248 return -1;
249 else
250 return 0;
251}
252#endif