aboutsummaryrefslogtreecommitdiff
path: root/plat/allwinner/common/sunxi_common.c
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2018-10-14 22:13:53 +0100
committerAndre Przywara <andre.przywara@arm.com>2018-10-20 16:23:59 +0100
commitd5ddf67a66d77d04a6f0f6856af02704f486fd73 (patch)
treef0096dcb5ac0a0ba98af90ad7e92cbb36cdae8e4 /plat/allwinner/common/sunxi_common.c
parent103f19f055bebf5ffa5ef73bba51d736123c7c33 (diff)
downloadtrusted-firmware-a-d5ddf67a66d77d04a6f0f6856af02704f486fd73.tar.gz
allwinner: H6: Factor out I2C platform setup
In the H6 platform code there is a routine to do the platform initialisation of the R_I2C controller. We will need a very similar setup routine to initialise the RSB controller on the A64. Move this code to sunxi_common.c and generalise it to support all SoCs and also to cover the related RSB bus. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Diffstat (limited to 'plat/allwinner/common/sunxi_common.c')
-rw-r--r--plat/allwinner/common/sunxi_common.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 88156b51cb..a39c149ee6 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <debug.h>
+#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
@@ -100,3 +102,58 @@ void sunxi_set_gpio_out(char port, int pin, bool level_high)
0x7 << ((pin % 8) * 4),
0x1 << ((pin % 8) * 4));
}
+
+int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
+{
+ uint32_t pin_func = 0x77;
+ uint32_t device_bit;
+ unsigned int reset_offset = 0xb0;
+
+ switch (socid) {
+ case SUNXI_SOC_H5:
+ if (use_rsb)
+ return -ENODEV;
+ pin_func = 0x22;
+ device_bit = BIT(6);
+ break;
+ case SUNXI_SOC_H6:
+ if (use_rsb)
+ return -ENODEV;
+ pin_func = 0x33;
+ device_bit = BIT(16);
+ reset_offset = 0x19c;
+ break;
+ case SUNXI_SOC_A64:
+ pin_func = use_rsb ? 0x22 : 0x33;
+ device_bit = use_rsb ? BIT(3) : BIT(6);
+ break;
+ default:
+ INFO("R_I2C/RSB on Allwinner 0x%x SoC not supported\n", socid);
+ return -ENODEV;
+ }
+
+ /* un-gate R_PIO clock */
+ if (socid != SUNXI_SOC_H6)
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0));
+
+ /* switch pins PL0 and PL1 to the desired function */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x00, 0xffU, pin_func);
+
+ /* level 2 drive strength */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x14, 0x0fU, 0xaU);
+
+ /* set both pins to pull-up */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
+
+ /* assert, then de-assert reset of I2C/RSB controller */
+ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
+ /* un-gate clock */
+ if (socid != SUNXI_SOC_H6)
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
+ else
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+
+ return 0;
+}