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 | config DRIVER_TPM_I2C_BUS | ||||||
| 	hex | 	hex | ||||||
| 	default 0x1 | 	default 0x2 | ||||||
|  |  | ||||||
| config DRIVER_TPM_I2C_ADDR | config DRIVER_TPM_I2C_ADDR | ||||||
| 	hex | 	hex | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ bootblock-y += reset.c | |||||||
| verstage-y += boardid.c | verstage-y += boardid.c | ||||||
| verstage-y += cdp.c | verstage-y += cdp.c | ||||||
| verstage-y += chromeos.c | verstage-y += chromeos.c | ||||||
| verstage-y += gsbi.c | verstage-y += blsp.c | ||||||
| verstage-y += memlayout.ld | verstage-y += memlayout.ld | ||||||
| verstage-y += reset.c | verstage-y += reset.c | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,34 +27,47 @@ | |||||||
|  * SUCH DAMAGE. |  * SUCH DAMAGE. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <gpio.h> | ||||||
| #include <soc/gpio.h> | #include <soc/gpio.h> | ||||||
| #include <soc/gsbi.h> | #include <soc/blsp.h> | ||||||
| #include <soc/qup.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) { | 	switch (id) { | ||||||
| 	case GSBI_ID_7: | 	case BLSP_QUP_ID_0: | ||||||
| 			gpio_tlmm_config_set(8, GPIO_FUNC_I2C, | 	case BLSP_QUP_ID_1: | ||||||
| 					     GPIO_NO_PULL, GPIO_2MA, 1); | 	case BLSP_QUP_ID_2: | ||||||
| 			gpio_tlmm_config_set(9, GPIO_FUNC_I2C, | 	case BLSP_QUP_ID_3: | ||||||
| 					     GPIO_NO_PULL, GPIO_2MA, 1); | #if defined(IPQ40XX_I2C0_PINGROUP_1) || defined(IPQ40XX_I2C0_PINGROUP_2) | ||||||
| 		break; | 		gpio_tlmm_config_set(SDA_GPIO, GPIO_FUNC_SDA, | ||||||
| 	case GSBI_ID_4: | 				     GPIO_NO_PULL, GPIO_2MA, 1); | ||||||
| 			/* Configure GPIOs 13 - SCL, 12 - SDA, 2mA gpio_en */ | 		gpio_tlmm_config_set(SCL_GPIO, GPIO_FUNC_SCL, | ||||||
| 			gpio_tlmm_config_set(12, GPIO_FUNC_I2C, | 				     GPIO_NO_PULL, GPIO_2MA, 1); | ||||||
| 					     GPIO_NO_PULL, GPIO_2MA, 1); | #endif /* Pin Group 1 or 2 */ | ||||||
| 			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); |  | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		return 1; | 		return 1; | ||||||
| @@ -20,7 +20,7 @@ | |||||||
| #include <drivers/i2c/ww_ring/ww_ring.h> | #include <drivers/i2c/ww_ring/ww_ring.h> | ||||||
| #include <gpio.h> | #include <gpio.h> | ||||||
| #include <soc/cdp.h> | #include <soc/cdp.h> | ||||||
| #include <soc/gsbi.h> | #include <soc/blsp.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <timer.h> | #include <timer.h> | ||||||
| #include <vendorcode/google/chromeos/chromeos.h> | #include <vendorcode/google/chromeos/chromeos.h> | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
| #include <soc/clock.h> | #include <soc/clock.h> | ||||||
| #include <soc/soc_services.h> | #include <soc/soc_services.h> | ||||||
| #include <soc/usb.h> | #include <soc/usb.h> | ||||||
|  | #include <soc/blsp.h> | ||||||
| #include <symbols.h> | #include <symbols.h> | ||||||
|  |  | ||||||
| #include <vendorcode/google/chromeos/chromeos.h> | #include <vendorcode/google/chromeos/chromeos.h> | ||||||
| @@ -37,7 +38,7 @@ static void setup_usb(void) | |||||||
| } | } | ||||||
|  |  | ||||||
| #define TPM_RESET_GPIO		19 | #define TPM_RESET_GPIO		19 | ||||||
| static void ipq_setup_tpm(void) | void ipq_setup_tpm(void) | ||||||
| { | { | ||||||
| #ifdef CONFIG_I2C_TPM | #ifdef CONFIG_I2C_TPM | ||||||
| 	gpio_tlmm_config_set(TPM_RESET_GPIO, FUNC_SEL_GPIO, | 	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 += clock.c | ||||||
| verstage-y += gpio.c | verstage-y += gpio.c | ||||||
| libverstage-y += gsbi.c | libverstage-y += blsp.c | ||||||
| libverstage-y += i2c.c | libverstage-y += i2c.c | ||||||
| libverstage-y += qup.c | libverstage-y += qup.c | ||||||
| libverstage-y += spi.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 <delay.h> | ||||||
|  | #include <soc/blsp.h> | ||||||
| #include <soc/clock.h> | #include <soc/clock.h> | ||||||
| #include <types.h> | #include <types.h> | ||||||
|  | #include <console/console.h> | ||||||
|  |  | ||||||
| #define CLOCK_UPDATE_DELAY		1000 | #define CLOCK_UPDATE_DELAY		1000 | ||||||
|  |  | ||||||
| @@ -67,6 +69,7 @@ void uart_clock_config(unsigned int blsp_uart, unsigned int m, | |||||||
| 		udelay(1); | 		udelay(1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* Please refer to the comments in blsp_i2c_clock_config() */ | ||||||
| 	setbits_le32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP); | 	setbits_le32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -110,3 +113,67 @@ void usb_clock_config(void) | |||||||
| 	udelay(5); | 	udelay(5); | ||||||
| 	write32(USB30_RESET, 0);	/* deassert all USB resets again */ | 	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 <device/i2c.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <soc/gsbi.h> | #include <soc/blsp.h> | ||||||
| #include <soc/qup.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, | 	QUP_MINICORE_I2C_MASTER, | ||||||
| 	100000, | 	100000, | ||||||
| 	24000000, | 	19050000, | ||||||
| 	QUP_MODE_FIFO, | 	QUP_MODE_FIFO, | ||||||
| 	0 | 	0 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static qup_config_t gsbi4_qup_config = { | static qup_config_t blsp1_qup1_config = { | ||||||
| 	QUP_MINICORE_I2C_MASTER, | 	QUP_MINICORE_I2C_MASTER, | ||||||
| 	100000, | 	100000, | ||||||
| 	24000000, | 	19050000, | ||||||
| 	QUP_MODE_FIFO, | 	QUP_MODE_FIFO, | ||||||
| 	0 | 	0 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static qup_config_t gsbi7_qup_config = { | static qup_config_t blsp1_qup2_config = { | ||||||
| 	QUP_MINICORE_I2C_MASTER, | 	QUP_MINICORE_I2C_MASTER, | ||||||
| 	100000, | 	100000, | ||||||
| 	24000000, | 	19050000, | ||||||
|  | 	QUP_MODE_FIFO, | ||||||
|  | 	0 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static qup_config_t blsp1_qup3_config = { | ||||||
|  | 	QUP_MINICORE_I2C_MASTER, | ||||||
|  | 	100000, | ||||||
|  | 	19050000, | ||||||
| 	QUP_MODE_FIFO, | 	QUP_MODE_FIFO, | ||||||
| 	0 | 	0 | ||||||
| }; | }; | ||||||
| @@ -101,41 +110,43 @@ static int i2c_write(uint32_t gsbi_id, uint8_t slave, | |||||||
| 		return 0; | 		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; | 	qup_config_t *qup_config; | ||||||
|  |  | ||||||
| 	switch (gsbi_id) { | 	switch (id) { | ||||||
| 	case GSBI_ID_1: | 	case BLSP_QUP_ID_0: | ||||||
| 		qup_config = &gsbi1_qup_config; | 		qup_config = &blsp1_qup0_config; | ||||||
| 		break; | 		break; | ||||||
| 	case GSBI_ID_4: | 	case BLSP_QUP_ID_1: | ||||||
| 		qup_config = &gsbi4_qup_config; | 		qup_config = &blsp1_qup1_config; | ||||||
| 		break; | 		break; | ||||||
| 	case GSBI_ID_7: | 	case BLSP_QUP_ID_2: | ||||||
| 		qup_config = &gsbi7_qup_config; | 		qup_config = &blsp1_qup2_config; | ||||||
|  | 		break; | ||||||
|  | 	case BLSP_QUP_ID_3: | ||||||
|  | 		qup_config = &blsp1_qup3_config; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		printk(BIOS_ERR, "QUP configuration not defind for GSBI%d.\n", | 		printk(BIOS_ERR, "QUP configuration not defined for BLSP%d.\n", | ||||||
| 		       gsbi_id); | 		       id); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (qup_config->initialized) | 	if (qup_config->initialized) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) { | 	if (blsp_i2c_init(id)) { | ||||||
| 		printk(BIOS_ERR, "failed to initialize gsbi\n"); | 		printk(BIOS_ERR, "failed to initialize blsp\n"); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (qup_init(gsbi_id, qup_config)) { | 	if (qup_init(id, qup_config)) { | ||||||
| 		printk(BIOS_ERR, "failed to initialize qup\n"); | 		printk(BIOS_ERR, "failed to initialize qup\n"); | ||||||
| 		return 1; | 		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"); | 		printk(BIOS_ERR, "failed to reset i2c master status\n"); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -28,48 +28,33 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifndef __GSBI_H_ | #ifndef __BLSP_H_ | ||||||
| #define __GSBI_H_ | #define __BLSP_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 |  | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	GSBI_ID_1 = 1, | 	BLSP_QUP_ID_0, | ||||||
| 	GSBI_ID_2, | 	BLSP_QUP_ID_1, | ||||||
| 	GSBI_ID_3, | 	BLSP_QUP_ID_2, | ||||||
| 	GSBI_ID_4, | 	BLSP_QUP_ID_3, | ||||||
| 	GSBI_ID_5, | } blsp_qup_id_t; | ||||||
| 	GSBI_ID_6, |  | ||||||
| 	GSBI_ID_7, |  | ||||||
| } gsbi_id_t; |  | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	GSBI_SUCCESS = 0, | 	BLSP_SUCCESS = 0, | ||||||
| 	GSBI_ID_ERROR, | 	BLSP_ID_ERROR, | ||||||
| 	GSBI_ERROR, | 	BLSP_ERROR, | ||||||
| 	GSBI_UNSUPPORTED | 	BLSP_UNSUPPORTED | ||||||
| } gsbi_return_t; | } blsp_return_t; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	GSBI_PROTO_I2C_UIM = 1, | 	BLSP_PROTO_I2C_UIM = 1, | ||||||
| 	GSBI_PROTO_I2C_ONLY, | 	BLSP_PROTO_I2C_ONLY, | ||||||
| 	GSBI_PROTO_SPI_ONLY, | 	BLSP_PROTO_SPI_ONLY, | ||||||
| 	GSBI_PROTO_UART_FLOW_CTL, | 	BLSP_PROTO_UART_FLOW_CTL, | ||||||
| 	GSBI_PROTO_UIM, | 	BLSP_PROTO_UIM, | ||||||
| 	GSBI_PROTO_I2C_UART, | 	BLSP_PROTO_I2C_UART, | ||||||
| } gsbi_protocol_t; | } blsp_protocol_t; | ||||||
| 
 | 
 | ||||||
| gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol); | blsp_return_t blsp_i2c_init(blsp_qup_id_t id); | ||||||
| int gsbi_init_board(gsbi_id_t gsbi_id); | int blsp_i2c_init_board(blsp_qup_id_t id); | ||||||
| 
 | 
 | ||||||
| #endif | #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 nand_clock_config(void); | ||||||
| void usb_clock_config(void); | void usb_clock_config(void); | ||||||
| int audio_clock_config(unsigned frequency); | int audio_clock_config(unsigned frequency); | ||||||
|  | int blsp_i2c_clock_config(blsp_qup_id_t id); | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif  /*  __PLATFORM_IPQ40XX_CLOCK_H_ */ | #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); | 	gpio_tlmm_config_set(gpio, func, pull, drvstr, enable); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ipq_setup_tpm(void); | ||||||
|  |  | ||||||
| #endif // __SOC_QUALCOMM_IPQ40XX_GPIO_H_ | #endif // __SOC_QUALCOMM_IPQ40XX_GPIO_H_ | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ | |||||||
|  |  | ||||||
| #include <arch/io.h> | #include <arch/io.h> | ||||||
| #include <soc/cdp.h> | #include <soc/cdp.h> | ||||||
|  | #include <soc/blsp.h> | ||||||
|  |  | ||||||
| /* Typecast to allow integers being passed as address | /* Typecast to allow integers being passed as address | ||||||
|    This needs to be included because vendor code is not compliant with our |    This needs to be included because vendor code is not compliant with our | ||||||
| @@ -71,6 +72,13 @@ | |||||||
| #define		CRYPTO_AXI		(1 << 1) | #define		CRYPTO_AXI		(1 << 1) | ||||||
| #define		CRYPTO_AHB		(1 << 0) | #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_GLOBAL_CTRL_BASE	((void *)0x004a0000u) | ||||||
| #define GCNT_CNTCR		(GCNT_GLOBAL_CTRL_BASE + 0x1000) | #define GCNT_CNTCR		(GCNT_GLOBAL_CTRL_BASE + 0x1000) | ||||||
| #define GCNT_GLB_CNTCV_LO	(GCNT_GLOBAL_CTRL_BASE + 0x1008) | #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_APPS_D(x)	(GCC_BLSP1_UART_APPS_N(x) + 4) | ||||||
| #define GCC_BLSP1_UART_MISC(x)		(GCC_BLSP1_UART_APPS_D(x) + 4) | #define GCC_BLSP1_UART_MISC(x)		(GCC_BLSP1_UART_APPS_D(x) + 4) | ||||||
|  |  | ||||||
| #define GSBI1_BASE		((void *)0x12440000) | #define BLSP1_QUP0_BASE		((void *)0x078B5000) | ||||||
| #define GSBI2_BASE		((void *)0x12480000) | #define BLSP1_QUP1_BASE		((void *)0x078B6000) | ||||||
| #define GSBI3_BASE		((void *)0x16200000) | #define BLSP1_QUP2_BASE		((void *)0x078B7000) | ||||||
| #define GSBI4_BASE		((void *)0x16300000) | #define BLSP1_QUP3_BASE		((void *)0x078B8000) | ||||||
| #define GSBI5_BASE		((void *)0x1A200000) |  | ||||||
| #define GSBI6_BASE		((void *)0x16500000) |  | ||||||
| #define GSBI7_BASE		((void *)0x16600000) |  | ||||||
|  |  | ||||||
| #define GSBI1_CTL_REG		(GSBI1_BASE + (0x0)) | static inline void *blsp_qup_base(blsp_qup_id_t id) | ||||||
| #define GSBI2_CTL_REG		(GSBI2_BASE + (0x0)) | { | ||||||
| #define GSBI3_CTL_REG		(GSBI3_BASE + (0x0)) | 	switch (id) { | ||||||
| #define GSBI4_CTL_REG		(GSBI4_BASE + (0x0)) | 	case BLSP_QUP_ID_0: return BLSP1_QUP0_BASE; | ||||||
| #define GSBI5_CTL_REG		(GSBI5_BASE + (0x0)) | 	case BLSP_QUP_ID_1: return BLSP1_QUP1_BASE; | ||||||
| #define GSBI6_CTL_REG		(GSBI6_BASE + (0x0)) | 	case BLSP_QUP_ID_2: return BLSP1_QUP2_BASE; | ||||||
| #define GSBI7_CTL_REG		(GSBI7_BASE + (0x0)) | 	case BLSP_QUP_ID_3: return BLSP1_QUP3_BASE; | ||||||
|  | 	} | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
| #define GSBI_QUP1_BASE		(GSBI1_BASE + 0x20000) | #define BLSP_MINI_CORE_SHIFT		8 | ||||||
| #define GSBI_QUP2_BASE		(GSBI2_BASE + 0x20000) | #define BLSP_MINI_CORE_I2C		(0x2u << BLSP_MINI_CORE_SHIFT) | ||||||
| #define GSBI_QUP3_BASE		(GSBI3_BASE + 0x80000) | #define BLSP_MINI_CORE_MASK		(0xfu << BLSP_MINI_CORE_SHIFT) | ||||||
| #define GSBI_QUP4_BASE		(GSBI4_BASE + 0x80000) |  | ||||||
| #define GSBI_QUP5_BASE		(GSBI5_BASE + 0x80000) |  | ||||||
| #define GSBI_QUP6_BASE		(GSBI6_BASE + 0x80000) |  | ||||||
| #define GSBI_QUP7_BASE		(GSBI7_BASE + 0x80000) |  | ||||||
|  |  | ||||||
| #define GSBI_CTL_PROTO_I2C              2 | #define ETIMEDOUT -10 | ||||||
| #define GSBI_CTL_PROTO_CODE_SFT         4 | #define EINVAL -11 | ||||||
| #define GSBI_CTL_PROTO_CODE_MSK         0x7 | #define EIO -12 | ||||||
| #define GSBI_HCLK_CTL_GATE_ENA          6 |  | ||||||
| #define GSBI_HCLK_CTL_BRANCH_ENA        4 |  | ||||||
| #define GSBI_QUP_APPS_M_SHFT            16 |  | ||||||
| #define GSBI_QUP_APPS_M_MASK            0xFF |  | ||||||
| #define GSBI_QUP_APPS_D_SHFT            0 |  | ||||||
| #define GSBI_QUP_APPS_D_MASK            0xFF |  | ||||||
| #define GSBI_QUP_APPS_N_SHFT            16 |  | ||||||
| #define GSBI_QUP_APPS_N_MASK            0xFF |  | ||||||
| #define GSBI_QUP_APPS_ROOT_ENA_SFT      11 |  | ||||||
| #define GSBI_QUP_APPS_BRANCH_ENA_SFT    9 |  | ||||||
| #define GSBI_QUP_APPS_MNCTR_EN_SFT      8 |  | ||||||
| #define GSBI_QUP_APPS_MNCTR_MODE_MSK    0x3 |  | ||||||
| #define GSBI_QUP_APPS_MNCTR_MODE_SFT    5 |  | ||||||
| #define GSBI_QUP_APPS_PRE_DIV_MSK       0x3 |  | ||||||
| #define GSBI_QUP_APPS_PRE_DIV_SFT       3 |  | ||||||
| #define GSBI_QUP_APPS_SRC_SEL_MSK       0x7 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define GSBI_QUP_APSS_MD_REG(gsbi_n)	((MSM_CLK_CTL_BASE + 0x29c8) + \ |  | ||||||
| 							(32*(gsbi_n-1))) |  | ||||||
| #define GSBI_QUP_APSS_NS_REG(gsbi_n)	((MSM_CLK_CTL_BASE + 0x29cc) + \ |  | ||||||
| 							(32*(gsbi_n-1))) |  | ||||||
| #define GSBI_HCLK_CTL(n)		((MSM_CLK_CTL_BASE + 0x29C0) + \ |  | ||||||
| 							(32*(n-1))) |  | ||||||
| #endif // __SOC_QUALCOMM_IPQ40XX_IOMAP_H_ | #endif // __SOC_QUALCOMM_IPQ40XX_IOMAP_H_ | ||||||
|   | |||||||
| @@ -32,40 +32,50 @@ | |||||||
| #ifndef __QUP_H__ | #ifndef __QUP_H__ | ||||||
| #define __QUP_H__ | #define __QUP_H__ | ||||||
|  |  | ||||||
| #include <soc/gsbi.h> | #include <soc/blsp.h> | ||||||
|  |  | ||||||
| /* QUP block registers */ | /* QUP block registers */ | ||||||
| #define QUP_CONFIG			0x0 | #define QUP_CONFIG			0x000 | ||||||
| #define QUP_STATE			0x4 | #define QUP_STATE			0x004 | ||||||
| #define QUP_IO_MODES			0x8 | #define QUP_IO_MODES			0x008 | ||||||
| #define QUP_SW_RESET			0xc | #define QUP_SW_RESET			0x00C | ||||||
| #define QUP_TIME_OUT			0x10 | #define QUP_TRANSFER_CANCEL		0x014 | ||||||
| #define QUP_TIME_OUT_CURRENT		0x14 | #define QUP_OPERATIONAL			0x018 | ||||||
| #define QUP_OPERATIONAL			0x18 | #define QUP_ERROR_FLAGS			0x01C | ||||||
| #define QUP_ERROR_FLAGS			0x1c | #define QUP_ERROR_FLAGS_EN		0x020 | ||||||
| #define QUP_ERROR_FLAGS_EN		0x20 | #define QUP_TEST_CTRL			0x024 | ||||||
| #define QUP_TEST_CTRL			0x24 | #define QUP_OPERATIONAL_MASK		0x028 | ||||||
|  | #define QUP_HW_VERSION			0x030 | ||||||
| #define QUP_MX_OUTPUT_COUNT		0x100 | #define QUP_MX_OUTPUT_COUNT		0x100 | ||||||
| #define QUP_MX_OUTPUT_CNT_CURRENT	0x104 | #define QUP_MX_OUTPUT_CNT_CURRENT	0x104 | ||||||
| #define QUP_OUTPUT_DEBUG		0x108 | #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			0x110 | ||||||
|  | #define QUP_OUTPUT_FIFO_SIZE		64	/* bytes */ | ||||||
| #define QUP_MX_WRITE_COUNT		0x150 | #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_MX_INPUT_COUNT		0x200 | ||||||
| #define QUP_READ_COUNT			0x208 | #define QUP_MX_INPUT_CNT_CURRENT	0x204 | ||||||
| #define QUP_MX_READ_CNT_CURRENT		0x20c | #define QUP_MX_READ_COUNT		0x208 | ||||||
|  | #define QUP_MX_READ_CNT_CURRENT		0x20C | ||||||
| #define QUP_INPUT_DEBUG			0x210 | #define QUP_INPUT_DEBUG			0x210 | ||||||
| #define QUP_INPUT_FIFO_WORD_CNT		0x214 | #define QUP_INPUT_FIFO_WORD_CNT		0x214 | ||||||
| #define QUP_INPUT_FIFO			0x218 | #define QUP_INPUT_FIFO			0x218 | ||||||
|  | #define QUP_INPUT_FIFO_SIZE		64	/* bytes */ | ||||||
| #define QUP_I2C_MASTER_CLK_CTL		0x400 | #define QUP_I2C_MASTER_CLK_CTL		0x400 | ||||||
| #define QUP_I2C_MASTER_STATUS		0x404 | #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 OUTPUT_FIFO_FULL		(1<<6) | ||||||
| #define INPUT_FIFO_NOT_EMPTY		(1<<5) | #define INPUT_FIFO_NOT_EMPTY		(1<<5) | ||||||
| #define OUTPUT_FIFO_NOT_EMPTY		(1<<4) | #define OUTPUT_FIFO_NOT_EMPTY		(1<<4) | ||||||
| #define INPUT_SERVICE_FLAG		(1<<9) | #define INPUT_SERVICE_FLAG		(1<<9) | ||||||
| #define OUTPUT_SERVICE_FLAG		(1<<8) | #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_OUTPUT_BIT_SHIFT_EN		(1<<16) | ||||||
|  |  | ||||||
| #define QUP_MODE_MASK			(0x03) | #define QUP_MODE_MASK			(0x03) | ||||||
| @@ -74,6 +84,8 @@ | |||||||
|  |  | ||||||
| #define QUP_FS_DIVIDER_MASK		(0xFF) | #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_SHFT	(8) | ||||||
| #define QUP_MINI_CORE_PROTO_MASK	(0x0F) | #define QUP_MINI_CORE_PROTO_MASK	(0x0F) | ||||||
|  |  | ||||||
| @@ -170,50 +182,50 @@ typedef struct { | |||||||
| } qup_data_t; | } qup_data_t; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Initialize GSBI QUP block for FIFO I2C transfers. |  * Initialize BLSP QUP block for FIFO I2C transfers. | ||||||
|  * gsbi_id[IN]: GSBI for which QUP is to be initialized. |  * id[IN]: BLSP for which QUP is to be initialized. | ||||||
|  * config_ptr[IN]: configurations parameters for the QUP. |  * config_ptr[IN]: configurations parameters for the QUP. | ||||||
|  * |  * | ||||||
|  * return: QUP_SUCCESS, if initialization succeeds. |  * 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. |  * 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. |  * state[IN]: New state to transition to. | ||||||
|  * |  * | ||||||
|  * return: QUP_SUCCESS, if state transition succeeds. |  * 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. |  * 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. |  * 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. |  * 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. |  * 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. |  * 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. |  * 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); | 			   uint8_t stop_seq); | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Receive data from peripheral on the bus. |  * 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. |  * p_tx_obj[IN]: length of data to be received, slave address. | ||||||
|  *      [OUT]: buffer filled with data from slave. |  *      [OUT]: buffer filled with data from slave. | ||||||
|  * |  * | ||||||
|  * return: QUP_SUCCESS, when data is received successfully. |  * 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__ | #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. |  * Copyright (c) 2012 The Linux Foundation. All rights reserved. | ||||||
|  * |  * | ||||||
| @@ -34,263 +34,152 @@ | |||||||
|  |  | ||||||
| #include <spi_flash.h> | #include <spi_flash.h> | ||||||
| #include <soc/iomap.h> | #include <soc/iomap.h> | ||||||
|  | #include <soc/qup.h> | ||||||
|  |  | ||||||
| #define QUP5_BASE	((uint32_t)GSBI_QUP5_BASE) | #define BLSP0_QUP_REG_BASE		((void *)0x78b5000u) | ||||||
| #define QUP6_BASE	((uint32_t)GSBI_QUP6_BASE) | #define BLSP1_QUP_REG_BASE		((void *)0x78b6000u) | ||||||
| #define QUP7_BASE	((uint32_t)GSBI_QUP7_BASE) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP5_REG_BASE		(QUP5_BASE + 0x00000000) | #define BLSP0_SPI_CONFIG_REG		(BLSP0_QUP_REG_BASE + 0x00000300) | ||||||
| #define GSBI6_QUP6_REG_BASE		(QUP6_BASE + 0x00000000) | #define BLSP1_SPI_CONFIG_REG		(BLSP1_QUP_REG_BASE + 0x00000300) | ||||||
| #define GSBI7_QUP7_REG_BASE		(QUP7_BASE + 0x00000000) |  | ||||||
|  |  | ||||||
| #define GSBI5_REG_BASE			((uint32_t)(GSBI5_BASE + 0x00000000)) | #define BLSP0_SPI_IO_CONTROL_REG	(BLSP0_QUP_REG_BASE + 0x00000304) | ||||||
| #define GSBI6_REG_BASE			((uint32_t)(GSBI6_BASE + 0x00000000)) | #define BLSP1_SPI_IO_CONTROL_REG	(BLSP1_QUP_REG_BASE + 0x00000304) | ||||||
| #define GSBI7_REG_BASE			((uint32_t)(GSBI7_BASE + 0x00000000)) |  | ||||||
|  |  | ||||||
| #define BOOT_SPI_PORT5_BASE		QUP5_BASE | #define BLSP0_SPI_ERROR_FLAGS_REG	(BLSP0_QUP_REG_BASE + 0x00000308) | ||||||
| #define BOOT_SPI_PORT6_BASE		QUP6_BASE | #define BLSP1_SPI_ERROR_FLAGS_REG	(BLSP1_QUP_REG_BASE + 0x00000308) | ||||||
| #define BOOT_SPI_PORT7_BASE		QUP7_BASE |  | ||||||
|  |  | ||||||
| #define GSBI5_SPI_CONFIG_REG		(GSBI5_QUP5_REG_BASE + 0x00000300) | #define BLSP0_SPI_DEASSERT_WAIT_REG	(BLSP0_QUP_REG_BASE + 0x00000310) | ||||||
| #define GSBI6_SPI_CONFIG_REG		(GSBI6_QUP6_REG_BASE + 0x00000300) | #define BLSP1_SPI_DEASSERT_WAIT_REG	(BLSP1_QUP_REG_BASE + 0x00000310) | ||||||
| #define GSBI7_SPI_CONFIG_REG		(GSBI7_QUP7_REG_BASE + 0x00000300) | #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 BLSP0_QUP_CONFIG_REG		(BLSP0_QUP_REG_BASE + 0x00000000) | ||||||
| #define GSBI6_SPI_IO_CONTROL_REG	(GSBI6_QUP6_REG_BASE + 0x00000304) | #define BLSP1_QUP_CONFIG_REG		(BLSP1_QUP_REG_BASE + 0x00000000) | ||||||
| #define GSBI7_SPI_IO_CONTROL_REG	(GSBI7_QUP7_REG_BASE + 0x00000304) |  | ||||||
|  |  | ||||||
| #define GSBI5_SPI_ERROR_FLAGS_REG	(GSBI5_QUP5_REG_BASE + 0x00000308) | #define BLSP0_QUP_ERROR_FLAGS_REG	(BLSP0_QUP_REG_BASE + 0x0000001c) | ||||||
| #define GSBI6_SPI_ERROR_FLAGS_REG	(GSBI6_QUP6_REG_BASE + 0x00000308) | #define BLSP1_QUP_ERROR_FLAGS_REG	(BLSP1_QUP_REG_BASE + 0x0000001c) | ||||||
| #define GSBI7_SPI_ERROR_FLAGS_REG	(GSBI7_QUP7_REG_BASE + 0x00000308) |  | ||||||
|  |  | ||||||
| #define GSBI5_SPI_ERROR_FLAGS_EN_REG	(GSBI5_QUP5_REG_BASE + 0x0000030c) | #define BLSP0_QUP_ERROR_FLAGS_EN_REG	(BLSP0_QUP_REG_BASE + 0x00000020) | ||||||
| #define GSBI6_SPI_ERROR_FLAGS_EN_REG	(GSBI6_QUP6_REG_BASE + 0x0000030c) | #define BLSP1_QUP_ERROR_FLAGS_EN_REG	(BLSP1_QUP_REG_BASE + 0x00000020) | ||||||
| #define GSBI7_SPI_ERROR_FLAGS_EN_REG	(GSBI7_QUP7_REG_BASE + 0x0000030c) |  | ||||||
|  |  | ||||||
| #define GSBI5_GSBI_CTRL_REG_REG		(GSBI5_REG_BASE + 0x00000000) | #define BLSP0_QUP_OPERATIONAL_MASK	(BLSP0_QUP_REG_BASE + 0x00000028) | ||||||
| #define GSBI6_GSBI_CTRL_REG_REG		(GSBI6_REG_BASE + 0x00000000) | #define BLSP1_QUP_OPERATIONAL_MASK	(BLSP1_QUP_REG_BASE + 0x00000028) | ||||||
| #define GSBI7_GSBI_CTRL_REG_REG		(GSBI7_REG_BASE + 0x00000000) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_CONFIG_REG		(GSBI5_QUP5_REG_BASE + 0x00000000) | #define BLSP0_QUP_OPERATIONAL_REG	(BLSP0_QUP_REG_BASE + 0x00000018) | ||||||
| #define GSBI6_QUP_CONFIG_REG		(GSBI6_QUP6_REG_BASE + 0x00000000) | #define BLSP1_QUP_OPERATIONAL_REG	(BLSP1_QUP_REG_BASE + 0x00000018) | ||||||
| #define GSBI7_QUP_CONFIG_REG		(GSBI7_QUP7_REG_BASE + 0x00000000) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_ERROR_FLAGS_REG	(GSBI5_QUP5_REG_BASE      + 0x0000001c) | #define BLSP0_QUP_IO_MODES_REG		(BLSP0_QUP_REG_BASE + 0x00000008) | ||||||
| #define GSBI6_QUP_ERROR_FLAGS_REG	(GSBI6_QUP6_REG_BASE      + 0x0000001c) | #define BLSP1_QUP_IO_MODES_REG		(BLSP1_QUP_REG_BASE + 0x00000008) | ||||||
| #define GSBI7_QUP_ERROR_FLAGS_REG	(GSBI7_QUP7_REG_BASE      + 0x0000001c) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_ERROR_FLAGS_EN_REG	(GSBI5_QUP5_REG_BASE + 0x00000020) | #define BLSP0_QUP_STATE_REG		(BLSP0_QUP_REG_BASE + 0x00000004) | ||||||
| #define GSBI6_QUP_ERROR_FLAGS_EN_REG	(GSBI6_QUP6_REG_BASE + 0x00000020) | #define BLSP1_QUP_STATE_REG		(BLSP1_QUP_REG_BASE + 0x00000004) | ||||||
| #define GSBI7_QUP_ERROR_FLAGS_EN_REG	(GSBI7_QUP7_REG_BASE + 0x00000020) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_OPERATIONAL_REG	(GSBI5_QUP5_REG_BASE + 0x00000018) | #define BLSP0_QUP_INPUT_FIFOc_REG(c) \ | ||||||
| #define GSBI6_QUP_OPERATIONAL_REG	(GSBI6_QUP6_REG_BASE + 0x00000018) | 		(BLSP0_QUP_REG_BASE + 0x00000218 + 4 * (c)) | ||||||
| #define GSBI7_QUP_OPERATIONAL_REG	(GSBI7_QUP7_REG_BASE + 0x00000018) | #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 BLSP0_QUP_OUTPUT_FIFOc_REG(c) \ | ||||||
| #define GSBI6_QUP_IO_MODES_REG		(GSBI6_QUP6_REG_BASE + 0x00000008) | 		(BLSP0_QUP_REG_BASE + 0x00000110 + 4 * (c)) | ||||||
| #define GSBI7_QUP_IO_MODES_REG		(GSBI7_QUP7_REG_BASE + 0x00000008) | #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 BLSP0_QUP_MX_INPUT_COUNT_REG	(BLSP0_QUP_REG_BASE + 0x00000200) | ||||||
| #define GSBI6_QUP_STATE_REG		(GSBI6_QUP6_REG_BASE + 0x00000004) | #define BLSP1_QUP_MX_INPUT_COUNT_REG	(BLSP1_QUP_REG_BASE + 0x00000200) | ||||||
| #define GSBI7_QUP_STATE_REG		(GSBI7_QUP7_REG_BASE + 0x00000004) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_OUT_FIFO_WORD_CNT_REG	(GSBI5_QUP5_REG_BASE + 0x0000010c) | #define BLSP0_QUP_MX_OUTPUT_COUNT_REG	(BLSP0_QUP_REG_BASE + 0x00000100) | ||||||
| #define GSBI6_QUP_OUT_FIFO_WORD_CNT_REG	(GSBI6_QUP6_REG_BASE + 0x0000010c) | #define BLSP1_QUP_MX_OUTPUT_COUNT_REG	(BLSP1_QUP_REG_BASE + 0x00000100) | ||||||
| #define GSBI7_QUP_OUT_FIFO_WORD_CNT_REG	(GSBI7_QUP7_REG_BASE + 0x0000010c) |  | ||||||
|  |  | ||||||
| #define GSBI5_QUP_IN_FIFO_WORD_CNT_REG	(GSBI5_QUP5_REG_BASE + 0x00000214) | #define BLSP0_QUP_SW_RESET_REG		(BLSP0_QUP_REG_BASE + 0x0000000c) | ||||||
| #define GSBI6_QUP_IN_FIFO_WORD_CNT_REG	(GSBI6_QUP6_REG_BASE + 0x00000214) | #define BLSP1_QUP_SW_RESET_REG		(BLSP1_QUP_REG_BASE + 0x0000000c) | ||||||
| #define GSBI7_QUP_IN_FIFO_WORD_CNT_REG	(GSBI7_QUP7_REG_BASE + 0x00000214) |  | ||||||
|  |  | ||||||
| #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_MSK		(0x0F << 8) | ||||||
| #define QUP_CONFIG_MINI_CORE_SPI		(1 << 8) | #define QUP_CONFIG_MINI_CORE_SPI		(1 << 8) | ||||||
| #define SPI_QUP_CONF_INPUT_MSK			(1 << 7) | #define QUP_CONF_INPUT_MSK			(1 << 7) | ||||||
| #define SPI_QUP_CONF_INPUT_ENA			(0 << 7) | #define QUP_CONF_INPUT_ENA			(0 << 7) | ||||||
| #define SPI_QUP_CONF_NO_INPUT			(1 << 7) | #define QUP_CONF_NO_INPUT			(1 << 7) | ||||||
| #define SPI_QUP_CONF_OUTPUT_MSK			(1 << 6) | #define QUP_CONF_OUTPUT_MSK			(1 << 6) | ||||||
| #define SPI_QUP_CONF_OUTPUT_ENA			(0 << 6) | #define QUP_CONF_OUTPUT_ENA			(0 << 6) | ||||||
| #define SPI_QUP_CONF_NO_OUTPUT			(1 << 6) | #define QUP_CONF_NO_OUTPUT			(1 << 6) | ||||||
| #define SPI_QUP_CONF_OUTPUT_ENA			(0 << 6) | #define QUP_CONF_N_MASK				0x1F | ||||||
| #define QUP_STATE_RESET_STATE			0x0 | #define QUP_CONF_N_SPI_8_BIT_WORD		0x07 | ||||||
| #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 GSBI_M_VAL_SHFT				16 | #define SPI_CONFIG_INPUT_FIRST			(1 << 9) | ||||||
| #define GSBIn_M_VAL_MSK				(0xFF << GSBI_M_VAL_SHFT) | #define SPI_CONFIG_INPUT_FIRST_BACK		(0 << 9) | ||||||
| #define GSBI_N_VAL_SHFT				16 | #define SPI_CONFIG_LOOP_BACK_MSK		(1 << 8) | ||||||
| #define GSBIn_N_VAL_MSK				(0xFF << GSBI_N_VAL_SHFT) | #define SPI_CONFIG_NO_LOOP_BACK			(0 << 8) | ||||||
| #define GSBI_D_VAL_SHFT				0 | #define SPI_CONFIG_NO_SLAVE_OPER_MSK		(1 << 5) | ||||||
| #define GSBIn_D_VAL_MSK				(0xFF << GSBI_D_VAL_SHFT) | #define SPI_CONFIG_NO_SLAVE_OPER		(0 << 5) | ||||||
| #define MNCNTR_RST_MSK				(1 << 7) |  | ||||||
| #define MNCNTR_RST_ENA				(1 << 7) | #define SPI_IO_CTRL_CLK_ALWAYS_ON		(0 << 9) | ||||||
| #define MNCNTR_RST_DIS				(0 << 7) | #define SPI_IO_CTRL_MX_CS_MODE			(1 << 8) | ||||||
| #define MNCNTR_MSK				(1 << 8) | #define SPI_IO_CTRL_NO_TRI_STATE		(1 << 0) | ||||||
| #define MNCNTR_EN				(1 << 8) | #define SPI_IO_CTRL_FORCE_CS_MSK		(1 << 11) | ||||||
| #define MNCNTR_DIS				(0 << 8) | #define SPI_IO_CTRL_FORCE_CS_EN			(1 << 11) | ||||||
| #define MNCNTR_MODE_MSK				(0x3 << 5) | #define SPI_IO_CTRL_FORCE_CS_DIS		(0 << 11) | ||||||
| #define MNCNTR_MODE_BYPASS			(0 << 5) | #define SPI_IO_CTRL_CLOCK_IDLE_HIGH		(1 << 10) | ||||||
| #define MNCNTR_MODE_DUAL_EDGE			(0x2 << 5) |  | ||||||
| #define GSBI_PRE_DIV_SEL_SHFT			3 | #define QUP_IO_MODES_OUTPUT_BIT_SHIFT_MSK	(1 << 16) | ||||||
| #define GSBIn_PRE_DIV_SEL_MSK			(0x3 << GSBI_PRE_DIV_SEL_SHFT) | #define QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN	(1 << 16) | ||||||
| #define GSBIn_PLL_SRC_MSK			(0x03 << 0) | #define QUP_IO_MODES_INPUT_MODE_MSK		(0x03 << 12) | ||||||
| #define GSBIn_PLL_SRC_PXO			(0 << 0) | #define QUP_IO_MODES_INPUT_BLOCK_MODE		(0x01 << 12) | ||||||
| #define GSBIn_PLL_SRC_PLL8			(0x3 << 0) | #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_INPUT_BLOCK_SIZE			4 | ||||||
| #define SPI_OUTPUT_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_RESET				0 | ||||||
| #define SPI_CORE_RUNNING			1 | #define SPI_CORE_RUNNING			1 | ||||||
| #define GSBI_SPI_MODE_0				0 | #define SPI_MODE0				0 | ||||||
| #define GSBI_SPI_MODE_1				1 | #define SPI_MODE1				1 | ||||||
| #define GSBI_SPI_MODE_2				2 | #define SPI_MODE2				2 | ||||||
| #define GSBI_SPI_MODE_3				3 | #define SPI_MODE3				3 | ||||||
| #define GSBI5_SPI				0 | #define BLSP0_SPI				0 | ||||||
| #define GSBI6_SPI				1 | #define BLSP1_SPI				1 | ||||||
| #define GSBI7_SPI				2 |  | ||||||
|  |  | ||||||
| struct gsbi_spi { | struct blsp_spi { | ||||||
| 	unsigned int     spi_config; | 	void *spi_config; | ||||||
| 	unsigned int     io_control; | 	void *io_control; | ||||||
| 	unsigned int     error_flags; | 	void *error_flags; | ||||||
| 	unsigned int     error_flags_en; | 	void *error_flags_en; | ||||||
| 	unsigned int     gsbi_ctrl; | 	void *qup_config; | ||||||
| 	unsigned int     qup_config; | 	void *qup_error_flags; | ||||||
| 	unsigned int     qup_error_flags; | 	void *qup_error_flags_en; | ||||||
| 	unsigned int     qup_error_flags_en; | 	void *qup_operational; | ||||||
| 	unsigned int     qup_operational; | 	void *qup_io_modes; | ||||||
| 	unsigned int     qup_io_modes; | 	void *qup_state; | ||||||
| 	unsigned int     qup_state; | 	void *qup_input_fifo; | ||||||
| 	unsigned int     qup_input_fifo; | 	void *qup_output_fifo; | ||||||
| 	unsigned int     qup_output_fifo; | 	void *qup_mx_input_count; | ||||||
| 	unsigned int     qup_mx_input_count; | 	void *qup_mx_output_count; | ||||||
| 	unsigned int     qup_mx_output_count; | 	void *qup_sw_reset; | ||||||
| 	unsigned int     qup_sw_reset; | 	void *qup_ns_reg; | ||||||
| 	unsigned int     qup_ns_reg; | 	void *qup_md_reg; | ||||||
| 	unsigned int     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 ipq_spi_slave { | ||||||
| 	struct spi_slave slave; | 	struct spi_slave slave; | ||||||
| 	const struct gsbi_spi *regs; | 	const struct blsp_spi *regs; | ||||||
| 	unsigned int mode; | 	unsigned int mode; | ||||||
| 	unsigned int initialized; | 	unsigned int initialized; | ||||||
| 	unsigned long freq; | 	unsigned long freq; | ||||||
|   | |||||||
| @@ -36,27 +36,35 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <soc/qup.h> | #include <soc/qup.h> | ||||||
|  |  | ||||||
| #define TIMEOUT_CNT	100000 | #define TIMEOUT_CNT	100 | ||||||
|  |  | ||||||
| //TODO: refactor the following array to iomap driver. | #define QUP_ADDR(id, reg)	(blsp_qup_base(id) + (reg)) | ||||||
| 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(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; | 		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) | 	if (reg_val & QUP_I2C_INVALID_READ_ADDR) | ||||||
| 		return QUP_ERR_I2C_INVALID_SLAVE_ADDR; | 		return QUP_ERR_I2C_INVALID_SLAVE_ADDR; | ||||||
| 	if (reg_val & QUP_I2C_FAILED_MASK) | 	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) | 		if (count == 0) | ||||||
| 			return QUP_ERR_TIMEOUT; | 			return QUP_ERR_TIMEOUT; | ||||||
| 		count--; | 		count--; | ||||||
| 		udelay(1); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return QUP_SUCCESS; | 	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 |  * 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. | 	 * The I2C_STATUS is a status register. | ||||||
| 	 * Bit31-25, Bit1 and Bit0 are reserved. | 	 * Writing any value clears the status bits. | ||||||
| 	 */ | 	 */ | ||||||
| 	//TODO: Define each status bit. OR all status bits in a single macro. | 	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS), 0); | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS), 0x3FFFFFC); |  | ||||||
| 	return QUP_SUCCESS; | 	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); | 	qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS), 0x3C); | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS_EN), 0x7C); | 	qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS_EN), 0x3C); | ||||||
| 	qup_reset_i2c_master_status(gsbi_id); | 	qup_reset_i2c_master_status(id); | ||||||
| 	return QUP_SUCCESS; | 	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; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
| 	unsigned int count = TIMEOUT_CNT; | 	unsigned int count = TIMEOUT_CNT; | ||||||
|  |  | ||||||
| 	while (!(read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status)) { | 	while (!(read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status)) { | ||||||
| 		ret = qup_i2c_master_status(gsbi_id); | 		ret = qup_i2c_master_status(id); | ||||||
| 		if (ret) | 		if (ret) | ||||||
| 			return ret; | 			return ret; | ||||||
| 		if (count == 0) | 		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; | 	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; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
| 	unsigned int count = TIMEOUT_CNT; | 	unsigned int count = TIMEOUT_CNT; | ||||||
|  |  | ||||||
| 	while (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status) { | 	while (read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status) { | ||||||
| 		ret = qup_i2c_master_status(gsbi_id); | 		ret = qup_i2c_master_status(id); | ||||||
| 		if (ret) | 		if (ret) | ||||||
| 			return ret; | 			return ret; | ||||||
| 		if (count == 0) | 		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; | 	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) | 				       uint8_t stop_seq) | ||||||
| { | { | ||||||
| 	qup_return_t ret = QUP_ERR_UNDEFINED; | 	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; | 	uint8_t *data_ptr = p_tx_obj->p.iic.data; | ||||||
| 	unsigned data_len = p_tx_obj->p.iic.data_len; | 	unsigned data_len = p_tx_obj->p.iic.data_len; | ||||||
| 	unsigned idx = 0; | 	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_reset_master_status(id); | ||||||
| 	qup_set_state(gsbi_id, QUP_STATE_RUN); |  | ||||||
|  |  | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO), | 	qup_set_state(id, QUP_STATE_RUN); | ||||||
| 		(QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr))); |  | ||||||
|  | 	/* | ||||||
|  | 	 * 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) { | 	while (data_len) { | ||||||
| 		if (data_len == 1 && stop_seq) { |  | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO), | 		tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq, | ||||||
| 				QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data_ptr[idx])); | 						data_ptr[idx]); | ||||||
| 		} else { |  | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO), |  | ||||||
| 				QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data_ptr[idx])); |  | ||||||
| 		} |  | ||||||
| 		data_len--; | 		data_len--; | ||||||
| 		idx++; | 		idx++; | ||||||
|  |  | ||||||
| 		if (data_len) { | 		if (data_len) { | ||||||
| 			ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_FULL); | 			tag |= qup_i2c_create_output_tag( | ||||||
| 			if (ret) | 						data_len == 1 && stop_seq, | ||||||
| 				return ret; | 						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 | 		qup_write32(fifo, tag); | ||||||
| 			register changes from 1 to 0, indicating that software | 		fifo++; | ||||||
| 			can write more data to the output FIFO. Software should |  | ||||||
| 			set OUTPUT_SERVICE_FLAG to 1 to clear it to 0, which | 		if ((fifo >= fifo_end) && data_len) { | ||||||
| 			means that software knows to return to fill the output |  | ||||||
| 			FIFO with data. | 			fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO); | ||||||
| 		 */ |  | ||||||
| 		if (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & | 			ret = qup_i2c_write_fifo_flush(id); | ||||||
| 				OUTPUT_SERVICE_FLAG) { |  | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), | 			if (ret) { | ||||||
| 				OUTPUT_SERVICE_FLAG); | 				printk(BIOS_DEBUG, "%s: error\n", __func__); | ||||||
|  | 				return ret; | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY); | 	ret = qup_i2c_write_fifo_flush(id); | ||||||
| 	if (ret) |  | ||||||
| 		return ret; |  | ||||||
|  |  | ||||||
| 	qup_set_state(gsbi_id, QUP_STATE_PAUSE); | 	qup_set_state(id, QUP_STATE_RESET); | ||||||
| 	return qup_i2c_master_status(gsbi_id); |  | ||||||
|  | 	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_data_t *p_tx_obj, uint8_t stop_seq) | ||||||
| { | { | ||||||
| 	qup_return_t ret = QUP_ERR_UNDEFINED; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
|  |  | ||||||
| 	switch (mode) { | 	switch (mode) { | ||||||
| 	case QUP_MODE_FIFO: | 	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; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		ret = QUP_ERR_UNSUPPORTED; | 		ret = QUP_ERR_UNSUPPORTED; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		qup_set_state(gsbi_id, QUP_STATE_RESET); | 		qup_set_state(id, QUP_STATE_RESET); | ||||||
| 		printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret); | 		printk(QUPDBG "%s() failed (%d)\n", __func__, ret); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return 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; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
| 	uint8_t addr = p_tx_obj->p.iic.addr; | 	uint8_t addr = p_tx_obj->p.iic.addr; | ||||||
| 	uint8_t *data_ptr = p_tx_obj->p.iic.data; | 	uint8_t *data_ptr = p_tx_obj->p.iic.data; | ||||||
| 	unsigned data_len = p_tx_obj->p.iic.data_len; | 	unsigned data_len = p_tx_obj->p.iic.data_len; | ||||||
| 	unsigned idx = 0; | 	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_reset_master_status(id); | ||||||
| 	qup_set_state(gsbi_id, QUP_STATE_RUN); |  | ||||||
|  |  | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO), | 	qup_set_state(id, QUP_STATE_RUN); | ||||||
| 		QUP_I2C_START_SEQ | (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ)); |  | ||||||
|  |  | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO), | 	qup_write32(fifo, (QUP_I2C_START_SEQ | | ||||||
| 		QUP_I2C_RECV_SEQ | data_len); | 				  (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); | 	ret = qup_i2c_write_fifo_flush(id); | ||||||
| 	if (ret) | 	if (ret) { | ||||||
|  | 		printk(QUPDBG "%s: OUTPUT_FIFO_NOT_EMPTY\n", __func__); | ||||||
| 		return ret; | 		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) { | 	while (data_len) { | ||||||
| 		uint32_t data; | 		uint32_t data; | ||||||
|  | 		int count; | ||||||
|  |  | ||||||
| 		ret = qup_fifo_wait_for(gsbi_id, INPUT_SERVICE_FLAG); | 		data = read32(fifo); | ||||||
| 		if (ret) | 		fifo++; | ||||||
| 			return ret; |  | ||||||
|  |  | ||||||
| 		data = read32(QUP_ADDR(gsbi_id, QUP_INPUT_FIFO)); | 		count = qup_i2c_parse_tag(data, data_ptr + idx, data_len); | ||||||
|  |  | ||||||
| 		/* | 		if (count < 0) { | ||||||
| 		 * Process tag and corresponding data value. For I2C master | 			printk(QUPDBG "%s: Cannot parse tag 0x%x\n", | ||||||
| 		 * mini-core, data in FIFO is composed of 16 bits and is divided | 						__func__, data); | ||||||
| 		 * into an 8-bit tag for the upper bits and 8-bit data for the | 			qup_set_state(id, QUP_STATE_PAUSE); | ||||||
| 		 * lower bits. The 8-bit tag indicates whether the byte is the |  | ||||||
| 		 * last byte, or if a bus error happened during the receipt of | 			return QUP_ERR_I2C_INVALID_TAG; | ||||||
| 		 * the byte. | 		} | ||||||
| 		 */ |  | ||||||
| 		if ((QUP_I2C_MI_TAG(data)) == QUP_I2C_MIDATA_SEQ) { | 		idx += count; | ||||||
| 			/* Tag: MIDATA = Master input data.*/ | 		data_len -= count; | ||||||
| 			data_ptr[idx] = QUP_I2C_DATA(data); |  | ||||||
| 			idx++; | 		if ((fifo >= fifo_end) || (data_len == 0)) { | ||||||
| 			data_len--; | 			fifo = QUP_ADDR(id, QUP_INPUT_FIFO); | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), | 			qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), | ||||||
| 				INPUT_SERVICE_FLAG); | 					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; | 	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; | 	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_data_t *p_tx_obj) | ||||||
| { | { | ||||||
| 	qup_return_t ret = QUP_ERR_UNDEFINED; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
|  |  | ||||||
|  | 	qup_set_state(id, QUP_STATE_RESET); | ||||||
|  |  | ||||||
| 	switch (mode) { | 	switch (mode) { | ||||||
| 	case QUP_MODE_FIFO: | 	case QUP_MODE_FIFO: | ||||||
| 		ret = qup_i2c_read_fifo(gsbi_id, p_tx_obj); | 		ret = qup_i2c_read_fifo(id, p_tx_obj); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		ret = QUP_ERR_UNSUPPORTED; | 		ret = QUP_ERR_UNSUPPORTED; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		qup_set_state(gsbi_id, QUP_STATE_RESET); | 		qup_set_state(id, QUP_STATE_RESET); | ||||||
| 		printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret); | 		printk(QUPDBG "%s() failed (%d)\n", __func__, ret); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return 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; | 	qup_return_t ret = QUP_ERR_UNDEFINED; | ||||||
| 	uint32_t reg_val; | 	uint32_t reg_val; | ||||||
|  |  | ||||||
| 	/* Reset the QUP core.*/ | 	/* 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 */ | 	/* 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) | 	if (ret) | ||||||
| 		goto bailout; | 		goto bailout; | ||||||
|  |  | ||||||
| 	/* Reset the config */ | 	/* Reset the config */ | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_CONFIG), 0); | 	qup_write32(QUP_ADDR(id, QUP_CONFIG), 0); | ||||||
|  |  | ||||||
| 	/*Program the config register*/ | 	/* Program the config register */ | ||||||
| 	/*Set N value*/ | 	/* Set N value */ | ||||||
| 	reg_val = 0x0F; | 	reg_val = 0x0F; | ||||||
| 	/*Set protocol*/ | 	/* Set protocol */ | ||||||
| 	switch (config_ptr->protocol) { | 	switch (config_ptr->protocol) { | ||||||
| 	case QUP_MINICORE_I2C_MASTER: | 	case QUP_MINICORE_I2C_MASTER: | ||||||
| 		reg_val |= ((config_ptr->protocol & | 		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; | 		ret = QUP_ERR_UNSUPPORTED; | ||||||
| 		goto bailout; | 		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*/ | 	/* Choose version 1 tag */ | ||||||
| 	write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), 0); | 	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) { | 	switch (config_ptr->mode) { | ||||||
| 	case QUP_MODE_FIFO: | 	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) << | 			  ((config_ptr->mode & QUP_MODE_MASK) << | ||||||
| 					QUP_OUTPUT_MODE_SHFT) | | 					QUP_OUTPUT_MODE_SHFT) | | ||||||
| 			  ((config_ptr->mode & QUP_MODE_MASK) << | 			  ((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; | 		ret = QUP_ERR_UNSUPPORTED; | ||||||
| 		goto bailout; | 		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*/ | 	/*Set i2c clk cntl*/ | ||||||
| 	reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT); | 	reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT); | ||||||
| 	reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency) | 	reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency) | ||||||
| 			/ 2) - QUP_DIVIDER_MIN_VAL) & | 			/ 2) - QUP_DIVIDER_MIN_VAL) & | ||||||
| 				QUP_FS_DIVIDER_MASK); | 				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: | bailout: | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		printk(BIOS_ERR, "failed to init qup (%d)\n", ret); | 		printk(QUPDBG "failed to init qup (%d)\n", ret); | ||||||
|  |  | ||||||
| 	return 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; | 	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) | 	if ((state >= QUP_STATE_RESET && state <= QUP_STATE_PAUSE) | ||||||
| 		&& (curr_state & QUP_STATE_VALID_MASK)) { | 		&& (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. | 		* transition to complete. | ||||||
| 		*/ | 		*/ | ||||||
| 		if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) { | 		if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) { | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2); | 			qup_write32(QUP_ADDR(id, QUP_STATE), 0x2); | ||||||
| 			write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2); | 			qup_write32(QUP_ADDR(id, QUP_STATE), 0x2); | ||||||
| 		} else { | 		} 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; | 	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) | 				      uint8_t stop_seq) | ||||||
| { | { | ||||||
| 	qup_return_t ret = QUP_ERR_UNDEFINED; | 	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; | 			QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK; | ||||||
|  |  | ||||||
| 	ret = qup_i2c_write(gsbi_id, mode, p_tx_obj, stop_seq); | 	ret = qup_i2c_write(id, mode, p_tx_obj, stop_seq); | ||||||
| 	if (0) { | 	if (QUP_DEBUG) { | ||||||
| 		int i; | 		int i; | ||||||
|  |  | ||||||
| 		printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:", | 		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++) | 		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, " %2.2x", p_tx_obj->p.iic.data[i]); | ||||||
| 		printk(BIOS_DEBUG, "\n"); | 		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; | 	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) | 			   uint8_t stop_seq) | ||||||
| { | { | ||||||
| 	qup_return_t ret = QUP_ERR_UNDEFINED; | 	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)) { | 			QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) { | ||||||
| 		switch (p_tx_obj->protocol) { | 		switch (p_tx_obj->protocol) { | ||||||
| 		case QUP_MINICORE_I2C_MASTER: | 		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; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			ret = QUP_ERR_UNSUPPORTED; | 			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; | 	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; | 	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; | 			QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK; | ||||||
|  |  | ||||||
| 	ret = qup_i2c_read(gsbi_id, mode, p_rx_obj); | 	ret = qup_i2c_read(id, mode, p_rx_obj); | ||||||
| 	if (0) { | 	if (QUP_DEBUG) { | ||||||
| 		int i; | 		int i; | ||||||
|  |  | ||||||
| 		printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:", | 		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++) | 		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, " %2.2x", p_rx_obj->p.iic.data[i]); | ||||||
| 		printk(BIOS_DEBUG, "\n"); | 		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; | 	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; | 	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)) { | 			QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) { | ||||||
| 		switch (p_rx_obj->protocol) { | 		switch (p_rx_obj->protocol) { | ||||||
| 		case QUP_MINICORE_I2C_MASTER: | 		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; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			ret = QUP_ERR_UNSUPPORTED; | 			ret = QUP_ERR_UNSUPPORTED; | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -35,7 +35,7 @@ | |||||||
| #include <delay.h> | #include <delay.h> | ||||||
| #include <gpio.h> | #include <gpio.h> | ||||||
| #include <soc/clock.h> | #include <soc/clock.h> | ||||||
| #include <soc/gsbi.h> | #include <soc/blsp.h> | ||||||
| #include <soc/ipq_uart.h> | #include <soc/ipq_uart.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user