From c0699975cf215f03d8d19df3f0f923a74f2aff9d Mon Sep 17 00:00:00 2001 From: Ruibin Chang Date: Mon, 17 Feb 2020 13:44:30 +0800 Subject: driver/tcpm/it8xxx2: PD driver for chip it8xxx1/8xxx2 Add PD driver for chip it8xxx1/8xxx2 series. BRANCH=none BUG=none TEST=test below functions on PDEVB port0, 1, 2 with TCPMv1 (set cc toggle by console cmd): 1.pin configuration console cmd "gpioget" check gpio settings. memory dump check cc pin alternate settings. 2.Tx data error handle Message discard, No GoodCRC, Tx not enable, Timeout errors happen, corresponding INT will be triggered then do properly handle. 3.basic pd connection SNK:connect with adaptor, request max power (15V,3A), state SNK_READY. SRC:enable DRP role, connect with dongle, provide power (5V,1.5A), source Vconn 5v, get ack of cable discover id, state SRC_READY. 4.pd module disable SNK:connect with adapter. console cmd "hibernate sec", driver disable pd module, check still connection with adapter via dead battery rd. And when resume from hibernate, pd init can re-enable pd module, re-connect with adapter. SRC:connect with dongle. console cmd "hibernate sec", driver disable pd module, check cc pin (not Vconn source pin) volt power down to ~0v. And when resume from hibernate, pd init can re-enable pd module, re-connect with dongle. 5.Tx hard reset console cmd "pd port hard", check hard reset message by lecroy analyzer. 6.Tx cable reset check cable reset message by lecroy analyzer. 7.SOP' enable SRC:connects to SNK via E-mark cable. Source Vconn successfully, and receives cable's ack of discover id request. Not source Vconn to cable, and receives nothing of discover id request (this isn't effect on request SNK flow). 8.power role swap console cmd "pd port swap power", check pd protocol by lecroy. Change-Id: I687e0e65e2687ebbb790eb1e1c8c459305f4dbc1 Signed-off-by: Ruibin Chang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2009538 Reviewed-by: Jett Rink --- chip/it83xx/clock.c | 16 +++---- chip/it83xx/config_chip_it8320.h | 4 ++ chip/it83xx/config_chip_it8xxx2.h | 4 ++ chip/it83xx/gpio.c | 49 ++++++++++++++------ chip/it83xx/intc.c | 47 ++++++++++++------- chip/it83xx/registers.h | 95 +-------------------------------------- 6 files changed, 84 insertions(+), 131 deletions(-) (limited to 'chip') diff --git a/chip/it83xx/clock.c b/chip/it83xx/clock.c index 00acf8864e..755644ce9e 100644 --- a/chip/it83xx/clock.c +++ b/chip/it83xx/clock.c @@ -505,14 +505,14 @@ void __enter_hibernate(uint32_t seconds, uint32_t microseconds) ext_timer_start(FREE_EXT_TIMER_L, 0); } -#ifdef CONFIG_USB_PD_TCPM_ITE83XX - /* - * Disable integrated pd modules in hibernate for - * better power consumption. - */ - for (i = 0; i < IT83XX_USBPD_PHY_PORT_COUNT; i++) - it83xx_disable_pd_module(i); -#endif + if (IS_ENABLED(CONFIG_USB_PD_TCPM_ITE_ON_CHIP)) { + /* + * Disable integrated pd modules in hibernate for + * better power consumption. + */ + for (i = 0; i < IT83XX_USBPD_PHY_PORT_COUNT; i++) + it83xx_disable_pd_module(i); + } for (i = 0; i < hibernate_wake_pins_used; ++i) gpio_enable_interrupt(hibernate_wake_pins[i]); diff --git a/chip/it83xx/config_chip_it8320.h b/chip/it83xx/config_chip_it8320.h index 9fedd8258a..2ae98fe888 100644 --- a/chip/it83xx/config_chip_it8320.h +++ b/chip/it83xx/config_chip_it8320.h @@ -26,6 +26,10 @@ #define CONFIG_PROGRAM_MEMORY_BASE 0x00000000 +/****************************************************************************/ +/* Chip IT8320 is used with IT83XX TCPM driver */ +#define CONFIG_USB_PD_TCPM_DRIVER_IT83XX + #if defined(CHIP_VARIANT_IT8320BX) /* This is the physical size of the flash on the chip. We'll reserve one bank * in order to emulate per-bank write-protection UNTIL REBOOT. The hardware diff --git a/chip/it83xx/config_chip_it8xxx2.h b/chip/it83xx/config_chip_it8xxx2.h index 01e4b6eda2..036736fd70 100644 --- a/chip/it83xx/config_chip_it8xxx2.h +++ b/chip/it83xx/config_chip_it8xxx2.h @@ -30,6 +30,10 @@ #define CONFIG_PROGRAM_MEMORY_BASE (CHIP_ILM_BASE) +/****************************************************************************/ +/* Chip IT83202 is used with IT8XXX2 TCPM driver */ +#define CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 + #if defined(CHIP_VARIANT_IT83202BX) /* TODO(b/133460224): enable properly chip config option. */ #define CONFIG_FLASH_SIZE 0x00080000 diff --git a/chip/it83xx/gpio.c b/chip/it83xx/gpio.c index c753e095e0..cdef32384a 100644 --- a/chip/it83xx/gpio.c +++ b/chip/it83xx/gpio.c @@ -10,6 +10,7 @@ #include "gpio.h" #include "hooks.h" #include "intc.h" +#include "it83xx_pd.h" #include "kmsc_chip.h" #include "registers.h" #include "switch.h" @@ -633,6 +634,29 @@ int gpio_clear_pending_interrupt(enum gpio_signal signal) return EC_SUCCESS; } +/* To prevent cc pins leakage, disables integrated cc module. */ +void it83xx_disable_cc_module(int port) +{ + /* Power down all CC, and disable CC voltage detector */ + IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC; +#if defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) + IT83XX_USBPD_CCCSR(port) |= USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR; +#elif defined(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2) + IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR; +#endif + /* + * Disconnect CC analog module (ex.UP/RD/DET/TX/RX), and + * disconnect CC 5.1K to GND + */ + IT83XX_USBPD_CCCSR(port) |= (USBPD_REG_MASK_CC2_DISCONNECT | + USBPD_REG_MASK_CC2_DISCONNECT_5_1K_TO_GND | + USBPD_REG_MASK_CC1_DISCONNECT | + USBPD_REG_MASK_CC2_DISCONNECT_5_1K_TO_GND); + /* Disconnect CC 5V tolerant */ + IT83XX_USBPD_CCPSR(port) |= (USBPD_REG_MASK_DISCONNECT_POWER_CC2 | + USBPD_REG_MASK_DISCONNECT_POWER_CC1); +} + void gpio_pre_init(void) { const struct gpio_info *g = gpio_list; @@ -642,20 +666,19 @@ void gpio_pre_init(void) IT83XX_GPIO_GCR = 0x06; -#ifndef CONFIG_USB_PD_TCPM_ITE83XX - /* To prevent cc pins leakage if we don't use pd module */ - for (i = 0; i < IT83XX_USBPD_PHY_PORT_COUNT; i++) { - IT83XX_USBPD_CCGCR(i) = 0x1f; - /* - * bit7 and bit3: Dis-connect CC with UP/RD/DET/TX/RX. - * bit6 and bit2: Dis-connect CC with 5.1K resister to GND. - * bit5 and bit1: Disable CC voltage detector. - * bit4 and bit0: Disable CC. - */ - IT83XX_USBPD_CCCSR(i) = 0xff; - IT83XX_USBPD_CCPSR(i) = 0x66; + /* + * To prevent cc pins leakage ... + * If we don't use ITE TCPC: disable all ITE port cc modules. + */ + if (!IS_ENABLED(CONFIG_USB_PD_TCPM_ITE_ON_CHIP)) { + for (i = 0; i < IT83XX_USBPD_PHY_PORT_COUNT; i++) { + it83xx_disable_cc_module(i); + /* Dis-connect 5.1K dead battery resistor to CC */ + IT83XX_USBPD_CCPSR(i) |= + (USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB | + USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB); + } } -#endif #ifndef CONFIG_USB /* diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c index e109773eba..1a6e6c74dc 100644 --- a/chip/it83xx/intc.c +++ b/chip/it83xx/intc.c @@ -12,7 +12,7 @@ #include "tcpm.h" #include "usb_pd.h" -#ifdef CONFIG_USB_PD_TCPM_ITE83XX +#if defined(CONFIG_USB_PD_TCPM_ITE_ON_CHIP) static void chip_pd_irq(enum usbpd_port port) { task_clear_pending_irq(usbpd_ctrl_regs[port].irq); @@ -23,19 +23,28 @@ static void chip_pd_irq(enum usbpd_port port) IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_HARD_RESET_DETECT; task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_TCPC_RESET, 0); - } else { - if (USBPD_IS_RX_DONE(port)) { - tcpm_enqueue_message(port); - /* clear RX done interrupt */ - IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_RX_DONE; - } - if (USBPD_IS_TX_DONE(port)) { - /* clear TX done interrupt */ - IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_TX_DONE; - task_set_event(PD_PORT_TO_TASK_ID(port), - TASK_EVENT_PHY_TX_DONE, 0); - } -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT + } + + if (USBPD_IS_RX_DONE(port)) { + tcpm_enqueue_message(port); + /* clear RX done interrupt */ + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_RX_DONE; + } + + if (USBPD_IS_TX_DONE(port)) { +#ifdef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 + it83xx_clear_tx_error_status(port); + /* check TX status, clear by TX_DONE status too */ + if (USBPD_IS_TX_ERR(port)) + it83xx_get_tx_error_status(port); +#endif + /* clear TX done interrupt */ + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_TX_DONE; + task_set_event(PD_PORT_TO_TASK_ID(port), + TASK_EVENT_PHY_TX_DONE, 0); + } + + if (IS_ENABLED(IT83XX_INTC_PLUG_IN_SUPPORT)) { if (USBPD_IS_PLUG_IN_OUT_DETECT(port)) { /* * When tcpc detect type-c plug in, then disable @@ -56,7 +65,6 @@ static void chip_pd_irq(enum usbpd_port port) task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); } -#endif //IT83XX_INTC_PLUG_IN_SUPPORT } } #endif @@ -135,7 +143,7 @@ void intc_cpu_int_group_12(void) espi_vw_interrupt(); break; #endif -#ifdef CONFIG_USB_PD_TCPM_ITE83XX +#ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP case IT83XX_IRQ_USBPD0: chip_pd_irq(USBPD_PORT_A); break; @@ -143,7 +151,12 @@ void intc_cpu_int_group_12(void) case IT83XX_IRQ_USBPD1: chip_pd_irq(USBPD_PORT_B); break; -#endif /* CONFIG_USB_PD_TCPM_ITE83XX */ +#ifdef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 + case IT83XX_IRQ_USBPD2: + chip_pd_irq(USBPD_PORT_C); + break; +#endif +#endif #ifdef CONFIG_SPI case IT83XX_IRQ_SPI_SLAVE: spi_slv_int_handler(); diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index af76705274..dfa8c2ad11 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -750,6 +750,8 @@ #define IT83XX_GPIO_GPCRL1 REG8(IT83XX_GPIO_BASE+0x99) #define IT83XX_GPIO_GPCRL2 REG8(IT83XX_GPIO_BASE+0x9A) #define IT83XX_GPIO_GPCRL3 REG8(IT83XX_GPIO_BASE+0x9B) +#define IT83XX_GPIO_GPCRP0 REG8(IT83XX_GPIO2_BASE+0x18) +#define IT83XX_GPIO_GPCRP1 REG8(IT83XX_GPIO2_BASE+0x19) #define IT83XX_GPIO_GRC1 REG8(IT83XX_GPIO_BASE+0xF0) #define IT83XX_GPIO_GRC2 REG8(IT83XX_GPIO_BASE+0xF1) @@ -1456,99 +1458,6 @@ enum i2c_channels { IT83XX_I2C_PORT_COUNT, }; -/* USBPD Controller */ -#define IT83XX_USBPD_BASE(port) (0x00F03700 + (0x100 * (port))) - -#define IT83XX_USBPD_GCR(p) REG8(IT83XX_USBPD_BASE(p)+0x0) -#define USBPD_REG_MASK_SW_RESET_BIT BIT(7) -#define USBPD_REG_MASK_TYPE_C_DETECT_RESET BIT(6) -#define USBPD_REG_MASK_BMC_PHY BIT(4) -#define USBPD_REG_MASK_AUTO_SEND_SW_RESET BIT(3) -#define USBPD_REG_MASK_AUTO_SEND_HW_RESET BIT(2) -#define USBPD_REG_MASK_SNIFFER_MODE BIT(1) -#define USBPD_REG_MASK_GLOBAL_ENABLE BIT(0) -#define IT83XX_USBPD_PDMSR(p) REG8(IT83XX_USBPD_BASE(p)+0x01) -#define USBPD_REG_MASK_SOPPP_ENABLE BIT(7) -#define USBPD_REG_MASK_SOPP_ENABLE BIT(6) -#define USBPD_REG_MASK_SOP_ENABLE BIT(5) -#define IT83XX_USBPD_CCGCR(p) REG8(IT83XX_USBPD_BASE(p)+0x04) -#define USBPD_REG_MASK_DISABLE_CC BIT(4) -#define IT83XX_USBPD_CCCSR(p) REG8(IT83XX_USBPD_BASE(p)+0x05) -#ifdef IT83XX_USBPD_CC_VOLTAGE_DETECTOR_INDEPENDENT -#define IT83XX_USBPD_REG_MASK_CC1_DISCONNECT (BIT(3) | BIT(1)) -#define IT83XX_USBPD_REG_MASK_CC2_DISCONNECT (BIT(7) | BIT(5)) -#else -#define IT83XX_USBPD_REG_MASK_CC1_DISCONNECT BIT(3) -#define IT83XX_USBPD_REG_MASK_CC2_DISCONNECT BIT(7) -#endif -#define USBPD_CC1_DISCONNECTED(p) \ - ((IT83XX_USBPD_CCCSR(p) | IT83XX_USBPD_REG_MASK_CC1_DISCONNECT) & \ - ~IT83XX_USBPD_REG_MASK_CC2_DISCONNECT) -#define USBPD_CC2_DISCONNECTED(p) \ - ((IT83XX_USBPD_CCCSR(p) | IT83XX_USBPD_REG_MASK_CC2_DISCONNECT) & \ - ~IT83XX_USBPD_REG_MASK_CC1_DISCONNECT) - -#define IT83XX_USBPD_CCPSR(p) REG8(IT83XX_USBPD_BASE(p)+0x06) -#define USBPD_REG_MASK_DISCONNECT_POWER_CC2 BIT(5) -#define USBPD_REG_MASK_DISCONNECT_POWER_CC1 BIT(1) -#define IT83XX_USBPD_DFPVDR(p) REG8(IT83XX_USBPD_BASE(p)+0x08) -#define IT83XX_USBPD_UFPVDR(p) REG8(IT83XX_USBPD_BASE(p)+0x09) -#define IT83XX_USBPD_CCADCR(p) REG8(IT83XX_USBPD_BASE(p)+0x0C) -#define IT83XX_USBPD_ISR(p) REG8(IT83XX_USBPD_BASE(p)+0x14) -#define USBPD_REG_MASK_TYPE_C_DETECT BIT(7) -#define USBPD_REG_MASK_CABLE_RESET_DETECT BIT(6) -#define USBPD_REG_MASK_HARD_RESET_DETECT BIT(5) -#define USBPD_REG_MASK_MSG_RX_DONE BIT(4) -#define USBPD_REG_MASK_AUTO_SOFT_RESET_TX_DONE BIT(3) -#define USBPD_REG_MASK_HARD_RESET_TX_DONE BIT(2) -#define USBPD_REG_MASK_MSG_TX_DONE BIT(1) -#define USBPD_REG_MASK_TIMER_TIMEOUT BIT(0) -#define IT83XX_USBPD_IMR(p) REG8(IT83XX_USBPD_BASE(p)+0x15) -#define IT83XX_USBPD_MTCR(p) REG8(IT83XX_USBPD_BASE(p)+0x18) -#define USBPD_REG_MASK_SW_RESET_TX_STAT BIT(3) -#define USBPD_REG_MASK_TX_BUSY_STAT BIT(2) -#define USBPD_REG_MASK_TX_DISCARD_STAT BIT(2) -#ifdef IT83XX_PD_TX_ERROR_STATUS_BIT5 -#define USBPD_REG_MASK_TX_ERR_STAT BIT(5) -#else -#define USBPD_REG_MASK_TX_ERR_STAT BIT(1) -#endif -#define USBPD_REG_MASK_TX_START BIT(0) -#define IT83XX_USBPD_MTSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x19) -#define USBPD_REG_MASK_CABLE_ENABLE BIT(7) -#define USBPD_REG_MASK_SEND_HW_RESET BIT(6) -#define USBPD_REG_MASK_SEND_BIST_MODE_2 BIT(5) -#define IT83XX_USBPD_MTSR1(p) REG8(IT83XX_USBPD_BASE(p)+0x1A) -#define IT83XX_USBPD_VDMMCSR(p) REG8(IT83XX_USBPD_BASE(p)+0x1B) -#define IT83XX_USBPD_MRSR(p) REG8(IT83XX_USBPD_BASE(p)+0x1C) -#define USBPD_REG_MASK_RX_MSG_VALID BIT(0) -#define IT83XX_USBPD_PEFSMR(p) REG8(IT83XX_USBPD_BASE(p)+0x1D) -#define IT83XX_USBPD_PES0R(p) REG8(IT83XX_USBPD_BASE(p)+0x1E) -#define IT83XX_USBPD_PES1R(p) REG8(IT83XX_USBPD_BASE(p)+0x1F) -#define IT83XX_USBPD_TDO(p) REG32(IT83XX_USBPD_BASE(p)+0x20) -#define IT83XX_USBPD_AGTMHLR(p) REG8(IT83XX_USBPD_BASE(p)+0x3C) -#define IT83XX_USBPD_AGTMHHR(p) REG8(IT83XX_USBPD_BASE(p)+0x3D) -#define IT83XX_USBPD_TMHLR(p) REG8(IT83XX_USBPD_BASE(p)+0x3E) -#define IT83XX_USBPD_TMHHR(p) REG8(IT83XX_USBPD_BASE(p)+0x3F) -#define IT83XX_USBPD_RDO0(p) REG32(IT83XX_USBPD_BASE(p)+0x40) -#define IT83XX_USBPD_RMH(p) REG16(IT83XX_USBPD_BASE(p)+0x5E) -#define IT83XX_USBPD_CCPSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x60) -#define IT83XX_USBPD_BMCSR(p) REG8(IT83XX_USBPD_BASE(p)+0x64) -#define IT83XX_USBPD_PDMHSR(p) REG8(IT83XX_USBPD_BASE(p)+0x65) -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT -#define IT83XX_USBPD_TCDCR(p) REG8(IT83XX_USBPD_BASE(p)+0x67) -#define USBPD_REG_PLUG_OUT_DETECT_TYPE_SELECT BIT(7) -#define USBPD_REG_MASK_TYPEC_PLUG_IN_OUT_ISR BIT(4) -#define USBPD_REG_PLUG_IN_OUT_SELECT BIT(3) -#define USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE BIT(1) -#define USBPD_REG_PLUG_IN_OUT_DETECT_STAT BIT(0) -#endif //IT83XX_INTC_PLUG_IN_SUPPORT - -enum usbpd_port { - USBPD_PORT_A, - USBPD_PORT_B, -}; - #define USB_VID_ITE 0x048d #define IT83XX_ESPI_BASE 0x00F03100 -- cgit v1.2.1