diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/qualcomm/ipq806x/gsbi.c | 116 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/i2c.c | 47 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/soc/iomap.h | 72 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/soc/qup.h | 3 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/soc/spi.h | 17 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/qup.c | 16 |
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))) |