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