* arch/arm64/src/a64/a64_rsb.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
*
* "Rendering PinePhone's Display (DE and TCON0)"
* https://lupyuen.github.io/articles/de
*
* "NuttX RTOS for PinePhone: Render Graphics in Zig"
* https://lupyuen.github.io/articles/de2
*
* "A80 Page" refers to Allwinner A80 User Manual
* https://lupyuen.github.io/images/A80_User_Manual_v1.3.1_20150513.pdf
*/
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "hardware/a64_memorymap.h"
#include "arm64_arch.h"
#include "a64_rsb.h"
* Pre-processor Definitions
****************************************************************************/
#define TRANS_TIMEOUT_MS 5
#define RSB_CTRL (A64_RSB_ADDR + 0x00)
#define START_TRANS (1 << 7)
#define RSB_STAT (A64_RSB_ADDR + 0x0c)
#define TRANS_OVER (1 << 0)
#define RSB_AR (A64_RSB_ADDR + 0x10)
#define RSB_DATA (A64_RSB_ADDR + 0x1c)
#define RSB_CMD (A64_RSB_ADDR + 0x2c)
#define RSB_DAR (A64_RSB_ADDR + 0x30)
#define RTA(n) ((n) << 16)
#define RSBCMD_WR8 0x4e
#define RSBCMD_RD8 0x8b
* Private Functions
****************************************************************************/
* Name: rsb_wait_trans
*
* Description:
* Wait for Reduced Serial Bus Transaction to complete or fail with error.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; ERROR if timeout.
*
****************************************************************************/
static int rsb_wait_trans(void)
{
int i;
for (i = 0; i < TRANS_TIMEOUT_MS; i++)
{
if ((getreg32(RSB_CTRL) & START_TRANS) == 0)
{
return OK;
}
up_mdelay(1);
}
baterr("RSB Transaction Timeout");
return ERROR;
}
* Name: rsb_wait_status
*
* Description:
* Wait for Reduced Serial Bus Transaction to complete or fail with error.
* Return the Transaction Status.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; ERROR if status is error or timeout.
*
****************************************************************************/
static int rsb_wait_status(void)
{
int ret;
ret = rsb_wait_trans();
if (ret < 0)
{
return ret;
}
* If TRANS_OVER (Bit 0) is 1, RSB Transfer has completed without error
*/
if (getreg32(RSB_STAT) == TRANS_OVER)
{
return OK;
}
baterr("RSB Transaction Failed\n");
return ERROR;
}
* Public Functions
****************************************************************************/
* Name: a64_rsb_read
*
* Description:
* Read a byte from a device on the Reduced Serial Bus.
*
* Input Parameters:
* rt_addr - Run-Time Address of RSB Device
* reg_addr - Register Address of RSB Device
*
* Returned Value:
* Byte read from the RSB Device; ERROR if the read failed or timed out.
*
****************************************************************************/
int a64_rsb_read(uint8_t rt_addr, uint8_t reg_addr)
{
int ret;
* Set to 0x8B (RD8) to read one byte
*/
batinfo("rt_addr=0x%x, reg_addr=0x%x\n", rt_addr, reg_addr);
putreg32(RSBCMD_RD8, RSB_CMD);
* Set RTA (Bits 16 to 23) to the Run-Time Address of RSB Device
*/
putreg32(RTA(rt_addr), RSB_DAR);
* Set to the Register Address that will be read from RSB Device
*/
putreg32(reg_addr, RSB_AR);
* Set START_TRANS (Bit 7) to 1 (Start Transaction)
*/
putreg32(START_TRANS, RSB_CTRL);
ret = rsb_wait_status();
if (ret < 0)
{
return ret;
}
* Contains the Register Value read from RSB Device
*/
return getreg8(RSB_DATA);
}
* Name: a64_rsb_write
*
* Description:
* Write a byte to a device on the Reduced Serial Bus.
*
* Input Parameters:
* rt_addr - Run-Time Address of RSB Device
* reg_addr - Register Address of RSB Device
* value - Byte to be written
*
* Returned Value:
* Zero (OK) on success; ERROR if the write failed or timed out.
*
****************************************************************************/
int a64_rsb_write(uint8_t rt_addr, uint8_t reg_addr, uint8_t value)
{
* Set to 0x4E (WR8) to write one byte
*/
batinfo("rt_addr=0x%x, reg_addr=0x%x, value=0x%x\n",
rt_addr, reg_addr, value);
putreg32(RSBCMD_WR8, RSB_CMD);
* Set RTA (Bits 16 to 23) to the Run-Time Address of RSB Device
*/
putreg32(RTA(rt_addr), RSB_DAR);
* Set to the Register Address that will be written to RSB Device
*/
putreg32(reg_addr, RSB_AR);
* Set to the Register Value that will be written to RSB Device
*/
putreg32(value, RSB_DATA);
* Set START_TRANS (Bit 7) to 1 (Start Transaction)
*/
putreg32(START_TRANS, RSB_CTRL);
return rsb_wait_status();
}