summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/qualcomm/ipq806x/gsbi.c116
-rw-r--r--src/soc/qualcomm/ipq806x/i2c.c47
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/iomap.h72
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/qup.h3
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/spi.h17
-rw-r--r--src/soc/qualcomm/ipq806x/qup.c16
6 files changed, 176 insertions, 95 deletions
diff --git a/src/soc/qualcomm/ipq806x/gsbi.c b/src/soc/qualcomm/ipq806x/gsbi.c
index 3fc723a555..54adbe8db7 100644
--- a/src/soc/qualcomm/ipq806x/gsbi.c
+++ b/src/soc/qualcomm/ipq806x/gsbi.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,68 +28,78 @@
*/
#include <arch/io.h>
+#include <soc/iomap.h>
#include <soc/gsbi.h>
-#include <soc/gpio.h>
+#include <console/console.h>
-//TODO: To be implemented as part of the iomap.
-static int gsbi_base[] = {
- 0x12440000, /*GSBI1*/
- 0x12480000, /*GSBI2*/
- 0x16200000, /*GSBI3*/
- 0x16300000, /*GSBI4*/
- 0x1A200000, /*GSBI5*/
- 0x16500000, /*GSBI6*/
- 0x16600000 /*GSBI7*/
-};
-
-#define QUP_APPS_ADDR(N, os) ((void *)((0x009029C8+os)+(32*(N-1))))
-#define GSBI_HCLK_CTL(N) ((void *)(0x009029C0 + (32*(N-1))))
-#define GSBI_RESET(N) ((void *)(0x009029DC + (32*(N-1))))
-#define GSBI_CTL(N) ((void *)(gsbi_base[N-1]))
-
-#define GSBI_APPS_MD_OFFSET 0x0
-#define GSBI_APPS_NS_OFFSET 0x4
-#define GSBI_APPS_MAX_OFFSET 0xff
+static inline void *gsbi_ctl_reg_addr(gsbi_id_t gsbi_id)
+{
+ switch (gsbi_id) {
+ case GSBI_ID_1:
+ return GSBI1_CTL_REG;
+ case GSBI_ID_2:
+ return GSBI2_CTL_REG;
+ case GSBI_ID_3:
+ return GSBI3_CTL_REG;
+ case GSBI_ID_4:
+ return GSBI4_CTL_REG;
+ case GSBI_ID_5:
+ return GSBI5_CTL_REG;
+ case GSBI_ID_6:
+ return GSBI6_CTL_REG;
+ case GSBI_ID_7:
+ return GSBI7_CTL_REG;
+ default:
+ printk(BIOS_ERR, "Unsupported GSBI%d\n", gsbi_id);
+ return 0;
+ }
+}
gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol)
{
- unsigned i = 0;
- unsigned qup_apps_ini[] = {
- GSBI_APPS_NS_OFFSET, 0xf80b43,
- GSBI_APPS_NS_OFFSET, 0xfc095b,
- GSBI_APPS_NS_OFFSET, 0xfc015b,
- GSBI_APPS_NS_OFFSET, 0xfc005b,
- GSBI_APPS_NS_OFFSET, 0xA05,
- GSBI_APPS_NS_OFFSET, 0x185,
- GSBI_APPS_MD_OFFSET, 0x100fb,
- GSBI_APPS_NS_OFFSET, 0xA05,
- GSBI_APPS_NS_OFFSET, 0xfc015b,
- GSBI_APPS_NS_OFFSET, 0xfc015b,
- GSBI_APPS_NS_OFFSET, 0xfc095b,
- GSBI_APPS_NS_OFFSET, 0xfc0b5b,
- GSBI_APPS_MAX_OFFSET, 0x0
- };
+ unsigned reg_val;
+ unsigned m = 1;
+ unsigned n = 4;
+ unsigned pre_div = 4;
+ unsigned src = 3;
+ unsigned mnctr_mode = 2;
+ void *gsbi_ctl = gsbi_ctl_reg_addr(gsbi_id);
- gsbi_return_t ret = GSBI_SUCCESS;
+ if (!gsbi_ctl)
+ return GSBI_ID_ERROR;
- writel(0, GSBI_RESET(gsbi_id));
+ writel((1 << GSBI_HCLK_CTL_GATE_ENA) | (1 << GSBI_HCLK_CTL_BRANCH_ENA),
+ GSBI_HCLK_CTL(gsbi_id));
- if (gsbi_init_board(gsbi_id)) {
- ret = GSBI_UNSUPPORTED;
- goto bail_out;
- }
+ if (gsbi_init_board(gsbi_id))
+ return GSBI_UNSUPPORTED;
- /*Select i2c protocol*/
- writel((2 << 4), GSBI_CTL(gsbi_id));
+ writel(0, GSBI_QUP_APSS_NS_REG(gsbi_id));
+ writel(0, GSBI_QUP_APSS_MD_REG(gsbi_id));
+
+ reg_val = ((m & GSBI_QUP_APPS_M_MASK) << GSBI_QUP_APPS_M_SHFT) |
+ ((~n & GSBI_QUP_APPS_D_MASK) << GSBI_QUP_APPS_D_SHFT);
+ writel(reg_val, GSBI_QUP_APSS_MD_REG(gsbi_id));
+
+ reg_val = (((~(n - m)) & GSBI_QUP_APPS_N_MASK) <<
+ GSBI_QUP_APPS_N_SHFT) |
+ ((mnctr_mode & GSBI_QUP_APPS_MNCTR_MODE_MSK) <<
+ GSBI_QUP_APPS_MNCTR_MODE_SFT) |
+ (((pre_div - 1) & GSBI_QUP_APPS_PRE_DIV_MSK) <<
+ GSBI_QUP_APPS_PRE_DIV_SFT) |
+ (src & GSBI_QUP_APPS_SRC_SEL_MSK);
+ writel(reg_val, GSBI_QUP_APSS_NS_REG(gsbi_id));
- //TODO: Make use of clock API when available instead of the hardcoding.
- /* Clock set to 24Mhz */
- for (i = 0; GSBI_APPS_MAX_OFFSET != qup_apps_ini[i]; i += 2)
- writel(qup_apps_ini[i+1],
- QUP_APPS_ADDR(gsbi_id, qup_apps_ini[i]));
+ reg_val |= (1 << GSBI_QUP_APPS_ROOT_ENA_SFT) |
+ (1 << GSBI_QUP_APPS_MNCTR_EN_SFT);
+ writel(reg_val, GSBI_QUP_APSS_NS_REG(gsbi_id));
- writel(((1 << 6)|(1 << 4)), GSBI_HCLK_CTL(gsbi_id));
+ reg_val |= (1 << GSBI_QUP_APPS_BRANCH_ENA_SFT);
+ writel(reg_val, GSBI_QUP_APSS_NS_REG(gsbi_id));
+
+ /*Select i2c protocol*/
+ writel(((GSBI_CTL_PROTO_I2C & GSBI_CTL_PROTO_CODE_MSK) <<
+ GSBI_CTL_PROTO_CODE_SFT), gsbi_ctl);
-bail_out:
- return ret;
+ return GSBI_SUCCESS;
}
diff --git a/src/soc/qualcomm/ipq806x/i2c.c b/src/soc/qualcomm/ipq806x/i2c.c
index a4d1c00856..9aaa173513 100644
--- a/src/soc/qualcomm/ipq806x/i2c.c
+++ b/src/soc/qualcomm/ipq806x/i2c.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,11 +37,28 @@
#include <soc/gsbi.h>
#include <soc/qup.h>
-static const qup_config_t gsbi4_qup_config = {
+static qup_config_t gsbi1_qup_config = {
QUP_MINICORE_I2C_MASTER,
100000,
24000000,
- QUP_MODE_FIFO
+ QUP_MODE_FIFO,
+ 0
+};
+
+static qup_config_t gsbi4_qup_config = {
+ QUP_MINICORE_I2C_MASTER,
+ 100000,
+ 24000000,
+ QUP_MODE_FIFO,
+ 0
+};
+
+static qup_config_t gsbi7_qup_config = {
+ QUP_MINICORE_I2C_MASTER,
+ 100000,
+ 24000000,
+ QUP_MODE_FIFO,
+ 0
};
static int i2c_read(uint32_t gsbi_id, uint8_t slave,
@@ -84,10 +101,26 @@ static int i2c_write(uint32_t gsbi_id, uint8_t slave,
static int i2c_init(unsigned bus)
{
- static uint8_t initialized = 0;
unsigned gsbi_id = bus;
+ qup_config_t *qup_config;
+
+ switch (gsbi_id) {
+ case GSBI_ID_1:
+ qup_config = &gsbi1_qup_config;
+ break;
+ case GSBI_ID_4:
+ qup_config = &gsbi4_qup_config;
+ break;
+ case GSBI_ID_7:
+ qup_config = &gsbi7_qup_config;
+ break;
+ default:
+ printk(BIOS_ERR, "QUP configuration not defind for GSBI%d.\n",
+ gsbi_id);
+ return 1;
+ }
- if (initialized)
+ if (qup_config->initialized)
return 0;
if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) {
@@ -95,7 +128,7 @@ static int i2c_init(unsigned bus)
return 1;
}
- if (qup_init(gsbi_id, &gsbi4_qup_config)) {
+ if (qup_init(gsbi_id, qup_config)) {
printk(BIOS_ERR, "failed to initialize qup\n");
return 1;
}
@@ -105,7 +138,7 @@ static int i2c_init(unsigned bus)
return 1;
}
- initialized = 1;
+ qup_config->initialized = 1;
return 0;
}
diff --git a/src/soc/qualcomm/ipq806x/include/soc/iomap.h b/src/soc/qualcomm/ipq806x/include/soc/iomap.h
index 76131805d4..412ff77c35 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/iomap.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/iomap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012 - 2013, 2015 The Linux Foundation. All rights reserved.
*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
@@ -49,13 +49,13 @@
#define clrsetbits_le32_i(addr, clear, set) \
clrsetbits_le32(((void *)(addr)), (clear), (set))
-#define MSM_CLK_CTL_BASE ((unsigned char *)0x00900000)
+#define MSM_CLK_CTL_BASE ((void *)0x00900000)
-#define MSM_TMR_BASE ((unsigned char *)0x0200A000)
+#define MSM_TMR_BASE ((void *)0x0200A000)
#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
-#define GPT_REG(off) ((void *)(MSM_GPT_BASE + (off)))
+#define GPT_REG(off) (MSM_GPT_BASE + (off))
#define DGT_REG(off) (MSM_DGT_BASE + (off))
#define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040)
@@ -88,7 +88,7 @@
#define RPM_SIGNAL_ENTRY ((void *)0x47C24)
#define RPM_FW_MAGIC_NUM 0x4D505242
-#define TLMM_BASE_ADDR ((char *)0x00800000)
+#define TLMM_BASE_ADDR ((void *)0x00800000)
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
#define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4)
@@ -100,10 +100,7 @@
#define USB_HOST1_DWC3_BASE 0x1100C100
#define USB_HOST1_PHY_BASE 0x110F8800
-#define GSBI_1 1
-#define GSBI_2 2
#define GSBI_4 4
-#define GSBI_2 2
#define UART1_DM_BASE 0x12450000
#define UART_GSBI1_BASE 0x12440000
#define UART2_DM_BASE 0x12490000
@@ -114,12 +111,55 @@
#define UART2_DM_BASE 0x12490000
#define UART_GSBI2_BASE 0x12480000
-#define GSBI_QUP1_BASE 0x12460000
-#define GSBI_QUP2_BASE 0x124A0000
-#define GSBI_QUP3_BASE 0x16280000
-#define GSBI_QUP4_BASE 0x16380000
-#define GSBI_QUP5_BASE 0x1A280000
-#define GSBI_QUP6_BASE 0x16580000
-#define GSBI_QUP7_BASE 0x16680000
-
+#define GSBI1_BASE ((void *)0x12440000)
+#define GSBI2_BASE ((void *)0x12480000)
+#define GSBI3_BASE ((void *)0x16200000)
+#define GSBI4_BASE ((void *)0x16300000)
+#define GSBI5_BASE ((void *)0x1A200000)
+#define GSBI6_BASE ((void *)0x16500000)
+#define GSBI7_BASE ((void *)0x16600000)
+
+#define GSBI1_CTL_REG (GSBI1_BASE + (0x0))
+#define GSBI2_CTL_REG (GSBI2_BASE + (0x0))
+#define GSBI3_CTL_REG (GSBI3_BASE + (0x0))
+#define GSBI4_CTL_REG (GSBI4_BASE + (0x0))
+#define GSBI5_CTL_REG (GSBI5_BASE + (0x0))
+#define GSBI6_CTL_REG (GSBI6_BASE + (0x0))
+#define GSBI7_CTL_REG (GSBI7_BASE + (0x0))
+
+#define GSBI_QUP1_BASE (GSBI1_BASE + 0x20000)
+#define GSBI_QUP2_BASE (GSBI2_BASE + 0x20000)
+#define GSBI_QUP3_BASE (GSBI3_BASE + 0x80000)
+#define GSBI_QUP4_BASE (GSBI4_BASE + 0x80000)
+#define GSBI_QUP5_BASE (GSBI5_BASE + 0x80000)
+#define GSBI_QUP6_BASE (GSBI6_BASE + 0x80000)
+#define GSBI_QUP7_BASE (GSBI7_BASE + 0x80000)
+
+#define GSBI_CTL_PROTO_I2C 2
+#define GSBI_CTL_PROTO_CODE_SFT 4
+#define GSBI_CTL_PROTO_CODE_MSK 0x7
+#define GSBI_HCLK_CTL_GATE_ENA 6
+#define GSBI_HCLK_CTL_BRANCH_ENA 4
+#define GSBI_QUP_APPS_M_SHFT 16
+#define GSBI_QUP_APPS_M_MASK 0xFF
+#define GSBI_QUP_APPS_D_SHFT 0
+#define GSBI_QUP_APPS_D_MASK 0xFF
+#define GSBI_QUP_APPS_N_SHFT 16
+#define GSBI_QUP_APPS_N_MASK 0xFF
+#define GSBI_QUP_APPS_ROOT_ENA_SFT 11
+#define GSBI_QUP_APPS_BRANCH_ENA_SFT 9
+#define GSBI_QUP_APPS_MNCTR_EN_SFT 8
+#define GSBI_QUP_APPS_MNCTR_MODE_MSK 0x3
+#define GSBI_QUP_APPS_MNCTR_MODE_SFT 5
+#define GSBI_QUP_APPS_PRE_DIV_MSK 0x3
+#define GSBI_QUP_APPS_PRE_DIV_SFT 3
+#define GSBI_QUP_APPS_SRC_SEL_MSK 0x7
+
+
+#define GSBI_QUP_APSS_MD_REG(gsbi_n) ((MSM_CLK_CTL_BASE + 0x29c8) + \
+ (32*(gsbi_n-1)))
+#define GSBI_QUP_APSS_NS_REG(gsbi_n) ((MSM_CLK_CTL_BASE + 0x29cc) + \
+ (32*(gsbi_n-1)))
+#define GSBI_HCLK_CTL(n) ((MSM_CLK_CTL_BASE + 0x29C0) + \
+ (32*(n-1)))
#endif // __SOC_QUALCOMM_IPQ806X_IOMAP_H_
diff --git a/src/soc/qualcomm/ipq806x/include/soc/qup.h b/src/soc/qualcomm/ipq806x/include/soc/qup.h
index 8f6f6bcca9..a12f6c5f86 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/qup.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/qup.h
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -143,6 +143,7 @@ typedef struct {
unsigned clk_frequency;
unsigned src_frequency;
qup_mode_t mode;
+ unsigned initialized;
} qup_config_t;
typedef struct {
diff --git a/src/soc/qualcomm/ipq806x/include/soc/spi.h b/src/soc/qualcomm/ipq806x/include/soc/spi.h
index f7dda07a51..6d816daf5e 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/spi.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/spi.h
@@ -7,22 +7,19 @@
#define _IPQ806X_SPI_H_
#include <spi_flash.h>
+#include <soc/iomap.h>
-#define QUP5_BASE 0x1a280000
-#define QUP6_BASE 0x16580000
-#define QUP7_BASE 0x16680000
-
-#define GSBI5_BASE 0x1a200000
-#define GSBI6_BASE 0x16500000
-#define GSBI7_BASE 0x16600000
+#define QUP5_BASE ((uint32_t)GSBI_QUP5_BASE)
+#define QUP6_BASE ((uint32_t)GSBI_QUP6_BASE)
+#define QUP7_BASE ((uint32_t)GSBI_QUP7_BASE)
#define GSBI5_QUP5_REG_BASE (QUP5_BASE + 0x00000000)
#define GSBI6_QUP6_REG_BASE (QUP6_BASE + 0x00000000)
#define GSBI7_QUP7_REG_BASE (QUP7_BASE + 0x00000000)
-#define GSBI5_REG_BASE (GSBI5_BASE + 0x00000000)
-#define GSBI6_REG_BASE (GSBI6_BASE + 0x00000000)
-#define GSBI7_REG_BASE (GSBI7_BASE + 0x00000000)
+#define GSBI5_REG_BASE ((uint32_t)(GSBI5_BASE + 0x00000000))
+#define GSBI6_REG_BASE ((uint32_t)(GSBI6_BASE + 0x00000000))
+#define GSBI7_REG_BASE ((uint32_t)(GSBI7_BASE + 0x00000000))
#define BOOT_SPI_PORT5_BASE QUP5_BASE
#define BOOT_SPI_PORT6_BASE QUP6_BASE
diff --git a/src/soc/qualcomm/ipq806x/qup.c b/src/soc/qualcomm/ipq806x/qup.c
index 0ae3990183..72ba724e8b 100644
--- a/src/soc/qualcomm/ipq806x/qup.c
+++ b/src/soc/qualcomm/ipq806x/qup.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,13 +38,13 @@
//TODO: refactor the following array to iomap driver.
static unsigned gsbi_qup_base[] = {
- GSBI_QUP1_BASE,
- GSBI_QUP2_BASE,
- GSBI_QUP3_BASE,
- GSBI_QUP4_BASE,
- GSBI_QUP5_BASE,
- GSBI_QUP6_BASE,
- GSBI_QUP7_BASE,
+ (unsigned)GSBI_QUP1_BASE,
+ (unsigned)GSBI_QUP2_BASE,
+ (unsigned)GSBI_QUP3_BASE,
+ (unsigned)GSBI_QUP4_BASE,
+ (unsigned)GSBI_QUP5_BASE,
+ (unsigned)GSBI_QUP6_BASE,
+ (unsigned)GSBI_QUP7_BASE,
};
#define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))