xref: /rk3399_ARM-atf/drivers/allwinner/sunxi_rsb.c (revision c3cf06f1a3a9b9ee8ac7a0ae505f95c45f7dca84)
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