[PATCH] aspeed: SCU helper functions for I2C.
maxims at google.com
maxims at google.com
Tue Oct 4 05:55:57 AEDT 2016
From: Maxim Sloyko <maxims at google.com>
SCU helper functions for configuring I2C pins and accessing APB clock.
---
arch/arm/include/asm/arch-aspeed/ast_scu.h | 6 +++++
arch/arm/include/asm/arch-aspeed/regs-scu.h | 8 ++++++
arch/arm/mach-aspeed/ast-scu.c | 38 +++++++++++++++++++++++++++++
3 files changed, 52 insertions(+)
diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
index d248416..80ebd6f 100644
--- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
+++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
@@ -38,6 +38,7 @@ extern void ast_scu_get_who_init_dram(void);
extern u32 ast_get_clk_source(void);
extern u32 ast_get_h_pll_clk(void);
extern u32 ast_get_ahbclk(void);
+extern u32 ast_get_apbclk(void);
extern u32 ast_scu_get_vga_memsize(void);
@@ -45,4 +46,9 @@ extern void ast_scu_init_eth(u8 num);
extern void ast_scu_multi_func_eth(u8 num);
extern void ast_scu_multi_func_romcs(u8 num);
+/* Enable I2C controller and pins for a particular device.
+ * Device numbering starts at 1
+ */
+extern void ast_scu_enable_i2c(u8 num);
+
#endif
diff --git a/arch/arm/include/asm/arch-aspeed/regs-scu.h b/arch/arm/include/asm/arch-aspeed/regs-scu.h
index aab032a..4c869c1 100644
--- a/arch/arm/include/asm/arch-aspeed/regs-scu.h
+++ b/arch/arm/include/asm/arch-aspeed/regs-scu.h
@@ -915,6 +915,11 @@
#define SCU_FUN_PIN_ROMA4 (0x1 << 18)
#define SCU_FUN_PIN_ROMA3 (0x1 << 17)
#define SCU_FUN_PIN_ROMA2 (0x1 << 16)
+/* AST2500 only */
+#define SCU_FUN_PIN_SDA2 (0x1 << 15)
+#define SCU_FUN_PIN_SCL2 (0x1 << 14)
+#define SCU_FUN_PIN_SDA1 (0x1 << 13)
+#define SCU_FUN_PIN_SCL1 (0x1 << 12)
/* AST_SCU_FUN_PIN_CTRL9 0xA8 - Multi-function Pin Control#9 */
#define SCU_FUN_PIN_ROMA21 (0x1 << 3)
@@ -950,4 +955,7 @@
/* AST_SCU_BMC_CLASS 0x19C - BMC device class code and revision ID */
/* AST_SCU_BMC_DEV_ID 0x1A4 - BMC device ID */
+#define SCU_I2C_MIN_BUS_NUM (1)
+#define SCU_I2C_MAX_BUS_NUM (14)
+
#endif
diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
index 280c421..1dbd667 100644
--- a/arch/arm/mach-aspeed/ast-scu.c
+++ b/arch/arm/mach-aspeed/ast-scu.c
@@ -318,6 +318,17 @@ u32 ast_get_ahbclk(void)
#endif /* AST_SOC_G5 */
+u32 ast_get_apbclk(void)
+{
+ u32 h_pll = ast_get_h_pll_clk();
+ /* The formula for converting the bit pattern to divisor is
+ * (4 + 4 * DIV), according to datasheet
+ */
+ u32 apb_div = 4 + 4 * SCU_GET_PCLK_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+ return h_pll / apb_div;
+}
+
+
void ast_scu_show_system_info(void)
{
@@ -496,3 +507,30 @@ void ast_scu_get_who_init_dram(void)
break;
}
}
+
+void ast_scu_enable_i2c(u8 bus_num)
+{
+ if (bus_num < SCU_I2C_MIN_BUS_NUM || bus_num > SCU_I2C_MAX_BUS_NUM) {
+ debug("%s: bus_num is out of range, must be [%d - %d]\n", __func__,
+ SCU_I2C_MIN_BUS_NUM, SCU_I2C_MAX_BUS_NUM);
+ return;
+ }
+
+ /* Enable I2C Controllers */
+ clrbits_le32(AST_SCU_BASE + AST_SCU_RESET, SCU_RESET_I2C);
+
+ if (bus_num >= 3) {
+ setbits_le32(AST_SCU_BASE + AST_SCU_FUN_PIN_CTRL5,
+ SCU_FUN_PIN_I2C(bus_num));
+#ifdef AST_SOC_G5
+ /* In AST2400 aka AST_SOC_G4 SDA{1,2}/SCL{1,2} are fixed function pins,
+ * so no need to change their function. */
+ } else if (bus_num == 1) {
+ setbits_le32(AST_SCU_BASE + AST_SCU_FUN_PIN_CTRL8,
+ SCU_FUN_PIN_SDA1 | SCU_FUN_PIN_SCL1);
+ } else if (bus_num == 2) {
+ setbits_le32(AST_SCU_BASE + AST_SCU_FUN_PIN_CTRL8,
+ SCU_FUN_PIN_SDA2 | SCU_FUN_PIN_SCL2);
+#endif
+ }
+}
--
2.8.0.rc3.226.g39d4020
More information about the openbmc
mailing list