soc/qualcomm/ipq40xx: Add support for BLSP QUP I2C
Able to talk to the TPM device and the commands seem to succeed. BUG=chrome-os-partner:49249 chrome-os-partner:49250 TEST=All commands to the TPM succeed BRANCH=none Original-Commit-Id: c13900108f524c8422c38dee88469c8bfe24d0bd Original-Change-Id: Ie8c3c1ab1290cd8d7e6ddd1ae22f765c7be81019 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Reviewed-on: https://chromium-review.googlesource.com/333314 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> squashed: soc/qualcomm/ipq40xx: Add support for BLSP QUP SPI - Enable BLSP SPI driver for ipq40xx - supports only FIFO mode BUG=chrome-os-partner:49249 TEST=None. Initial code not sure if it will even compile BRANCH=none Original-Commit-Id: 0714025975854dd048d35fe602824ead4c7d94e9 Original-Change-Id: If809b0fdf7d6c9405db6fd3747a3774c00ea9870 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Reviewed-on: https://chromium-review.googlesource.com/333303 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Change-Id: Ia518af5bfc782b08a0883ac93224d476d07e2426 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: https://review.coreboot.org/14677 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
3939acaa77
commit
2596764f34
|
@ -56,7 +56,7 @@ config DRAM_SIZE_MB
|
|||
|
||||
config DRIVER_TPM_I2C_BUS
|
||||
hex
|
||||
default 0x1
|
||||
default 0x2
|
||||
|
||||
config DRIVER_TPM_I2C_ADDR
|
||||
hex
|
||||
|
|
|
@ -21,7 +21,7 @@ bootblock-y += reset.c
|
|||
verstage-y += boardid.c
|
||||
verstage-y += cdp.c
|
||||
verstage-y += chromeos.c
|
||||
verstage-y += gsbi.c
|
||||
verstage-y += blsp.c
|
||||
verstage-y += memlayout.ld
|
||||
verstage-y += reset.c
|
||||
|
||||
|
|
|
@ -27,34 +27,47 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <gpio.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <soc/qup.h>
|
||||
|
||||
#define GPIO_FUNC_I2C 0x1
|
||||
#define IPQ40XX_I2C0_PINGROUP_1 1
|
||||
#define IPQ40XX_I2C0_PINGROUP_2 (!IPQ40XX_I2C0_PINGROUP_1)
|
||||
|
||||
int gsbi_init_board(gsbi_id_t gsbi_id)
|
||||
#if IPQ40XX_I2C0_PINGROUP_1
|
||||
|
||||
#define SCL_GPIO 20
|
||||
#define SDA_GPIO 21
|
||||
#define GPIO_FUNC_SCL 0x1
|
||||
#define GPIO_FUNC_SDA 0x1
|
||||
|
||||
#elif IPQ40XX_I2C0_PINGROUP_2
|
||||
|
||||
#define SCL_GPIO 58
|
||||
#define SDA_GPIO 59
|
||||
#define GPIO_FUNC_SCL 0x3
|
||||
#define GPIO_FUNC_SDA 0x2
|
||||
|
||||
#else
|
||||
|
||||
#warning "TPM: I2C pingroup not specified"
|
||||
|
||||
#endif
|
||||
|
||||
int blsp_i2c_init_board(blsp_qup_id_t 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:
|
||||
/* Configure GPIOs 13 - SCL, 12 - SDA, 2mA gpio_en */
|
||||
gpio_tlmm_config_set(12, GPIO_FUNC_I2C,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
gpio_tlmm_config_set(13, GPIO_FUNC_I2C,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
break;
|
||||
case GSBI_ID_1:
|
||||
/* Configure GPIOs 54 - SCL, 53 - SDA, 2mA gpio_en */
|
||||
gpio_tlmm_config_set(54, GPIO_FUNC_I2C,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
gpio_tlmm_config_set(53, GPIO_FUNC_I2C,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
switch (id) {
|
||||
case BLSP_QUP_ID_0:
|
||||
case BLSP_QUP_ID_1:
|
||||
case BLSP_QUP_ID_2:
|
||||
case BLSP_QUP_ID_3:
|
||||
#if defined(IPQ40XX_I2C0_PINGROUP_1) || defined(IPQ40XX_I2C0_PINGROUP_2)
|
||||
gpio_tlmm_config_set(SDA_GPIO, GPIO_FUNC_SDA,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
gpio_tlmm_config_set(SCL_GPIO, GPIO_FUNC_SCL,
|
||||
GPIO_NO_PULL, GPIO_2MA, 1);
|
||||
#endif /* Pin Group 1 or 2 */
|
||||
break;
|
||||
default:
|
||||
return 1;
|
|
@ -20,7 +20,7 @@
|
|||
#include <drivers/i2c/ww_ring/ww_ring.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/cdp.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <soc/clock.h>
|
||||
#include <soc/soc_services.h>
|
||||
#include <soc/usb.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <symbols.h>
|
||||
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
@ -37,7 +38,7 @@ static void setup_usb(void)
|
|||
}
|
||||
|
||||
#define TPM_RESET_GPIO 19
|
||||
static void ipq_setup_tpm(void)
|
||||
void ipq_setup_tpm(void)
|
||||
{
|
||||
#ifdef CONFIG_I2C_TPM
|
||||
gpio_tlmm_config_set(TPM_RESET_GPIO, FUNC_SEL_GPIO,
|
||||
|
|
|
@ -24,7 +24,7 @@ bootblock-$(CONFIG_DRIVERS_UART) += uart.c
|
|||
|
||||
verstage-y += clock.c
|
||||
verstage-y += gpio.c
|
||||
libverstage-y += gsbi.c
|
||||
libverstage-y += blsp.c
|
||||
libverstage-y += i2c.c
|
||||
libverstage-y += qup.c
|
||||
libverstage-y += spi.c
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 - 2016 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 are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <soc/blsp.h>
|
||||
#include <soc/clock.h>
|
||||
|
||||
blsp_return_t blsp_i2c_init(blsp_qup_id_t id)
|
||||
{
|
||||
void *base = blsp_qup_base(id);
|
||||
|
||||
if (!base)
|
||||
return BLSP_ID_ERROR;
|
||||
|
||||
if (blsp_i2c_clock_config(id) != 0)
|
||||
return BLSP_ID_ERROR;
|
||||
|
||||
if (blsp_i2c_init_board(id))
|
||||
return BLSP_UNSUPPORTED;
|
||||
|
||||
/* Configure Mini core to I2C core */
|
||||
clrsetbits_le32(base, BLSP_MINI_CORE_MASK, BLSP_MINI_CORE_I2C);
|
||||
|
||||
return BLSP_SUCCESS;
|
||||
}
|
|
@ -28,8 +28,10 @@
|
|||
*/
|
||||
|
||||
#include <delay.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <types.h>
|
||||
#include <console/console.h>
|
||||
|
||||
#define CLOCK_UPDATE_DELAY 1000
|
||||
|
||||
|
@ -67,6 +69,7 @@ void uart_clock_config(unsigned int blsp_uart, unsigned int m,
|
|||
udelay(1);
|
||||
}
|
||||
|
||||
/* Please refer to the comments in blsp_i2c_clock_config() */
|
||||
setbits_le32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP);
|
||||
}
|
||||
|
||||
|
@ -110,3 +113,67 @@ void usb_clock_config(void)
|
|||
udelay(5);
|
||||
write32(USB30_RESET, 0); /* deassert all USB resets again */
|
||||
}
|
||||
|
||||
int blsp_i2c_clock_config(blsp_qup_id_t id)
|
||||
{
|
||||
int i;
|
||||
const int max_tries = 200;
|
||||
struct { void *cbcr, *cmd, *cfg; } clk[] = {
|
||||
{
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CBCR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
|
||||
},
|
||||
{
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CBCR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
|
||||
},
|
||||
{
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CBCR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
|
||||
},
|
||||
{
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CBCR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
|
||||
GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* uart_clock_config() does this. Ideally, setting these bits once
|
||||
* should suffice. However, if for some reason the order of invocation
|
||||
* of uart_clock_config and blsp_i2c_clock_config gets changed or
|
||||
* something, then one of the functions might not work. Hence, to steer
|
||||
* clear of such dependencies, just replicating the setting of this
|
||||
* bits.
|
||||
*
|
||||
* Moreover, they are read-modify-write and HW wise repeated setting of
|
||||
* the same bits is harmless. Hence repeating them here should be ok.
|
||||
* This will ensure root and branch clocks remain on.
|
||||
*/
|
||||
setbits_le32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP);
|
||||
|
||||
/* Src Sel 1 (fepll 200), Src Div 10.5 */
|
||||
write32(clk[id].cfg, (1u << 8) | (20u << 0));
|
||||
|
||||
write32(clk[id].cmd, BIT(0)); /* Update En */
|
||||
|
||||
for (i = 0; i < max_tries; i++) {
|
||||
if (read32(clk[id].cmd) & BIT(0)) {
|
||||
udelay(5);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == max_tries) {
|
||||
printk(BIOS_ERR, "%s failed\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
write32(clk[id].cbcr, BIT(0)); /* Enable */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* 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 are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <console/console.h>
|
||||
|
||||
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 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);
|
||||
|
||||
if (!gsbi_ctl)
|
||||
return GSBI_ID_ERROR;
|
||||
|
||||
write32(GSBI_HCLK_CTL(gsbi_id),
|
||||
(1 << GSBI_HCLK_CTL_GATE_ENA) |
|
||||
(1 << GSBI_HCLK_CTL_BRANCH_ENA));
|
||||
|
||||
if (gsbi_init_board(gsbi_id))
|
||||
return GSBI_UNSUPPORTED;
|
||||
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), 0);
|
||||
write32(GSBI_QUP_APSS_MD_REG(gsbi_id), 0);
|
||||
|
||||
reg_val = ((m & GSBI_QUP_APPS_M_MASK) << GSBI_QUP_APPS_M_SHFT) |
|
||||
((~n & GSBI_QUP_APPS_D_MASK) << GSBI_QUP_APPS_D_SHFT);
|
||||
write32(GSBI_QUP_APSS_MD_REG(gsbi_id), reg_val);
|
||||
|
||||
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);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
reg_val |= (1 << GSBI_QUP_APPS_ROOT_ENA_SFT) |
|
||||
(1 << GSBI_QUP_APPS_MNCTR_EN_SFT);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
reg_val |= (1 << GSBI_QUP_APPS_BRANCH_ENA_SFT);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
/*Select i2c protocol*/
|
||||
write32(gsbi_ctl,
|
||||
((GSBI_CTL_PROTO_I2C & GSBI_CTL_PROTO_CODE_MSK)
|
||||
<< GSBI_CTL_PROTO_CODE_SFT));
|
||||
|
||||
return GSBI_SUCCESS;
|
||||
}
|
|
@ -36,29 +36,38 @@
|
|||
#include <device/i2c.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <soc/qup.h>
|
||||
#include <soc/gpio.h>
|
||||
|
||||
static qup_config_t gsbi1_qup_config = {
|
||||
static qup_config_t blsp1_qup0_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
19050000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static qup_config_t gsbi4_qup_config = {
|
||||
static qup_config_t blsp1_qup1_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
19050000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static qup_config_t gsbi7_qup_config = {
|
||||
static qup_config_t blsp1_qup2_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
19050000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static qup_config_t blsp1_qup3_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
19050000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
@ -101,41 +110,43 @@ static int i2c_write(uint32_t gsbi_id, uint8_t slave,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_init(unsigned bus)
|
||||
static int i2c_init(blsp_qup_id_t id)
|
||||
{
|
||||
unsigned gsbi_id = bus;
|
||||
qup_config_t *qup_config;
|
||||
|
||||
switch (gsbi_id) {
|
||||
case GSBI_ID_1:
|
||||
qup_config = &gsbi1_qup_config;
|
||||
switch (id) {
|
||||
case BLSP_QUP_ID_0:
|
||||
qup_config = &blsp1_qup0_config;
|
||||
break;
|
||||
case GSBI_ID_4:
|
||||
qup_config = &gsbi4_qup_config;
|
||||
case BLSP_QUP_ID_1:
|
||||
qup_config = &blsp1_qup1_config;
|
||||
break;
|
||||
case GSBI_ID_7:
|
||||
qup_config = &gsbi7_qup_config;
|
||||
case BLSP_QUP_ID_2:
|
||||
qup_config = &blsp1_qup2_config;
|
||||
break;
|
||||
case BLSP_QUP_ID_3:
|
||||
qup_config = &blsp1_qup3_config;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "QUP configuration not defind for GSBI%d.\n",
|
||||
gsbi_id);
|
||||
printk(BIOS_ERR, "QUP configuration not defined for BLSP%d.\n",
|
||||
id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_config->initialized)
|
||||
return 0;
|
||||
|
||||
if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) {
|
||||
printk(BIOS_ERR, "failed to initialize gsbi\n");
|
||||
if (blsp_i2c_init(id)) {
|
||||
printk(BIOS_ERR, "failed to initialize blsp\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_init(gsbi_id, qup_config)) {
|
||||
if (qup_init(id, qup_config)) {
|
||||
printk(BIOS_ERR, "failed to initialize qup\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_reset_i2c_master_status(gsbi_id)) {
|
||||
if (qup_reset_i2c_master_status(id)) {
|
||||
printk(BIOS_ERR, "failed to reset i2c master status\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -28,48 +28,33 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef __GSBI_H_
|
||||
#define __GSBI_H_
|
||||
|
||||
/* GSBI Registers */
|
||||
#define GSBI_CTRL_REG(base) ((base) + 0x0)
|
||||
|
||||
#define GSBI_CTRL_REG_PROTOCOL_CODE_S 4
|
||||
#define GSBI_PROTOCOL_CODE_I2C 0x2
|
||||
#define GSBI_PROTOCOL_CODE_SPI 0x3
|
||||
#define GSBI_PROTOCOL_CODE_UART_FLOW 0x4
|
||||
#define GSBI_PROTOCOL_CODE_I2C_UART 0x6
|
||||
|
||||
#define GSBI_HCLK_CTL_S 4
|
||||
#define GSBI_HCLK_CTL_CLK_ENA 0x1
|
||||
#ifndef __BLSP_H_
|
||||
#define __BLSP_H_
|
||||
|
||||
typedef enum {
|
||||
GSBI_ID_1 = 1,
|
||||
GSBI_ID_2,
|
||||
GSBI_ID_3,
|
||||
GSBI_ID_4,
|
||||
GSBI_ID_5,
|
||||
GSBI_ID_6,
|
||||
GSBI_ID_7,
|
||||
} gsbi_id_t;
|
||||
BLSP_QUP_ID_0,
|
||||
BLSP_QUP_ID_1,
|
||||
BLSP_QUP_ID_2,
|
||||
BLSP_QUP_ID_3,
|
||||
} blsp_qup_id_t;
|
||||
|
||||
typedef enum {
|
||||
GSBI_SUCCESS = 0,
|
||||
GSBI_ID_ERROR,
|
||||
GSBI_ERROR,
|
||||
GSBI_UNSUPPORTED
|
||||
} gsbi_return_t;
|
||||
BLSP_SUCCESS = 0,
|
||||
BLSP_ID_ERROR,
|
||||
BLSP_ERROR,
|
||||
BLSP_UNSUPPORTED
|
||||
} blsp_return_t;
|
||||
|
||||
typedef enum {
|
||||
GSBI_PROTO_I2C_UIM = 1,
|
||||
GSBI_PROTO_I2C_ONLY,
|
||||
GSBI_PROTO_SPI_ONLY,
|
||||
GSBI_PROTO_UART_FLOW_CTL,
|
||||
GSBI_PROTO_UIM,
|
||||
GSBI_PROTO_I2C_UART,
|
||||
} gsbi_protocol_t;
|
||||
BLSP_PROTO_I2C_UIM = 1,
|
||||
BLSP_PROTO_I2C_ONLY,
|
||||
BLSP_PROTO_SPI_ONLY,
|
||||
BLSP_PROTO_UART_FLOW_CTL,
|
||||
BLSP_PROTO_UIM,
|
||||
BLSP_PROTO_I2C_UART,
|
||||
} blsp_protocol_t;
|
||||
|
||||
gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol);
|
||||
int gsbi_init_board(gsbi_id_t gsbi_id);
|
||||
blsp_return_t blsp_i2c_init(blsp_qup_id_t id);
|
||||
int blsp_i2c_init_board(blsp_qup_id_t id);
|
||||
|
||||
#endif
|
|
@ -210,5 +210,7 @@ void uart_clock_config(unsigned int blsp_uart, unsigned int m, unsigned int n,
|
|||
void nand_clock_config(void);
|
||||
void usb_clock_config(void);
|
||||
int audio_clock_config(unsigned frequency);
|
||||
int blsp_i2c_clock_config(blsp_qup_id_t id);
|
||||
|
||||
|
||||
#endif /* __PLATFORM_IPQ40XX_CLOCK_H_ */
|
||||
|
|
|
@ -113,4 +113,7 @@ static inline void gpio_tlmm_config(unsigned int gpio, unsigned int func,
|
|||
{
|
||||
gpio_tlmm_config_set(gpio, func, pull, drvstr, enable);
|
||||
}
|
||||
|
||||
void ipq_setup_tpm(void);
|
||||
|
||||
#endif // __SOC_QUALCOMM_IPQ40XX_GPIO_H_
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <arch/io.h>
|
||||
#include <soc/cdp.h>
|
||||
#include <soc/blsp.h>
|
||||
|
||||
/* Typecast to allow integers being passed as address
|
||||
This needs to be included because vendor code is not compliant with our
|
||||
|
@ -71,6 +72,13 @@
|
|||
#define CRYPTO_AXI (1 << 1)
|
||||
#define CRYPTO_AHB (1 << 0)
|
||||
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CBCR (MSM_CLK_CTL_BASE + 0x2008)
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR (MSM_CLK_CTL_BASE + 0x200c)
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR (MSM_CLK_CTL_BASE + 0x2010)
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CBCR (MSM_CLK_CTL_BASE + 0x3010)
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CMD_RCGR (MSM_CLK_CTL_BASE + 0x3000)
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CFG_RCGR (MSM_CLK_CTL_BASE + 0x3004)
|
||||
|
||||
#define GCNT_GLOBAL_CTRL_BASE ((void *)0x004a0000u)
|
||||
#define GCNT_CNTCR (GCNT_GLOBAL_CTRL_BASE + 0x1000)
|
||||
#define GCNT_GLB_CNTCV_LO (GCNT_GLOBAL_CTRL_BASE + 0x1008)
|
||||
|
@ -117,55 +125,28 @@ enum {
|
|||
#define GCC_BLSP1_UART_APPS_D(x) (GCC_BLSP1_UART_APPS_N(x) + 4)
|
||||
#define GCC_BLSP1_UART_MISC(x) (GCC_BLSP1_UART_APPS_D(x) + 4)
|
||||
|
||||
#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 BLSP1_QUP0_BASE ((void *)0x078B5000)
|
||||
#define BLSP1_QUP1_BASE ((void *)0x078B6000)
|
||||
#define BLSP1_QUP2_BASE ((void *)0x078B7000)
|
||||
#define BLSP1_QUP3_BASE ((void *)0x078B8000)
|
||||
|
||||
#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))
|
||||
static inline void *blsp_qup_base(blsp_qup_id_t id)
|
||||
{
|
||||
switch (id) {
|
||||
case BLSP_QUP_ID_0: return BLSP1_QUP0_BASE;
|
||||
case BLSP_QUP_ID_1: return BLSP1_QUP1_BASE;
|
||||
case BLSP_QUP_ID_2: return BLSP1_QUP2_BASE;
|
||||
case BLSP_QUP_ID_3: return BLSP1_QUP3_BASE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#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 BLSP_MINI_CORE_SHIFT 8
|
||||
#define BLSP_MINI_CORE_I2C (0x2u << BLSP_MINI_CORE_SHIFT)
|
||||
#define BLSP_MINI_CORE_MASK (0xfu << BLSP_MINI_CORE_SHIFT)
|
||||
|
||||
#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 ETIMEDOUT -10
|
||||
#define EINVAL -11
|
||||
#define EIO -12
|
||||
|
||||
|
||||
#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_IPQ40XX_IOMAP_H_
|
||||
|
|
|
@ -32,40 +32,50 @@
|
|||
#ifndef __QUP_H__
|
||||
#define __QUP_H__
|
||||
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/blsp.h>
|
||||
|
||||
/* QUP block registers */
|
||||
#define QUP_CONFIG 0x0
|
||||
#define QUP_STATE 0x4
|
||||
#define QUP_IO_MODES 0x8
|
||||
#define QUP_SW_RESET 0xc
|
||||
#define QUP_TIME_OUT 0x10
|
||||
#define QUP_TIME_OUT_CURRENT 0x14
|
||||
#define QUP_OPERATIONAL 0x18
|
||||
#define QUP_ERROR_FLAGS 0x1c
|
||||
#define QUP_ERROR_FLAGS_EN 0x20
|
||||
#define QUP_TEST_CTRL 0x24
|
||||
#define QUP_CONFIG 0x000
|
||||
#define QUP_STATE 0x004
|
||||
#define QUP_IO_MODES 0x008
|
||||
#define QUP_SW_RESET 0x00C
|
||||
#define QUP_TRANSFER_CANCEL 0x014
|
||||
#define QUP_OPERATIONAL 0x018
|
||||
#define QUP_ERROR_FLAGS 0x01C
|
||||
#define QUP_ERROR_FLAGS_EN 0x020
|
||||
#define QUP_TEST_CTRL 0x024
|
||||
#define QUP_OPERATIONAL_MASK 0x028
|
||||
#define QUP_HW_VERSION 0x030
|
||||
#define QUP_MX_OUTPUT_COUNT 0x100
|
||||
#define QUP_MX_OUTPUT_CNT_CURRENT 0x104
|
||||
#define QUP_OUTPUT_DEBUG 0x108
|
||||
#define QUP_OUTPUT_FIFO_WORD_CNT 0x10c
|
||||
#define QUP_OUTPUT_FIFO_WORD_CNT 0x10C
|
||||
#define QUP_OUTPUT_FIFO 0x110
|
||||
#define QUP_OUTPUT_FIFO_SIZE 64 /* bytes */
|
||||
#define QUP_MX_WRITE_COUNT 0x150
|
||||
#define QUP_WRITE_CNT_CURRENT 0x154
|
||||
#define QUP_MX_WRITE_CNT_CURRENT 0x154
|
||||
#define QUP_MX_INPUT_COUNT 0x200
|
||||
#define QUP_READ_COUNT 0x208
|
||||
#define QUP_MX_READ_CNT_CURRENT 0x20c
|
||||
#define QUP_MX_INPUT_CNT_CURRENT 0x204
|
||||
#define QUP_MX_READ_COUNT 0x208
|
||||
#define QUP_MX_READ_CNT_CURRENT 0x20C
|
||||
#define QUP_INPUT_DEBUG 0x210
|
||||
#define QUP_INPUT_FIFO_WORD_CNT 0x214
|
||||
#define QUP_INPUT_FIFO 0x218
|
||||
#define QUP_INPUT_FIFO_SIZE 64 /* bytes */
|
||||
#define QUP_I2C_MASTER_CLK_CTL 0x400
|
||||
#define QUP_I2C_MASTER_STATUS 0x404
|
||||
#define QUP_I2C_MASTER_CONFIG 0x408
|
||||
#define QUP_I2C_MASTER_BUS_CLEAR 0x40C
|
||||
#define QUP_I2C_MASTER_LOCAL_ID 0x410
|
||||
#define QUP_I2C_MASTER_COMMAND 0x414
|
||||
|
||||
#define OUTPUT_FIFO_FULL (1<<6)
|
||||
#define INPUT_FIFO_NOT_EMPTY (1<<5)
|
||||
#define OUTPUT_FIFO_NOT_EMPTY (1<<4)
|
||||
#define INPUT_SERVICE_FLAG (1<<9)
|
||||
#define OUTPUT_SERVICE_FLAG (1<<8)
|
||||
#define QUP_UNPACK_EN (1<<14)
|
||||
#define QUP_PACK_EN (1<<15)
|
||||
#define QUP_OUTPUT_BIT_SHIFT_EN (1<<16)
|
||||
|
||||
#define QUP_MODE_MASK (0x03)
|
||||
|
@ -74,6 +84,8 @@
|
|||
|
||||
#define QUP_FS_DIVIDER_MASK (0xFF)
|
||||
|
||||
#define QUP_APP_CLK_ON_EN (1 << 12)
|
||||
#define QUP_CORE_CLK_ON_EN (1 << 13)
|
||||
#define QUP_MINI_CORE_PROTO_SHFT (8)
|
||||
#define QUP_MINI_CORE_PROTO_MASK (0x0F)
|
||||
|
||||
|
@ -170,50 +182,50 @@ typedef struct {
|
|||
} qup_data_t;
|
||||
|
||||
/*
|
||||
* Initialize GSBI QUP block for FIFO I2C transfers.
|
||||
* gsbi_id[IN]: GSBI for which QUP is to be initialized.
|
||||
* Initialize BLSP QUP block for FIFO I2C transfers.
|
||||
* id[IN]: BLSP for which QUP is to be initialized.
|
||||
* config_ptr[IN]: configurations parameters for the QUP.
|
||||
*
|
||||
* return: QUP_SUCCESS, if initialization succeeds.
|
||||
*/
|
||||
qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr);
|
||||
qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr);
|
||||
|
||||
/*
|
||||
* Set QUP state to run, pause, reset.
|
||||
* gsbi_id[IN]: GSBI block for which QUP state is to be set.
|
||||
* id[IN]: BLSP block for which QUP state is to be set.
|
||||
* state[IN]: New state to transition to.
|
||||
*
|
||||
* return: QUP_SUCCESS, if state transition succeeds.
|
||||
*/
|
||||
qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state);
|
||||
qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state);
|
||||
|
||||
/*
|
||||
* Reset the status bits set during an i2c transfer.
|
||||
* gsbi_id[IN]: GSBI block for which i2c status bits are to be cleared.
|
||||
* id[IN]: BLSP block for which i2c status bits are to be cleared.
|
||||
*
|
||||
* return: QUP_SUCCESS, if status bits are cleared successfully.
|
||||
*/
|
||||
qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id);
|
||||
qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id);
|
||||
|
||||
/*
|
||||
* Send data to the peripheral on the bus.
|
||||
* gsbi_id[IN]: GSBI block for which data is to be sent.
|
||||
* id[IN]: BLSP block for which data is to be sent.
|
||||
* p_tx_obj[IN]: Data to be sent to the slave on the bus.
|
||||
* stop_seq[IN]: When set to non-zero QUP engine sends i2c stop sequnce.
|
||||
*
|
||||
* return: QUP_SUCCESS, when data is sent successfully to the peripheral.
|
||||
*/
|
||||
qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq);
|
||||
|
||||
/*
|
||||
* Receive data from peripheral on the bus.
|
||||
* gsbi_id[IN]: GSBI block from which data is to be received.
|
||||
* id[IN]: BLSP block from which data is to be received.
|
||||
* p_tx_obj[IN]: length of data to be received, slave address.
|
||||
* [OUT]: buffer filled with data from slave.
|
||||
*
|
||||
* return: QUP_SUCCESS, when data is received successfully.
|
||||
*/
|
||||
qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj);
|
||||
qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_tx_obj);
|
||||
|
||||
#endif //__QUP_H__
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Register definitions for the IPQ GSBI Controller
|
||||
* Register definitions for the IPQ BLSP SPI Controller
|
||||
*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
|
@ -34,263 +34,152 @@
|
|||
|
||||
#include <spi_flash.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/qup.h>
|
||||
|
||||
#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 BLSP0_QUP_REG_BASE ((void *)0x78b5000u)
|
||||
#define BLSP1_QUP_REG_BASE ((void *)0x78b6000u)
|
||||
|
||||
#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 BLSP0_SPI_CONFIG_REG (BLSP0_QUP_REG_BASE + 0x00000300)
|
||||
#define BLSP1_SPI_CONFIG_REG (BLSP1_QUP_REG_BASE + 0x00000300)
|
||||
|
||||
#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 BLSP0_SPI_IO_CONTROL_REG (BLSP0_QUP_REG_BASE + 0x00000304)
|
||||
#define BLSP1_SPI_IO_CONTROL_REG (BLSP1_QUP_REG_BASE + 0x00000304)
|
||||
|
||||
#define BOOT_SPI_PORT5_BASE QUP5_BASE
|
||||
#define BOOT_SPI_PORT6_BASE QUP6_BASE
|
||||
#define BOOT_SPI_PORT7_BASE QUP7_BASE
|
||||
#define BLSP0_SPI_ERROR_FLAGS_REG (BLSP0_QUP_REG_BASE + 0x00000308)
|
||||
#define BLSP1_SPI_ERROR_FLAGS_REG (BLSP1_QUP_REG_BASE + 0x00000308)
|
||||
|
||||
#define GSBI5_SPI_CONFIG_REG (GSBI5_QUP5_REG_BASE + 0x00000300)
|
||||
#define GSBI6_SPI_CONFIG_REG (GSBI6_QUP6_REG_BASE + 0x00000300)
|
||||
#define GSBI7_SPI_CONFIG_REG (GSBI7_QUP7_REG_BASE + 0x00000300)
|
||||
#define BLSP0_SPI_DEASSERT_WAIT_REG (BLSP0_QUP_REG_BASE + 0x00000310)
|
||||
#define BLSP1_SPI_DEASSERT_WAIT_REG (BLSP1_QUP_REG_BASE + 0x00000310)
|
||||
#define BLSP0_SPI_ERROR_FLAGS_EN_REG (BLSP0_QUP_REG_BASE + 0x0000030c)
|
||||
#define BLSP1_SPI_ERROR_FLAGS_EN_REG (BLSP1_QUP_REG_BASE + 0x0000030c)
|
||||
|
||||
#define GSBI5_SPI_IO_CONTROL_REG (GSBI5_QUP5_REG_BASE + 0x00000304)
|
||||
#define GSBI6_SPI_IO_CONTROL_REG (GSBI6_QUP6_REG_BASE + 0x00000304)
|
||||
#define GSBI7_SPI_IO_CONTROL_REG (GSBI7_QUP7_REG_BASE + 0x00000304)
|
||||
#define BLSP0_QUP_CONFIG_REG (BLSP0_QUP_REG_BASE + 0x00000000)
|
||||
#define BLSP1_QUP_CONFIG_REG (BLSP1_QUP_REG_BASE + 0x00000000)
|
||||
|
||||
#define GSBI5_SPI_ERROR_FLAGS_REG (GSBI5_QUP5_REG_BASE + 0x00000308)
|
||||
#define GSBI6_SPI_ERROR_FLAGS_REG (GSBI6_QUP6_REG_BASE + 0x00000308)
|
||||
#define GSBI7_SPI_ERROR_FLAGS_REG (GSBI7_QUP7_REG_BASE + 0x00000308)
|
||||
#define BLSP0_QUP_ERROR_FLAGS_REG (BLSP0_QUP_REG_BASE + 0x0000001c)
|
||||
#define BLSP1_QUP_ERROR_FLAGS_REG (BLSP1_QUP_REG_BASE + 0x0000001c)
|
||||
|
||||
#define GSBI5_SPI_ERROR_FLAGS_EN_REG (GSBI5_QUP5_REG_BASE + 0x0000030c)
|
||||
#define GSBI6_SPI_ERROR_FLAGS_EN_REG (GSBI6_QUP6_REG_BASE + 0x0000030c)
|
||||
#define GSBI7_SPI_ERROR_FLAGS_EN_REG (GSBI7_QUP7_REG_BASE + 0x0000030c)
|
||||
#define BLSP0_QUP_ERROR_FLAGS_EN_REG (BLSP0_QUP_REG_BASE + 0x00000020)
|
||||
#define BLSP1_QUP_ERROR_FLAGS_EN_REG (BLSP1_QUP_REG_BASE + 0x00000020)
|
||||
|
||||
#define GSBI5_GSBI_CTRL_REG_REG (GSBI5_REG_BASE + 0x00000000)
|
||||
#define GSBI6_GSBI_CTRL_REG_REG (GSBI6_REG_BASE + 0x00000000)
|
||||
#define GSBI7_GSBI_CTRL_REG_REG (GSBI7_REG_BASE + 0x00000000)
|
||||
#define BLSP0_QUP_OPERATIONAL_MASK (BLSP0_QUP_REG_BASE + 0x00000028)
|
||||
#define BLSP1_QUP_OPERATIONAL_MASK (BLSP1_QUP_REG_BASE + 0x00000028)
|
||||
|
||||
#define GSBI5_QUP_CONFIG_REG (GSBI5_QUP5_REG_BASE + 0x00000000)
|
||||
#define GSBI6_QUP_CONFIG_REG (GSBI6_QUP6_REG_BASE + 0x00000000)
|
||||
#define GSBI7_QUP_CONFIG_REG (GSBI7_QUP7_REG_BASE + 0x00000000)
|
||||
#define BLSP0_QUP_OPERATIONAL_REG (BLSP0_QUP_REG_BASE + 0x00000018)
|
||||
#define BLSP1_QUP_OPERATIONAL_REG (BLSP1_QUP_REG_BASE + 0x00000018)
|
||||
|
||||
#define GSBI5_QUP_ERROR_FLAGS_REG (GSBI5_QUP5_REG_BASE + 0x0000001c)
|
||||
#define GSBI6_QUP_ERROR_FLAGS_REG (GSBI6_QUP6_REG_BASE + 0x0000001c)
|
||||
#define GSBI7_QUP_ERROR_FLAGS_REG (GSBI7_QUP7_REG_BASE + 0x0000001c)
|
||||
#define BLSP0_QUP_IO_MODES_REG (BLSP0_QUP_REG_BASE + 0x00000008)
|
||||
#define BLSP1_QUP_IO_MODES_REG (BLSP1_QUP_REG_BASE + 0x00000008)
|
||||
|
||||
#define GSBI5_QUP_ERROR_FLAGS_EN_REG (GSBI5_QUP5_REG_BASE + 0x00000020)
|
||||
#define GSBI6_QUP_ERROR_FLAGS_EN_REG (GSBI6_QUP6_REG_BASE + 0x00000020)
|
||||
#define GSBI7_QUP_ERROR_FLAGS_EN_REG (GSBI7_QUP7_REG_BASE + 0x00000020)
|
||||
#define BLSP0_QUP_STATE_REG (BLSP0_QUP_REG_BASE + 0x00000004)
|
||||
#define BLSP1_QUP_STATE_REG (BLSP1_QUP_REG_BASE + 0x00000004)
|
||||
|
||||
#define GSBI5_QUP_OPERATIONAL_REG (GSBI5_QUP5_REG_BASE + 0x00000018)
|
||||
#define GSBI6_QUP_OPERATIONAL_REG (GSBI6_QUP6_REG_BASE + 0x00000018)
|
||||
#define GSBI7_QUP_OPERATIONAL_REG (GSBI7_QUP7_REG_BASE + 0x00000018)
|
||||
#define BLSP0_QUP_INPUT_FIFOc_REG(c) \
|
||||
(BLSP0_QUP_REG_BASE + 0x00000218 + 4 * (c))
|
||||
#define BLSP1_QUP_INPUT_FIFOc_REG(c) \
|
||||
(BLSP1_QUP_REG_BASE + 0x00000218 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_IO_MODES_REG (GSBI5_QUP5_REG_BASE + 0x00000008)
|
||||
#define GSBI6_QUP_IO_MODES_REG (GSBI6_QUP6_REG_BASE + 0x00000008)
|
||||
#define GSBI7_QUP_IO_MODES_REG (GSBI7_QUP7_REG_BASE + 0x00000008)
|
||||
#define BLSP0_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(BLSP0_QUP_REG_BASE + 0x00000110 + 4 * (c))
|
||||
#define BLSP1_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(BLSP1_QUP_REG_BASE + 0x00000110 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_STATE_REG (GSBI5_QUP5_REG_BASE + 0x00000004)
|
||||
#define GSBI6_QUP_STATE_REG (GSBI6_QUP6_REG_BASE + 0x00000004)
|
||||
#define GSBI7_QUP_STATE_REG (GSBI7_QUP7_REG_BASE + 0x00000004)
|
||||
#define BLSP0_QUP_MX_INPUT_COUNT_REG (BLSP0_QUP_REG_BASE + 0x00000200)
|
||||
#define BLSP1_QUP_MX_INPUT_COUNT_REG (BLSP1_QUP_REG_BASE + 0x00000200)
|
||||
|
||||
#define GSBI5_QUP_OUT_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x0000010c)
|
||||
#define GSBI6_QUP_OUT_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x0000010c)
|
||||
#define GSBI7_QUP_OUT_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x0000010c)
|
||||
#define BLSP0_QUP_MX_OUTPUT_COUNT_REG (BLSP0_QUP_REG_BASE + 0x00000100)
|
||||
#define BLSP1_QUP_MX_OUTPUT_COUNT_REG (BLSP1_QUP_REG_BASE + 0x00000100)
|
||||
|
||||
#define GSBI5_QUP_IN_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x00000214)
|
||||
#define GSBI6_QUP_IN_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x00000214)
|
||||
#define GSBI7_QUP_IN_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x00000214)
|
||||
#define BLSP0_QUP_SW_RESET_REG (BLSP0_QUP_REG_BASE + 0x0000000c)
|
||||
#define BLSP1_QUP_SW_RESET_REG (BLSP1_QUP_REG_BASE + 0x0000000c)
|
||||
|
||||
#define GSBI5_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI5_QUP5_REG_BASE + 0x00000218 + 4 * (c))
|
||||
#define GSBI6_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI6_QUP6_REG_BASE + 0x00000218 + 4 * (c))
|
||||
#define GSBI7_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI7_QUP7_REG_BASE + 0x00000218 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI5_QUP5_REG_BASE + 0x00000110 + 4 * (c))
|
||||
#define GSBI6_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI6_QUP6_REG_BASE + 0x00000110 + 4 * (c))
|
||||
#define GSBI7_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI7_QUP7_REG_BASE + 0x00000110 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_MX_INPUT_COUNT_REG (GSBI5_QUP5_REG_BASE + 0x00000200)
|
||||
#define GSBI6_QUP_MX_INPUT_COUNT_REG (GSBI6_QUP6_REG_BASE + 0x00000200)
|
||||
#define GSBI7_QUP_MX_INPUT_COUNT_REG (GSBI7_QUP7_REG_BASE + 0x00000200)
|
||||
|
||||
#define GSBI5_QUP_MX_OUTPUT_COUNT_REG (GSBI5_QUP5_REG_BASE + 0x00000100)
|
||||
#define GSBI6_QUP_MX_OUTPUT_COUNT_REG (GSBI6_QUP6_REG_BASE + 0x00000100)
|
||||
#define GSBI7_QUP_MX_OUTPUT_COUNT_REG (GSBI7_QUP7_REG_BASE + 0x00000100)
|
||||
|
||||
#define GSBI5_QUP_SW_RESET_REG (GSBI5_QUP5_REG_BASE + 0x0000000c)
|
||||
#define GSBI6_QUP_SW_RESET_REG (GSBI6_QUP6_REG_BASE + 0x0000000c)
|
||||
#define GSBI7_QUP_SW_RESET_REG (GSBI7_QUP7_REG_BASE + 0x0000000c)
|
||||
|
||||
#define CLK_CTL_REG_BASE 0x00900000
|
||||
#define GSBIn_RESET_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029dc + 32 * ((n)-1))
|
||||
|
||||
#define SFAB_AHB_S3_FCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x0000216c)
|
||||
#define CFPB_CLK_NS_REG \
|
||||
(CLK_CTL_REG_BASE + 0x0000264c)
|
||||
#define SFAB_CFPB_S_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x000026c0)
|
||||
#define CFPB_SPLITTER_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x000026e0)
|
||||
#define CFPB0_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002650)
|
||||
#define CFPB2_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002658)
|
||||
#define GSBIn_HCLK_CTL_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029c0 + 32 * ((n)-1))
|
||||
#define GSBIn_QUP_APPS_NS_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029cc + 32 * ((n)-1))
|
||||
#define GSBIn_QUP_APPS_MD_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029c8 + 32 * ((n)-1))
|
||||
#define CLK_HALT_CFPB_STATEB_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002fd0)
|
||||
|
||||
#define GSBI5_HCLK 23
|
||||
#define GSBI6_HCLK 19
|
||||
#define GSBI7_HCLK 15
|
||||
#define GSBI5_QUP_APPS_CLK 20
|
||||
#define GSBI6_QUP_APPS_CLK 16
|
||||
#define GSBI7_QUP_APPS_CLK 12
|
||||
#define GSBI_CLK_BRANCH_ENA_MSK (1 << 4)
|
||||
#define GSBI_CLK_BRANCH_ENA (1 << 4)
|
||||
#define GSBI_CLK_BRANCH_DIS (0 << 4)
|
||||
#define QUP_CLK_BRANCH_ENA_MSK (1 << 9)
|
||||
#define QUP_CLK_BRANCH_ENA (1 << 9)
|
||||
#define QUP_CLK_BRANCH_DIS (0 << 9)
|
||||
#define CLK_ROOT_ENA_MSK (1 << 11)
|
||||
#define CLK_ROOT_ENA (1 << 11)
|
||||
#define CLK_ROOT_DIS (0 << 11)
|
||||
|
||||
#define QUP_STATE_VALID_BIT 2
|
||||
#define QUP_STATE_VALID 1
|
||||
#define QUP_STATE_MASK 0x3
|
||||
#define QUP_CONFIG_MINI_CORE_MSK (0x0F << 8)
|
||||
#define QUP_CONFIG_MINI_CORE_SPI (1 << 8)
|
||||
#define SPI_QUP_CONF_INPUT_MSK (1 << 7)
|
||||
#define SPI_QUP_CONF_INPUT_ENA (0 << 7)
|
||||
#define SPI_QUP_CONF_NO_INPUT (1 << 7)
|
||||
#define SPI_QUP_CONF_OUTPUT_MSK (1 << 6)
|
||||
#define SPI_QUP_CONF_OUTPUT_ENA (0 << 6)
|
||||
#define SPI_QUP_CONF_NO_OUTPUT (1 << 6)
|
||||
#define SPI_QUP_CONF_OUTPUT_ENA (0 << 6)
|
||||
#define QUP_STATE_RESET_STATE 0x0
|
||||
#define QUP_STATE_RUN_STATE 0x1
|
||||
#define QUP_STATE_PAUSE_STATE 0x3
|
||||
#define SPI_BIT_WORD_MSK 0x1F
|
||||
#define SPI_8_BIT_WORD 0x07
|
||||
#define PROTOCOL_CODE_MSK (0x07 << 4)
|
||||
#define PROTOCOL_CODE_SPI (0x03 << 4)
|
||||
#define LOOP_BACK_MSK (1 << 8)
|
||||
#define NO_LOOP_BACK (0 << 8)
|
||||
#define SLAVE_OPERATION_MSK (1 << 5)
|
||||
#define SLAVE_OPERATION (0 << 5)
|
||||
#define CLK_ALWAYS_ON (0 << 9)
|
||||
#define MX_CS_MODE (0 << 8)
|
||||
#define NO_TRI_STATE (1 << 0)
|
||||
#define OUTPUT_BIT_SHIFT_MSK (1 << 16)
|
||||
#define OUTPUT_BIT_SHIFT_EN (1 << 16)
|
||||
#define INPUT_BLOCK_MODE_MSK (0x03 << 12)
|
||||
#define INPUT_BLOCK_MODE (0x01 << 12)
|
||||
#define OUTPUT_BLOCK_MODE_MSK (0x03 << 10)
|
||||
#define OUTPUT_BLOCK_MODE (0x01 << 10)
|
||||
#define GSBI1_RESET (1 << 0)
|
||||
#define GSBI1_RESET_MSK 0x1
|
||||
#define QUP_CONF_INPUT_MSK (1 << 7)
|
||||
#define QUP_CONF_INPUT_ENA (0 << 7)
|
||||
#define QUP_CONF_NO_INPUT (1 << 7)
|
||||
#define QUP_CONF_OUTPUT_MSK (1 << 6)
|
||||
#define QUP_CONF_OUTPUT_ENA (0 << 6)
|
||||
#define QUP_CONF_NO_OUTPUT (1 << 6)
|
||||
#define QUP_CONF_N_MASK 0x1F
|
||||
#define QUP_CONF_N_SPI_8_BIT_WORD 0x07
|
||||
|
||||
#define GSBI_M_VAL_SHFT 16
|
||||
#define GSBIn_M_VAL_MSK (0xFF << GSBI_M_VAL_SHFT)
|
||||
#define GSBI_N_VAL_SHFT 16
|
||||
#define GSBIn_N_VAL_MSK (0xFF << GSBI_N_VAL_SHFT)
|
||||
#define GSBI_D_VAL_SHFT 0
|
||||
#define GSBIn_D_VAL_MSK (0xFF << GSBI_D_VAL_SHFT)
|
||||
#define MNCNTR_RST_MSK (1 << 7)
|
||||
#define MNCNTR_RST_ENA (1 << 7)
|
||||
#define MNCNTR_RST_DIS (0 << 7)
|
||||
#define MNCNTR_MSK (1 << 8)
|
||||
#define MNCNTR_EN (1 << 8)
|
||||
#define MNCNTR_DIS (0 << 8)
|
||||
#define MNCNTR_MODE_MSK (0x3 << 5)
|
||||
#define MNCNTR_MODE_BYPASS (0 << 5)
|
||||
#define MNCNTR_MODE_DUAL_EDGE (0x2 << 5)
|
||||
#define GSBI_PRE_DIV_SEL_SHFT 3
|
||||
#define GSBIn_PRE_DIV_SEL_MSK (0x3 << GSBI_PRE_DIV_SEL_SHFT)
|
||||
#define GSBIn_PLL_SRC_MSK (0x03 << 0)
|
||||
#define GSBIn_PLL_SRC_PXO (0 << 0)
|
||||
#define GSBIn_PLL_SRC_PLL8 (0x3 << 0)
|
||||
#define SPI_CONFIG_INPUT_FIRST (1 << 9)
|
||||
#define SPI_CONFIG_INPUT_FIRST_BACK (0 << 9)
|
||||
#define SPI_CONFIG_LOOP_BACK_MSK (1 << 8)
|
||||
#define SPI_CONFIG_NO_LOOP_BACK (0 << 8)
|
||||
#define SPI_CONFIG_NO_SLAVE_OPER_MSK (1 << 5)
|
||||
#define SPI_CONFIG_NO_SLAVE_OPER (0 << 5)
|
||||
|
||||
#define SPI_IO_CTRL_CLK_ALWAYS_ON (0 << 9)
|
||||
#define SPI_IO_CTRL_MX_CS_MODE (1 << 8)
|
||||
#define SPI_IO_CTRL_NO_TRI_STATE (1 << 0)
|
||||
#define SPI_IO_CTRL_FORCE_CS_MSK (1 << 11)
|
||||
#define SPI_IO_CTRL_FORCE_CS_EN (1 << 11)
|
||||
#define SPI_IO_CTRL_FORCE_CS_DIS (0 << 11)
|
||||
#define SPI_IO_CTRL_CLOCK_IDLE_HIGH (1 << 10)
|
||||
|
||||
#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_MSK (1 << 16)
|
||||
#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN (1 << 16)
|
||||
#define QUP_IO_MODES_INPUT_MODE_MSK (0x03 << 12)
|
||||
#define QUP_IO_MODES_INPUT_BLOCK_MODE (0x01 << 12)
|
||||
#define QUP_IO_MODES_OUTPUT_MODE_MSK (0x03 << 10)
|
||||
#define QUP_IO_MODES_OUTPUT_BLOCK_MODE (0x01 << 10)
|
||||
|
||||
#define SPI_INPUT_FIRST_MODE (1 << 9)
|
||||
#define SPI_IO_CONTROL_CLOCK_IDLE_HIGH (1 << 10)
|
||||
#define QUP_DATA_AVAILABLE_FOR_READ (1 << 5)
|
||||
#define QUP_OUTPUT_FIFO_NOT_EMPTY (1 << 4)
|
||||
#define OUTPUT_SERVICE_FLAG (1 << 8)
|
||||
#define INPUT_SERVICE_FLAG (1 << 9)
|
||||
#define QUP_OUTPUT_FIFO_FULL (1 << 6)
|
||||
#define QUP_INPUT_FIFO_NOT_EMPTY (1 << 5)
|
||||
#define SPI_INPUT_BLOCK_SIZE 4
|
||||
#define SPI_OUTPUT_BLOCK_SIZE 4
|
||||
#define GSBI5_SPI_CLK 21
|
||||
#define GSBI5_SPI_MISO 19
|
||||
#define GSBI5_SPI_MOSI 18
|
||||
#define GSBI5_SPI_CS_0 20
|
||||
#define GSBI5_SPI_CS_1 61
|
||||
#define GSBI5_SPI_CS_2 62
|
||||
#define GSBI5_SPI_CS_3 2
|
||||
#define GSBI6_SPI_CLK 30
|
||||
#define GSBI6_SPI_CS_0 29
|
||||
#define GSBI6_SPI_MISO 28
|
||||
#define GSBI6_SPI_MOSI 27
|
||||
#define GSBI7_SPI_CLK 9
|
||||
#define GSBI7_SPI_CS_0 8
|
||||
#define GSBI7_SPI_MISO 7
|
||||
#define GSBI7_SPI_MOSI 6
|
||||
|
||||
#define MSM_GSBI_MAX_FREQ 51200000
|
||||
#define MAX_COUNT_SIZE 0xffff
|
||||
|
||||
#define SPI_RESET_STATE 0
|
||||
#define SPI_RUN_STATE 1
|
||||
#define SPI_PAUSE_STATE 3
|
||||
#define SPI_CORE_RESET 0
|
||||
#define SPI_CORE_RUNNING 1
|
||||
#define GSBI_SPI_MODE_0 0
|
||||
#define GSBI_SPI_MODE_1 1
|
||||
#define GSBI_SPI_MODE_2 2
|
||||
#define GSBI_SPI_MODE_3 3
|
||||
#define GSBI5_SPI 0
|
||||
#define GSBI6_SPI 1
|
||||
#define GSBI7_SPI 2
|
||||
#define SPI_MODE0 0
|
||||
#define SPI_MODE1 1
|
||||
#define SPI_MODE2 2
|
||||
#define SPI_MODE3 3
|
||||
#define BLSP0_SPI 0
|
||||
#define BLSP1_SPI 1
|
||||
|
||||
struct gsbi_spi {
|
||||
unsigned int spi_config;
|
||||
unsigned int io_control;
|
||||
unsigned int error_flags;
|
||||
unsigned int error_flags_en;
|
||||
unsigned int gsbi_ctrl;
|
||||
unsigned int qup_config;
|
||||
unsigned int qup_error_flags;
|
||||
unsigned int qup_error_flags_en;
|
||||
unsigned int qup_operational;
|
||||
unsigned int qup_io_modes;
|
||||
unsigned int qup_state;
|
||||
unsigned int qup_input_fifo;
|
||||
unsigned int qup_output_fifo;
|
||||
unsigned int qup_mx_input_count;
|
||||
unsigned int qup_mx_output_count;
|
||||
unsigned int qup_sw_reset;
|
||||
unsigned int qup_ns_reg;
|
||||
unsigned int qup_md_reg;
|
||||
struct blsp_spi {
|
||||
void *spi_config;
|
||||
void *io_control;
|
||||
void *error_flags;
|
||||
void *error_flags_en;
|
||||
void *qup_config;
|
||||
void *qup_error_flags;
|
||||
void *qup_error_flags_en;
|
||||
void *qup_operational;
|
||||
void *qup_io_modes;
|
||||
void *qup_state;
|
||||
void *qup_input_fifo;
|
||||
void *qup_output_fifo;
|
||||
void *qup_mx_input_count;
|
||||
void *qup_mx_output_count;
|
||||
void *qup_sw_reset;
|
||||
void *qup_ns_reg;
|
||||
void *qup_md_reg;
|
||||
void *qup_op_mask;
|
||||
void *qup_deassert_wait;
|
||||
};
|
||||
|
||||
|
||||
#define SUCCESS 0
|
||||
|
||||
#define DUMMY_DATA_VAL 0
|
||||
#define TIMEOUT_CNT 100
|
||||
|
||||
#define ETIMEDOUT -10
|
||||
#define EINVAL -11
|
||||
#define EIO -12
|
||||
|
||||
/* MX_INPUT_COUNT and MX_OUTPUT_COUNT are 16-bits. Zero has a special meaning
|
||||
* (count function disabled) and does not hold significance in the count. */
|
||||
#define MAX_PACKET_COUNT ((64 * KiB) - 1)
|
||||
|
||||
|
||||
struct ipq_spi_slave {
|
||||
struct spi_slave slave;
|
||||
const struct gsbi_spi *regs;
|
||||
const struct blsp_spi *regs;
|
||||
unsigned int mode;
|
||||
unsigned int initialized;
|
||||
unsigned long freq;
|
||||
|
|
|
@ -36,27 +36,35 @@
|
|||
#include <stdlib.h>
|
||||
#include <soc/qup.h>
|
||||
|
||||
#define TIMEOUT_CNT 100000
|
||||
#define TIMEOUT_CNT 100
|
||||
|
||||
//TODO: refactor the following array to iomap driver.
|
||||
static unsigned gsbi_qup_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(id, reg) (blsp_qup_base(id) + (reg))
|
||||
|
||||
#define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))
|
||||
#define QUP_DEBUG 0
|
||||
|
||||
static qup_return_t qup_i2c_master_status(gsbi_id_t gsbi_id)
|
||||
#define QUPDBG BIOS_ERR, "\t-> "
|
||||
|
||||
#if QUP_DEBUG
|
||||
#define qup_write32(a, v) do { \
|
||||
write32(a, v); \
|
||||
printk(QUPDBG "%s(%d): write32(0x%p, 0x%x)\n", \
|
||||
__func__, __LINE__, a, v); \
|
||||
} while (0)
|
||||
#else
|
||||
#define qup_write32 write32
|
||||
#endif
|
||||
|
||||
static qup_return_t qup_i2c_master_status(blsp_qup_id_t id)
|
||||
{
|
||||
uint32_t reg_val = read32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS));
|
||||
uint32_t reg_val = read32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS));
|
||||
|
||||
if (read32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS)))
|
||||
if (read32(QUP_ADDR(id, QUP_ERROR_FLAGS)))
|
||||
return QUP_ERR_XFER_FAIL;
|
||||
|
||||
#if QUP_DEBUG
|
||||
printk(QUPDBG "%s: 0x%x\n", __func__, reg_val);
|
||||
#endif
|
||||
|
||||
if (reg_val & QUP_I2C_INVALID_READ_ADDR)
|
||||
return QUP_ERR_I2C_INVALID_SLAVE_ADDR;
|
||||
if (reg_val & QUP_I2C_FAILED_MASK)
|
||||
|
@ -84,7 +92,6 @@ static int check_bit_state(uint32_t *reg, int wait_for)
|
|||
if (count == 0)
|
||||
return QUP_ERR_TIMEOUT;
|
||||
count--;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
return QUP_SUCCESS;
|
||||
|
@ -93,37 +100,36 @@ static int check_bit_state(uint32_t *reg, int wait_for)
|
|||
/*
|
||||
* Check whether GSBIn_QUP State is valid
|
||||
*/
|
||||
static qup_return_t qup_wait_for_state(gsbi_id_t gsbi_id, unsigned wait_for)
|
||||
static qup_return_t qup_wait_for_state(blsp_qup_id_t id, unsigned wait_for)
|
||||
{
|
||||
return check_bit_state(QUP_ADDR(gsbi_id, QUP_STATE), wait_for);
|
||||
return check_bit_state(QUP_ADDR(id, QUP_STATE), wait_for);
|
||||
}
|
||||
|
||||
qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id)
|
||||
qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id)
|
||||
{
|
||||
/*
|
||||
* Writing a one clears the status bits.
|
||||
* Bit31-25, Bit1 and Bit0 are reserved.
|
||||
* The I2C_STATUS is a status register.
|
||||
* Writing any value clears the status bits.
|
||||
*/
|
||||
//TODO: Define each status bit. OR all status bits in a single macro.
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS), 0x3FFFFFC);
|
||||
qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS), 0);
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_reset_master_status(gsbi_id_t gsbi_id)
|
||||
static qup_return_t qup_reset_master_status(blsp_qup_id_t id)
|
||||
{
|
||||
write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS), 0x7C);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS_EN), 0x7C);
|
||||
qup_reset_i2c_master_status(gsbi_id);
|
||||
qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS), 0x3C);
|
||||
qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS_EN), 0x3C);
|
||||
qup_reset_i2c_master_status(id);
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_fifo_wait_for(gsbi_id_t gsbi_id, uint32_t status)
|
||||
static qup_return_t qup_fifo_wait_for(blsp_qup_id_t id, uint32_t status)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
|
||||
while (!(read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status)) {
|
||||
ret = qup_i2c_master_status(gsbi_id);
|
||||
while (!(read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status)) {
|
||||
ret = qup_i2c_master_status(id);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (count == 0)
|
||||
|
@ -134,13 +140,13 @@ static qup_return_t qup_fifo_wait_for(gsbi_id_t gsbi_id, uint32_t status)
|
|||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_fifo_wait_while(gsbi_id_t gsbi_id, uint32_t status)
|
||||
static qup_return_t qup_fifo_wait_while(blsp_qup_id_t id, uint32_t status)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
|
||||
while (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status) {
|
||||
ret = qup_i2c_master_status(gsbi_id);
|
||||
while (read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status) {
|
||||
ret = qup_i2c_master_status(id);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (count == 0)
|
||||
|
@ -151,7 +157,39 @@ static qup_return_t qup_fifo_wait_while(gsbi_id_t gsbi_id, uint32_t status)
|
|||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_write_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
static inline uint32_t qup_i2c_create_output_tag(int stop, u8 data)
|
||||
{
|
||||
uint32_t tag;
|
||||
|
||||
if (stop)
|
||||
tag = QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data);
|
||||
else
|
||||
tag = QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
static inline qup_return_t qup_i2c_write_fifo_flush(blsp_qup_id_t id)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);
|
||||
|
||||
mdelay(10); /* TPM seems to need this */
|
||||
|
||||
ret = qup_fifo_wait_while(id, OUTPUT_FIFO_NOT_EMPTY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qup_i2c_master_status(id);
|
||||
|
||||
if (ret)
|
||||
printk(BIOS_DEBUG, "%s: error\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_write_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
@ -159,180 +197,235 @@ static qup_return_t qup_i2c_write_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
|||
uint8_t *data_ptr = p_tx_obj->p.iic.data;
|
||||
unsigned data_len = p_tx_obj->p.iic.data_len;
|
||||
unsigned idx = 0;
|
||||
uint32_t tag, *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
|
||||
const uint32_t *fifo_end = fifo + QUP_OUTPUT_FIFO_SIZE / sizeof(*fifo);
|
||||
|
||||
qup_reset_master_status(gsbi_id);
|
||||
qup_set_state(gsbi_id, QUP_STATE_RUN);
|
||||
qup_reset_master_status(id);
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
(QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr)));
|
||||
qup_set_state(id, QUP_STATE_RUN);
|
||||
|
||||
/*
|
||||
* Since UNPACK enable is set in io mode register, populate 2 tags
|
||||
* for each fifo register.
|
||||
*
|
||||
* Create the first tag as follows, with the start tag and first byte
|
||||
* of the data to be written
|
||||
* +--------+--------+--------+--------+
|
||||
* | STOP / | data | START | ADDR |
|
||||
* |DATA tag| byte | tag | << 1 |
|
||||
* +--------+--------+--------+--------+
|
||||
* rest will be created in the following while loop.
|
||||
*/
|
||||
tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
|
||||
data_ptr[idx]);
|
||||
tag = ((tag << 16) & 0xffff0000) |
|
||||
(QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr));
|
||||
data_len--;
|
||||
idx++;
|
||||
|
||||
qup_write32(fifo, tag);
|
||||
fifo++;
|
||||
|
||||
while (data_len) {
|
||||
if (data_len == 1 && stop_seq) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data_ptr[idx]));
|
||||
} else {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data_ptr[idx]));
|
||||
}
|
||||
|
||||
tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
|
||||
data_ptr[idx]);
|
||||
data_len--;
|
||||
idx++;
|
||||
|
||||
if (data_len) {
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_FULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
tag |= qup_i2c_create_output_tag(
|
||||
data_len == 1 && stop_seq,
|
||||
data_ptr[idx]) << 16;
|
||||
data_len--;
|
||||
idx++;
|
||||
}
|
||||
/* Hardware sets the OUTPUT_SERVICE_FLAG flag to 1 when
|
||||
OUTPUT_FIFO_NOT_EMPTY flag in the QUP_OPERATIONAL
|
||||
register changes from 1 to 0, indicating that software
|
||||
can write more data to the output FIFO. Software should
|
||||
set OUTPUT_SERVICE_FLAG to 1 to clear it to 0, which
|
||||
means that software knows to return to fill the output
|
||||
FIFO with data.
|
||||
*/
|
||||
if (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) &
|
||||
OUTPUT_SERVICE_FLAG) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
|
||||
OUTPUT_SERVICE_FLAG);
|
||||
|
||||
qup_write32(fifo, tag);
|
||||
fifo++;
|
||||
|
||||
if ((fifo >= fifo_end) && data_len) {
|
||||
|
||||
fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
|
||||
|
||||
ret = qup_i2c_write_fifo_flush(id);
|
||||
|
||||
if (ret) {
|
||||
printk(BIOS_DEBUG, "%s: error\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = qup_i2c_write_fifo_flush(id);
|
||||
|
||||
qup_set_state(gsbi_id, QUP_STATE_PAUSE);
|
||||
return qup_i2c_master_status(gsbi_id);
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_write(gsbi_id_t gsbi_id, uint8_t mode,
|
||||
static qup_return_t qup_i2c_write(blsp_qup_id_t id, uint8_t mode,
|
||||
qup_data_t *p_tx_obj, uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
switch (mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
ret = qup_i2c_write_fifo(gsbi_id, p_tx_obj, stop_seq);
|
||||
ret = qup_i2c_write_fifo(id, p_tx_obj, stop_seq);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
qup_set_state(gsbi_id, QUP_STATE_RESET);
|
||||
printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_read_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj)
|
||||
static int qup_i2c_parse_tag(uint32_t data, uint8_t *data_ptr, uint32_t len)
|
||||
{
|
||||
int i, idx = 0;
|
||||
int max = (len > 2) ? 2 : len;
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
switch (QUP_I2C_MI_TAG(data)) {
|
||||
case QUP_I2C_MIDATA_SEQ:
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
break;
|
||||
case QUP_I2C_MISTOP_SEQ:
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
return idx;
|
||||
default:
|
||||
printk(QUPDBG "%s: Unexpected tag (0x%x)\n", __func__,
|
||||
QUP_I2C_MI_TAG(data));
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = (data >> 16);
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_read_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t addr = p_tx_obj->p.iic.addr;
|
||||
uint8_t *data_ptr = p_tx_obj->p.iic.data;
|
||||
unsigned data_len = p_tx_obj->p.iic.data_len;
|
||||
unsigned idx = 0;
|
||||
uint32_t *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
|
||||
const uint32_t *fifo_end = fifo + QUP_INPUT_FIFO_SIZE / sizeof(*fifo);
|
||||
|
||||
qup_reset_master_status(gsbi_id);
|
||||
qup_set_state(gsbi_id, QUP_STATE_RUN);
|
||||
qup_reset_master_status(id);
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_START_SEQ | (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ));
|
||||
qup_set_state(id, QUP_STATE_RUN);
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_RECV_SEQ | data_len);
|
||||
qup_write32(fifo, (QUP_I2C_START_SEQ |
|
||||
(QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ)) |
|
||||
((QUP_I2C_RECV_SEQ | data_len) << 16));
|
||||
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY);
|
||||
if (ret)
|
||||
ret = qup_i2c_write_fifo_flush(id);
|
||||
if (ret) {
|
||||
printk(QUPDBG "%s: OUTPUT_FIFO_NOT_EMPTY\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);
|
||||
qup_write32(QUP_ADDR(id, QUP_MX_READ_COUNT), data_len);
|
||||
|
||||
ret = qup_fifo_wait_for(id, INPUT_SERVICE_FLAG);
|
||||
if (ret) {
|
||||
printk(QUPDBG "%s: INPUT_SERVICE_FLAG\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fifo = QUP_ADDR(id, QUP_INPUT_FIFO);
|
||||
|
||||
while (data_len) {
|
||||
uint32_t data;
|
||||
int count;
|
||||
|
||||
ret = qup_fifo_wait_for(gsbi_id, INPUT_SERVICE_FLAG);
|
||||
if (ret)
|
||||
return ret;
|
||||
data = read32(fifo);
|
||||
fifo++;
|
||||
|
||||
data = read32(QUP_ADDR(gsbi_id, QUP_INPUT_FIFO));
|
||||
count = qup_i2c_parse_tag(data, data_ptr + idx, data_len);
|
||||
|
||||
/*
|
||||
* Process tag and corresponding data value. For I2C master
|
||||
* mini-core, data in FIFO is composed of 16 bits and is divided
|
||||
* into an 8-bit tag for the upper bits and 8-bit data for the
|
||||
* lower bits. The 8-bit tag indicates whether the byte is the
|
||||
* last byte, or if a bus error happened during the receipt of
|
||||
* the byte.
|
||||
*/
|
||||
if ((QUP_I2C_MI_TAG(data)) == QUP_I2C_MIDATA_SEQ) {
|
||||
/* Tag: MIDATA = Master input data.*/
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
data_len--;
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
|
||||
INPUT_SERVICE_FLAG);
|
||||
} else {
|
||||
if (QUP_I2C_MI_TAG(data) == QUP_I2C_MISTOP_SEQ) {
|
||||
/* Tag: MISTOP: Last byte of master input. */
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
data_len--;
|
||||
break;
|
||||
}
|
||||
/* Tag: MINACK: Invalid master input data.*/
|
||||
break;
|
||||
if (count < 0) {
|
||||
printk(QUPDBG "%s: Cannot parse tag 0x%x\n",
|
||||
__func__, data);
|
||||
qup_set_state(id, QUP_STATE_PAUSE);
|
||||
|
||||
return QUP_ERR_I2C_INVALID_TAG;
|
||||
}
|
||||
|
||||
idx += count;
|
||||
data_len -= count;
|
||||
|
||||
if ((fifo >= fifo_end) || (data_len == 0)) {
|
||||
fifo = QUP_ADDR(id, QUP_INPUT_FIFO);
|
||||
qup_write32(QUP_ADDR(id, QUP_OPERATIONAL),
|
||||
INPUT_SERVICE_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), INPUT_SERVICE_FLAG);
|
||||
p_tx_obj->p.iic.data_len = idx;
|
||||
qup_set_state(gsbi_id, QUP_STATE_PAUSE);
|
||||
|
||||
qup_write32(QUP_ADDR(id, QUP_MX_READ_COUNT), 0);
|
||||
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_read(gsbi_id_t gsbi_id, uint8_t mode,
|
||||
static qup_return_t qup_i2c_read(blsp_qup_id_t id, uint8_t mode,
|
||||
qup_data_t *p_tx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
|
||||
switch (mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
ret = qup_i2c_read_fifo(gsbi_id, p_tx_obj);
|
||||
ret = qup_i2c_read_fifo(id, p_tx_obj);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
qup_set_state(gsbi_id, QUP_STATE_RESET);
|
||||
printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
|
||||
qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Reset the QUP core.*/
|
||||
write32(QUP_ADDR(gsbi_id, QUP_SW_RESET), 0x1);
|
||||
qup_write32(QUP_ADDR(id, QUP_SW_RESET), 0x1);
|
||||
|
||||
/*Wait till the reset takes effect */
|
||||
ret = qup_wait_for_state(gsbi_id, QUP_STATE_RESET);
|
||||
/* Wait till the reset takes effect */
|
||||
ret = qup_wait_for_state(id, QUP_STATE_RESET);
|
||||
if (ret)
|
||||
goto bailout;
|
||||
|
||||
/* Reset the config */
|
||||
write32(QUP_ADDR(gsbi_id, QUP_CONFIG), 0);
|
||||
qup_write32(QUP_ADDR(id, QUP_CONFIG), 0);
|
||||
|
||||
/*Program the config register*/
|
||||
/*Set N value*/
|
||||
/* Program the config register */
|
||||
/* Set N value */
|
||||
reg_val = 0x0F;
|
||||
/*Set protocol*/
|
||||
/* Set protocol */
|
||||
switch (config_ptr->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
reg_val |= ((config_ptr->protocol &
|
||||
|
@ -343,15 +436,19 @@ qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
|
|||
ret = QUP_ERR_UNSUPPORTED;
|
||||
goto bailout;
|
||||
}
|
||||
write32(QUP_ADDR(gsbi_id, QUP_CONFIG), reg_val);
|
||||
reg_val |= QUP_APP_CLK_ON_EN | QUP_CORE_CLK_ON_EN;
|
||||
qup_write32(QUP_ADDR(id, QUP_CONFIG), reg_val);
|
||||
|
||||
/*Reset i2c clk cntl register*/
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), 0);
|
||||
/* Choose version 1 tag */
|
||||
qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CONFIG), 0);
|
||||
|
||||
/*Set QUP IO Mode*/
|
||||
/* Reset i2c clk cntl register */
|
||||
qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), 0);
|
||||
|
||||
/* Set QUP IO Mode */
|
||||
switch (config_ptr->mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
reg_val = QUP_OUTPUT_BIT_SHIFT_EN |
|
||||
reg_val = QUP_UNPACK_EN | QUP_PACK_EN |
|
||||
((config_ptr->mode & QUP_MODE_MASK) <<
|
||||
QUP_OUTPUT_MODE_SHFT) |
|
||||
((config_ptr->mode & QUP_MODE_MASK) <<
|
||||
|
@ -361,26 +458,27 @@ qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
|
|||
ret = QUP_ERR_UNSUPPORTED;
|
||||
goto bailout;
|
||||
}
|
||||
write32(QUP_ADDR(gsbi_id, QUP_IO_MODES), reg_val);
|
||||
qup_write32(QUP_ADDR(id, QUP_IO_MODES), reg_val);
|
||||
|
||||
/*Set i2c clk cntl*/
|
||||
reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT);
|
||||
reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
|
||||
/ 2) - QUP_DIVIDER_MIN_VAL) &
|
||||
QUP_FS_DIVIDER_MASK);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), reg_val);
|
||||
qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), reg_val);
|
||||
|
||||
qup_set_state(id, QUP_STATE_RESET);
|
||||
bailout:
|
||||
if (ret)
|
||||
printk(BIOS_ERR, "failed to init qup (%d)\n", ret);
|
||||
printk(QUPDBG "failed to init qup (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state)
|
||||
qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned curr_state = read32(QUP_ADDR(gsbi_id, QUP_STATE));
|
||||
unsigned curr_state = read32(QUP_ADDR(id, QUP_STATE));
|
||||
|
||||
if ((state >= QUP_STATE_RESET && state <= QUP_STATE_PAUSE)
|
||||
&& (curr_state & QUP_STATE_VALID_MASK)) {
|
||||
|
@ -390,30 +488,30 @@ qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state)
|
|||
* transition to complete.
|
||||
*/
|
||||
if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
|
||||
qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
|
||||
qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
|
||||
} else {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), state);
|
||||
qup_write32(QUP_ADDR(id, QUP_STATE), state);
|
||||
}
|
||||
ret = qup_wait_for_state(gsbi_id, state);
|
||||
ret = qup_wait_for_state(id, state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
static qup_return_t qup_i2c_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
|
||||
uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
|
||||
QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK;
|
||||
|
||||
ret = qup_i2c_write(gsbi_id, mode, p_tx_obj, stop_seq);
|
||||
if (0) {
|
||||
ret = qup_i2c_write(id, mode, p_tx_obj, stop_seq);
|
||||
if (QUP_DEBUG) {
|
||||
int i;
|
||||
|
||||
printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:",
|
||||
gsbi_id, p_tx_obj->p.iic.addr);
|
||||
id, p_tx_obj->p.iic.addr);
|
||||
for (i = 0; i < p_tx_obj->p.iic.data_len; i++)
|
||||
printk(BIOS_DEBUG, " %2.2x", p_tx_obj->p.iic.data[i]);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
@ -422,16 +520,16 @@ static qup_return_t qup_i2c_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
|||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
if (p_tx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
|
||||
if (p_tx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
|
||||
QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
|
||||
switch (p_tx_obj->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
ret = qup_i2c_send_data(gsbi_id, p_tx_obj, stop_seq);
|
||||
ret = qup_i2c_send_data(id, p_tx_obj, stop_seq);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
|
@ -441,18 +539,18 @@ qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
|
||||
static qup_return_t qup_i2c_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
|
||||
uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
|
||||
QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK;
|
||||
|
||||
ret = qup_i2c_read(gsbi_id, mode, p_rx_obj);
|
||||
if (0) {
|
||||
ret = qup_i2c_read(id, mode, p_rx_obj);
|
||||
if (QUP_DEBUG) {
|
||||
int i;
|
||||
|
||||
printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:",
|
||||
gsbi_id, p_rx_obj->p.iic.addr);
|
||||
id, p_rx_obj->p.iic.addr);
|
||||
for (i = 0; i < p_rx_obj->p.iic.data_len; i++)
|
||||
printk(BIOS_DEBUG, " %2.2x", p_rx_obj->p.iic.data[i]);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
@ -461,15 +559,15 @@ static qup_return_t qup_i2c_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
|
||||
qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
if (p_rx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
|
||||
if (p_rx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
|
||||
QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
|
||||
switch (p_rx_obj->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
ret = qup_i2c_recv_data(gsbi_id, p_rx_obj);
|
||||
ret = qup_i2c_recv_data(id, p_rx_obj);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,7 @@
|
|||
#include <delay.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/blsp.h>
|
||||
#include <soc/ipq_uart.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
Loading…
Reference in New Issue