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:
		
				
					committed by
					
						 Patrick Georgi
						Patrick Georgi
					
				
			
			
				
	
			
			
			
						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, | ||||
| 	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(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_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 | ||||
|   | ||||
							
								
								
									
										52
									
								
								src/soc/qualcomm/ipq40xx/blsp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/soc/qualcomm/ipq40xx/blsp.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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,175 +197,230 @@ 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); | ||||
|  | ||||
| 	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])); | ||||
| 		} | ||||
| 	/* | ||||
| 	 * 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) { | ||||
|  | ||||
| 		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) | ||||
| 			tag |= qup_i2c_create_output_tag( | ||||
| 						data_len == 1 && stop_seq, | ||||
| 						data_ptr[idx]) << 16; | ||||
| 			data_len--; | ||||
| 			idx++; | ||||
| 		} | ||||
|  | ||||
| 		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; | ||||
| 			} | ||||
| 		/* 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); | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY); | ||||
| 	if (ret) | ||||
| 	ret = qup_i2c_write_fifo_flush(id); | ||||
|  | ||||
| 	qup_set_state(id, QUP_STATE_RESET); | ||||
|  | ||||
| 	return ret; | ||||
|  | ||||
| 	qup_set_state(gsbi_id, QUP_STATE_PAUSE); | ||||
| 	return qup_i2c_master_status(gsbi_id); | ||||
| } | ||||
|  | ||||
| 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), | ||||
| 		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); | ||||
| 		} 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; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	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); | ||||
| 	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 */ | ||||
| @@ -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); | ||||
|  | ||||
| 	/* Choose version 1 tag */ | ||||
| 	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CONFIG), 0); | ||||
|  | ||||
| 	/* Reset i2c clk cntl register */ | ||||
| 	write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), 0); | ||||
| 	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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user