ipq806x: extend GSBI driver to support i2c on any GSBI block

The GSBI driver is extended to be able to program the CTRL reg for any given
GSBI block. The NS and MD registers programming is made more readable by
programming the M, N, D and other bits of the registers individually.
Defined configure structs for each QUP block to be able to track the init
status for each qup.
Configured GPIO8 and GPIO9 for I2C fuction.

BRANCH=chromeos-2013.04
BUG=chrome-os-partner:36722
TEST=Booted up storm P0.2, verified that the TPM on GSBI1 still works.

Change-Id: I17906beedef5c80267cf114892080b121902210a
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 07bc79211770decc1070c3a88874a4e452b8f5bc
Original-Change-Id: I841d0d419f7339f5e5cb3385da98786eb18252ad
Original-Signed-off-by: Sourabh Banerjee <sbanerje@codeaurora.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/250763
Original-Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Trybot-Ready: Vadim Bendebury <vbendeb@chromium.org>
Original-Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>
Original-Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: http://review.coreboot.org/9759
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Sourabh Banerjee 2015-02-19 16:43:26 +05:30 committed by Patrick Georgi
parent 3cfb6a066b
commit 8920865332
7 changed files with 183 additions and 96 deletions

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the depthcharge project. * This file is part of the depthcharge 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -36,6 +36,12 @@
int gsbi_init_board(gsbi_id_t gsbi_id) int gsbi_init_board(gsbi_id_t gsbi_id)
{ {
switch (gsbi_id) { switch (gsbi_id) {
case GSBI_ID_7:
gpio_tlmm_config_set(8, GPIO_FUNC_I2C,
GPIO_NO_PULL, GPIO_2MA, 1);
gpio_tlmm_config_set(9, GPIO_FUNC_I2C,
GPIO_NO_PULL, GPIO_2MA, 1);
break;
case GSBI_ID_4: case GSBI_ID_4:
/* Configure GPIOs 13 - SCL, 12 - SDA, 2mA gpio_en */ /* Configure GPIOs 13 - SCL, 12 - SDA, 2mA gpio_en */
gpio_tlmm_config_set(12, GPIO_FUNC_I2C, gpio_tlmm_config_set(12, GPIO_FUNC_I2C,

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the coreboot project. * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -28,68 +28,78 @@
*/ */
#include <arch/io.h> #include <arch/io.h>
#include <soc/iomap.h>
#include <soc/gsbi.h> #include <soc/gsbi.h>
#include <soc/gpio.h> #include <console/console.h>
//TODO: To be implemented as part of the iomap. static inline void *gsbi_ctl_reg_addr(gsbi_id_t gsbi_id)
static int gsbi_base[] = { {
0x12440000, /*GSBI1*/ switch (gsbi_id) {
0x12480000, /*GSBI2*/ case GSBI_ID_1:
0x16200000, /*GSBI3*/ return GSBI1_CTL_REG;
0x16300000, /*GSBI4*/ case GSBI_ID_2:
0x1A200000, /*GSBI5*/ return GSBI2_CTL_REG;
0x16500000, /*GSBI6*/ case GSBI_ID_3:
0x16600000 /*GSBI7*/ return GSBI3_CTL_REG;
}; case GSBI_ID_4:
return GSBI4_CTL_REG;
#define QUP_APPS_ADDR(N, os) ((void *)((0x009029C8+os)+(32*(N-1)))) case GSBI_ID_5:
#define GSBI_HCLK_CTL(N) ((void *)(0x009029C0 + (32*(N-1)))) return GSBI5_CTL_REG;
#define GSBI_RESET(N) ((void *)(0x009029DC + (32*(N-1)))) case GSBI_ID_6:
#define GSBI_CTL(N) ((void *)(gsbi_base[N-1])) return GSBI6_CTL_REG;
case GSBI_ID_7:
#define GSBI_APPS_MD_OFFSET 0x0 return GSBI7_CTL_REG;
#define GSBI_APPS_NS_OFFSET 0x4 default:
#define GSBI_APPS_MAX_OFFSET 0xff 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) gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol)
{ {
unsigned i = 0; unsigned reg_val;
unsigned qup_apps_ini[] = { unsigned m = 1;
GSBI_APPS_NS_OFFSET, 0xf80b43, unsigned n = 4;
GSBI_APPS_NS_OFFSET, 0xfc095b, unsigned pre_div = 4;
GSBI_APPS_NS_OFFSET, 0xfc015b, unsigned src = 3;
GSBI_APPS_NS_OFFSET, 0xfc005b, unsigned mnctr_mode = 2;
GSBI_APPS_NS_OFFSET, 0xA05, void *gsbi_ctl = gsbi_ctl_reg_addr(gsbi_id);
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
};
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)) { if (gsbi_init_board(gsbi_id))
ret = GSBI_UNSUPPORTED; return GSBI_UNSUPPORTED;
goto bail_out;
} 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));
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));
reg_val |= (1 << GSBI_QUP_APPS_BRANCH_ENA_SFT);
writel(reg_val, GSBI_QUP_APSS_NS_REG(gsbi_id));
/*Select i2c protocol*/ /*Select i2c protocol*/
writel((2 << 4), GSBI_CTL(gsbi_id)); writel(((GSBI_CTL_PROTO_I2C & GSBI_CTL_PROTO_CODE_MSK) <<
GSBI_CTL_PROTO_CODE_SFT), gsbi_ctl);
//TODO: Make use of clock API when available instead of the hardcoding. return GSBI_SUCCESS;
/* 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]));
writel(((1 << 6)|(1 << 4)), GSBI_HCLK_CTL(gsbi_id));
bail_out:
return ret;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the coreboot project. * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -37,11 +37,28 @@
#include <soc/gsbi.h> #include <soc/gsbi.h>
#include <soc/qup.h> #include <soc/qup.h>
static const qup_config_t gsbi4_qup_config = { static qup_config_t gsbi1_qup_config = {
QUP_MINICORE_I2C_MASTER, QUP_MINICORE_I2C_MASTER,
100000, 100000,
24000000, 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, 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 int i2c_init(unsigned bus)
{ {
static uint8_t initialized = 0;
unsigned gsbi_id = bus; unsigned gsbi_id = bus;
qup_config_t *qup_config;
if (initialized) 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 (qup_config->initialized)
return 0; return 0;
if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) { if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) {
@ -95,7 +128,7 @@ static int i2c_init(unsigned bus)
return 1; 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"); printk(BIOS_ERR, "failed to initialize qup\n");
return 1; return 1;
} }
@ -105,7 +138,7 @@ static int i2c_init(unsigned bus)
return 1; return 1;
} }
initialized = 1; qup_config->initialized = 1;
return 0; return 0;
} }

View File

@ -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. * Copyright (c) 2008, Google Inc.
* All rights reserved. * All rights reserved.
@ -49,13 +49,13 @@
#define clrsetbits_le32_i(addr, clear, set) \ #define clrsetbits_le32_i(addr, clear, set) \
clrsetbits_le32(((void *)(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_GPT_BASE (MSM_TMR_BASE + 0x04)
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) #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 DGT_REG(off) (MSM_DGT_BASE + (off))
#define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040) #define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040)
@ -88,7 +88,7 @@
#define RPM_SIGNAL_ENTRY ((void *)0x47C24) #define RPM_SIGNAL_ENTRY ((void *)0x47C24)
#define RPM_FW_MAGIC_NUM 0x4D505242 #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_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
#define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4) #define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4)
@ -100,10 +100,7 @@
#define USB_HOST1_DWC3_BASE 0x1100C100 #define USB_HOST1_DWC3_BASE 0x1100C100
#define USB_HOST1_PHY_BASE 0x110F8800 #define USB_HOST1_PHY_BASE 0x110F8800
#define GSBI_1 1
#define GSBI_2 2
#define GSBI_4 4 #define GSBI_4 4
#define GSBI_2 2
#define UART1_DM_BASE 0x12450000 #define UART1_DM_BASE 0x12450000
#define UART_GSBI1_BASE 0x12440000 #define UART_GSBI1_BASE 0x12440000
#define UART2_DM_BASE 0x12490000 #define UART2_DM_BASE 0x12490000
@ -114,12 +111,55 @@
#define UART2_DM_BASE 0x12490000 #define UART2_DM_BASE 0x12490000
#define UART_GSBI2_BASE 0x12480000 #define UART_GSBI2_BASE 0x12480000
#define GSBI_QUP1_BASE 0x12460000 #define GSBI1_BASE ((void *)0x12440000)
#define GSBI_QUP2_BASE 0x124A0000 #define GSBI2_BASE ((void *)0x12480000)
#define GSBI_QUP3_BASE 0x16280000 #define GSBI3_BASE ((void *)0x16200000)
#define GSBI_QUP4_BASE 0x16380000 #define GSBI4_BASE ((void *)0x16300000)
#define GSBI_QUP5_BASE 0x1A280000 #define GSBI5_BASE ((void *)0x1A200000)
#define GSBI_QUP6_BASE 0x16580000 #define GSBI6_BASE ((void *)0x16500000)
#define GSBI_QUP7_BASE 0x16680000 #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_ #endif // __SOC_QUALCOMM_IPQ806X_IOMAP_H_

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the coreboot project. * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -143,6 +143,7 @@ typedef struct {
unsigned clk_frequency; unsigned clk_frequency;
unsigned src_frequency; unsigned src_frequency;
qup_mode_t mode; qup_mode_t mode;
unsigned initialized;
} qup_config_t; } qup_config_t;
typedef struct { typedef struct {

View File

@ -7,22 +7,19 @@
#define _IPQ806X_SPI_H_ #define _IPQ806X_SPI_H_
#include <spi_flash.h> #include <spi_flash.h>
#include <soc/iomap.h>
#define QUP5_BASE 0x1a280000 #define QUP5_BASE ((uint32_t)GSBI_QUP5_BASE)
#define QUP6_BASE 0x16580000 #define QUP6_BASE ((uint32_t)GSBI_QUP6_BASE)
#define QUP7_BASE 0x16680000 #define QUP7_BASE ((uint32_t)GSBI_QUP7_BASE)
#define GSBI5_BASE 0x1a200000
#define GSBI6_BASE 0x16500000
#define GSBI7_BASE 0x16600000
#define GSBI5_QUP5_REG_BASE (QUP5_BASE + 0x00000000) #define GSBI5_QUP5_REG_BASE (QUP5_BASE + 0x00000000)
#define GSBI6_QUP6_REG_BASE (QUP6_BASE + 0x00000000) #define GSBI6_QUP6_REG_BASE (QUP6_BASE + 0x00000000)
#define GSBI7_QUP7_REG_BASE (QUP7_BASE + 0x00000000) #define GSBI7_QUP7_REG_BASE (QUP7_BASE + 0x00000000)
#define GSBI5_REG_BASE (GSBI5_BASE + 0x00000000) #define GSBI5_REG_BASE ((uint32_t)(GSBI5_BASE + 0x00000000))
#define GSBI6_REG_BASE (GSBI6_BASE + 0x00000000) #define GSBI6_REG_BASE ((uint32_t)(GSBI6_BASE + 0x00000000))
#define GSBI7_REG_BASE (GSBI7_BASE + 0x00000000) #define GSBI7_REG_BASE ((uint32_t)(GSBI7_BASE + 0x00000000))
#define BOOT_SPI_PORT5_BASE QUP5_BASE #define BOOT_SPI_PORT5_BASE QUP5_BASE
#define BOOT_SPI_PORT6_BASE QUP6_BASE #define BOOT_SPI_PORT6_BASE QUP6_BASE

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the coreboot project. * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -38,13 +38,13 @@
//TODO: refactor the following array to iomap driver. //TODO: refactor the following array to iomap driver.
static unsigned gsbi_qup_base[] = { static unsigned gsbi_qup_base[] = {
GSBI_QUP1_BASE, (unsigned)GSBI_QUP1_BASE,
GSBI_QUP2_BASE, (unsigned)GSBI_QUP2_BASE,
GSBI_QUP3_BASE, (unsigned)GSBI_QUP3_BASE,
GSBI_QUP4_BASE, (unsigned)GSBI_QUP4_BASE,
GSBI_QUP5_BASE, (unsigned)GSBI_QUP5_BASE,
GSBI_QUP6_BASE, (unsigned)GSBI_QUP6_BASE,
GSBI_QUP7_BASE, (unsigned)GSBI_QUP7_BASE,
}; };
#define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg))) #define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))