1 /* 2 * Copyright (c) 2017-2018 ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <debug.h> 8 #include <delay_timer.h> 9 #include <errno.h> 10 #include <mmio.h> 11 #include <sunxi_mmap.h> 12 13 #define RSB_CTRL 0x00 14 #define RSB_CCR 0x04 15 #define RSB_INTE 0x08 16 #define RSB_STAT 0x0c 17 #define RSB_DADDR0 0x10 18 #define RSB_DLEN 0x18 19 #define RSB_DATA0 0x1c 20 #define RSB_LCR 0x24 21 #define RSB_PMCR 0x28 22 #define RSB_CMD 0x2c 23 #define RSB_SADDR 0x30 24 25 #define RSBCMD_SRTA 0xE8 26 #define RSBCMD_RD8 0x8B 27 #define RSBCMD_RD16 0x9C 28 #define RSBCMD_RD32 0xA6 29 #define RSBCMD_WR8 0x4E 30 #define RSBCMD_WR16 0x59 31 #define RSBCMD_WR32 0x63 32 33 #define MAX_TRIES 100000 34 35 static int rsb_wait_bit(const char *desc, unsigned int offset, uint32_t mask) 36 { 37 uint32_t reg, tries = MAX_TRIES; 38 39 do 40 reg = mmio_read_32(SUNXI_R_RSB_BASE + offset); 41 while ((reg & mask) && --tries); /* transaction in progress */ 42 if (reg & mask) { 43 ERROR("%s: timed out\n", desc); 44 return -ETIMEDOUT; 45 } 46 47 return 0; 48 } 49 50 static int rsb_wait_stat(const char *desc) 51 { 52 uint32_t reg; 53 int ret = rsb_wait_bit(desc, RSB_CTRL, BIT(7)); 54 55 if (ret) 56 return ret; 57 58 reg = mmio_read_32(SUNXI_R_RSB_BASE + RSB_STAT); 59 if (reg == 0x01) 60 return 0; 61 62 ERROR("%s: 0x%x\n", desc, reg); 63 return -reg; 64 } 65 66 /* Initialize the RSB controller. */ 67 int rsb_init_controller(void) 68 { 69 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x01); /* soft reset */ 70 71 return rsb_wait_bit("RSB: reset controller", RSB_CTRL, BIT(0)); 72 } 73 74 int rsb_read(uint8_t rt_addr, uint8_t reg_addr) 75 { 76 int ret; 77 78 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_RD8); /* read a byte */ 79 mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, rt_addr << 16); 80 mmio_write_32(SUNXI_R_RSB_BASE + RSB_DADDR0, reg_addr); 81 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80);/* start transaction */ 82 83 ret = rsb_wait_stat("RSB: read command"); 84 if (ret) 85 return ret; 86 87 return mmio_read_32(SUNXI_R_RSB_BASE + RSB_DATA0) & 0xff; /* result */ 88 } 89 90 int rsb_write(uint8_t rt_addr, uint8_t reg_addr, uint8_t value) 91 { 92 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_WR8); /* byte write */ 93 mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, rt_addr << 16); 94 mmio_write_32(SUNXI_R_RSB_BASE + RSB_DADDR0, reg_addr); 95 mmio_write_32(SUNXI_R_RSB_BASE + RSB_DATA0, value); 96 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80);/* start transaction */ 97 98 return rsb_wait_stat("RSB: write command"); 99 } 100 101 int rsb_set_device_mode(uint32_t device_mode) 102 { 103 mmio_write_32(SUNXI_R_RSB_BASE + RSB_PMCR, 104 (device_mode & 0x00ffffff) | BIT(31)); 105 106 return rsb_wait_bit("RSB: set device to RSB", RSB_PMCR, BIT(31)); 107 } 108 109 int rsb_set_bus_speed(uint32_t source_freq, uint32_t bus_freq) 110 { 111 uint32_t reg; 112 113 if (bus_freq == 0) 114 return -EINVAL; 115 116 reg = source_freq / bus_freq; 117 if (reg < 2) 118 return -EINVAL; 119 120 reg = reg / 2 - 1; 121 reg |= (1U << 8); /* one cycle of CD output delay */ 122 123 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CCR, reg); 124 125 return 0; 126 } 127 128 /* Initialize the RSB PMIC connection. */ 129 int rsb_assign_runtime_address(uint16_t hw_addr, uint8_t rt_addr) 130 { 131 mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, hw_addr | (rt_addr << 16)); 132 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_SRTA); 133 mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80); 134 135 return rsb_wait_stat("RSB: set run-time address"); 136 } 137