1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park
7*54fd6939SJiyong Park #include <platform_def.h>
8*54fd6939SJiyong Park
9*54fd6939SJiyong Park #include <arch_helpers.h>
10*54fd6939SJiyong Park #include <common/debug.h>
11*54fd6939SJiyong Park #include <lib/mmio.h>
12*54fd6939SJiyong Park
13*54fd6939SJiyong Park #include <rpi_hw.h>
14*54fd6939SJiyong Park
15*54fd6939SJiyong Park #include <drivers/rpi3/mailbox/rpi3_mbox.h>
16*54fd6939SJiyong Park
17*54fd6939SJiyong Park #define RPI3_MAILBOX_MAX_RETRIES U(1000000)
18*54fd6939SJiyong Park
19*54fd6939SJiyong Park /*******************************************************************************
20*54fd6939SJiyong Park * Routine to send requests to the VideoCore using the mailboxes.
21*54fd6939SJiyong Park ******************************************************************************/
rpi3_vc_mailbox_request_send(rpi3_mbox_request_t * req,int req_size)22*54fd6939SJiyong Park void rpi3_vc_mailbox_request_send(rpi3_mbox_request_t *req, int req_size)
23*54fd6939SJiyong Park {
24*54fd6939SJiyong Park uint32_t st, data;
25*54fd6939SJiyong Park uintptr_t resp_addr, addr;
26*54fd6939SJiyong Park unsigned int retries;
27*54fd6939SJiyong Park
28*54fd6939SJiyong Park /* This is the location of the request buffer */
29*54fd6939SJiyong Park addr = (uintptr_t)req;
30*54fd6939SJiyong Park
31*54fd6939SJiyong Park /* Make sure that the changes are seen by the VideoCore */
32*54fd6939SJiyong Park flush_dcache_range(addr, req_size);
33*54fd6939SJiyong Park
34*54fd6939SJiyong Park /* Wait until the outbound mailbox is empty */
35*54fd6939SJiyong Park retries = 0U;
36*54fd6939SJiyong Park
37*54fd6939SJiyong Park do {
38*54fd6939SJiyong Park st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX1_STATUS_OFFSET);
39*54fd6939SJiyong Park
40*54fd6939SJiyong Park retries++;
41*54fd6939SJiyong Park if (retries == RPI3_MAILBOX_MAX_RETRIES) {
42*54fd6939SJiyong Park ERROR("rpi3: mbox: Send request timeout\n");
43*54fd6939SJiyong Park return;
44*54fd6939SJiyong Park }
45*54fd6939SJiyong Park
46*54fd6939SJiyong Park } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) == 0U);
47*54fd6939SJiyong Park
48*54fd6939SJiyong Park /* Send base address of this message to start request */
49*54fd6939SJiyong Park mmio_write_32(RPI3_MBOX_BASE + RPI3_MBOX1_WRITE_OFFSET,
50*54fd6939SJiyong Park RPI3_CHANNEL_ARM_TO_VC | (uint32_t) addr);
51*54fd6939SJiyong Park
52*54fd6939SJiyong Park /* Wait until the inbound mailbox isn't empty */
53*54fd6939SJiyong Park retries = 0U;
54*54fd6939SJiyong Park
55*54fd6939SJiyong Park do {
56*54fd6939SJiyong Park st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_STATUS_OFFSET);
57*54fd6939SJiyong Park
58*54fd6939SJiyong Park retries++;
59*54fd6939SJiyong Park if (retries == RPI3_MAILBOX_MAX_RETRIES) {
60*54fd6939SJiyong Park ERROR("rpi3: mbox: Receive response timeout\n");
61*54fd6939SJiyong Park return;
62*54fd6939SJiyong Park }
63*54fd6939SJiyong Park
64*54fd6939SJiyong Park } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) != 0U);
65*54fd6939SJiyong Park
66*54fd6939SJiyong Park /* Get location and channel */
67*54fd6939SJiyong Park data = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_READ_OFFSET);
68*54fd6939SJiyong Park
69*54fd6939SJiyong Park if ((data & RPI3_CHANNEL_MASK) != RPI3_CHANNEL_ARM_TO_VC) {
70*54fd6939SJiyong Park ERROR("rpi3: mbox: Wrong channel: 0x%08x\n", data);
71*54fd6939SJiyong Park panic();
72*54fd6939SJiyong Park }
73*54fd6939SJiyong Park
74*54fd6939SJiyong Park resp_addr = (uintptr_t)(data & ~RPI3_CHANNEL_MASK);
75*54fd6939SJiyong Park if (addr != resp_addr) {
76*54fd6939SJiyong Park ERROR("rpi3: mbox: Unexpected address: 0x%08x\n", data);
77*54fd6939SJiyong Park panic();
78*54fd6939SJiyong Park }
79*54fd6939SJiyong Park
80*54fd6939SJiyong Park /* Make sure that the data seen by the CPU is up to date */
81*54fd6939SJiyong Park inv_dcache_range(addr, req_size);
82*54fd6939SJiyong Park }
83