diff options
-rw-r--r-- | baseboard/dragonegg/baseboard.h | 2 | ||||
-rw-r--r-- | baseboard/intelrvp/build.mk | 2 | ||||
-rw-r--r-- | baseboard/intelrvp/ite_ec.h | 2 | ||||
-rw-r--r-- | baseboard/octopus/baseboard.h | 2 | ||||
-rw-r--r-- | board/it83xx_evb/board.h | 2 | ||||
-rw-r--r-- | board/reef_it8320/board.h | 2 | ||||
-rw-r--r-- | chip/it83xx/clock.c | 16 | ||||
-rw-r--r-- | chip/it83xx/config_chip_it8320.h | 4 | ||||
-rw-r--r-- | chip/it83xx/config_chip_it8xxx2.h | 4 | ||||
-rw-r--r-- | chip/it83xx/gpio.c | 49 | ||||
-rw-r--r-- | chip/it83xx/intc.c | 47 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 95 | ||||
-rw-r--r-- | driver/build.mk | 5 | ||||
-rw-r--r-- | driver/tcpm/it83xx.c | 5 | ||||
-rw-r--r-- | driver/tcpm/it83xx_pd.h | 265 | ||||
-rw-r--r-- | driver/tcpm/it8xxx2.c | 676 | ||||
-rw-r--r-- | include/config.h | 16 |
17 files changed, 1047 insertions, 147 deletions
diff --git a/baseboard/dragonegg/baseboard.h b/baseboard/dragonegg/baseboard.h index e34f5d11c3..d0d3c31486 100644 --- a/baseboard/dragonegg/baseboard.h +++ b/baseboard/dragonegg/baseboard.h @@ -78,7 +78,7 @@ #undef CONFIG_USB_PD_TCPC_LOW_POWER #undef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_VBUS_DETECT_PPC -#define CONFIG_USB_PD_TCPM_ITE83XX /* C0 & C1 TCPC: ITE EC */ +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP /* C0 & C1 TCPC: ITE EC */ #define CONFIG_USB_PD_TCPM_TUSB422 /* C1 TCPC: TUSB422 */ #define CONFIG_USB_POWER_DELIVERY /* diff --git a/baseboard/intelrvp/build.mk b/baseboard/intelrvp/build.mk index 4247a38948..12a62ffffc 100644 --- a/baseboard/intelrvp/build.mk +++ b/baseboard/intelrvp/build.mk @@ -13,7 +13,7 @@ baseboard-$(CONFIG_BATTERY_SMART)+=battery.o baseboard-$(CONFIG_USB_POWER_DELIVERY)+=chg_usb_pd.o usb_pd_policy.o #EC specific files -baseboard-$(CONFIG_USB_PD_TCPM_ITE83XX)+=ite_ec.o +baseboard-$(CONFIG_USB_PD_TCPM_ITE_ON_CHIP)+=ite_ec.o #BC1.2 specific files baseboard-$(CONFIG_BC12_DETECT_MAX14637)+=bc12.o diff --git a/baseboard/intelrvp/ite_ec.h b/baseboard/intelrvp/ite_ec.h index 35014c0fd1..14d9b27370 100644 --- a/baseboard/intelrvp/ite_ec.h +++ b/baseboard/intelrvp/ite_ec.h @@ -9,7 +9,7 @@ #define __CROS_EC_ITE_EC_H /* USB PD config */ -#define CONFIG_USB_PD_TCPM_ITE83XX +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP #define CONFIG_USB_PD_VBUS_DETECT_GPIO /* Optional feature - used by ITE */ diff --git a/baseboard/octopus/baseboard.h b/baseboard/octopus/baseboard.h index 4001c2bb2d..44ea94286b 100644 --- a/baseboard/octopus/baseboard.h +++ b/baseboard/octopus/baseboard.h @@ -172,7 +172,7 @@ #undef CONFIG_USB_PD_TCPC_LOW_POWER #undef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_VBUS_DETECT_PPC - #define CONFIG_USB_PD_TCPM_ITE83XX /* C0 & C1 TCPC: ITE EC */ + #define CONFIG_USB_PD_TCPM_ITE_ON_CHIP /* C0 & C1 TCPC: ITE EC */ #define CONFIG_USB_MUX_IT5205 /* C0 MUX: IT5205 */ #define CONFIG_USB_PD_TCPM_PS8751 /* C1 Mux: PS8751 */ #define CONFIG_USBC_PPC_SN5S330 /* C0 & C1 PPC: each SN5S330 */ diff --git a/board/it83xx_evb/board.h b/board/it83xx_evb/board.h index 45571f8423..97083d28b8 100644 --- a/board/it83xx_evb/board.h +++ b/board/it83xx_evb/board.h @@ -42,7 +42,7 @@ #define CONFIG_USB_PD_CUSTOM_PDO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_PORT_MAX_COUNT 2 -#define CONFIG_USB_PD_TCPM_ITE83XX +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP #define CONFIG_USB_PD_TRY_SRC #define CONFIG_USB_PD_VBUS_DETECT_GPIO #define CONFIG_USB_POWER_DELIVERY diff --git a/board/reef_it8320/board.h b/board/reef_it8320/board.h index 1273e93a75..46a6c76927 100644 --- a/board/reef_it8320/board.h +++ b/board/reef_it8320/board.h @@ -74,7 +74,7 @@ #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_MAX_COUNT 2 #define CONFIG_USB_PD_VBUS_DETECT_CHARGER -#define CONFIG_USB_PD_TCPM_ITE83XX +#define CONFIG_USB_PD_TCPM_ITE_ON_CHIP #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TRY_SRC #define CONFIG_USB_POWER_DELIVERY 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 diff --git a/driver/build.mk b/driver/build.mk index ee2afde542..ad51fa0a96 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -123,7 +123,10 @@ driver-$(CONFIG_USB_PD_TCPM_STUB)+=tcpm/stub.o driver-$(CONFIG_USB_PD_TCPM_TCPCI)+=tcpm/tcpci.o driver-$(CONFIG_USB_PD_TCPM_FUSB302)+=tcpm/fusb302.o driver-$(CONFIG_USB_PD_TCPM_MT6370)+=tcpm/mt6370.o -driver-$(CONFIG_USB_PD_TCPM_ITE83XX)+=tcpm/it83xx.o +ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP +driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT83XX)+=tcpm/it83xx.o +driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2)+=tcpm/it8xxx2.o +endif driver-$(CONFIG_USB_PD_TCPM_ANX74XX)+=tcpm/anx74xx.o driver-$(CONFIG_USB_PD_TCPM_ANX7688)+=tcpm/anx7688.o driver-$(CONFIG_USB_PD_TCPM_ANX7447)+=tcpm/anx7447.o diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c index d3c36ee1fc..e026503a51 100644 --- a/driver/tcpm/it83xx.c +++ b/driver/tcpm/it83xx.c @@ -368,7 +368,7 @@ static void it83xx_init(enum usbpd_port port, int role) * is enable). */ IT83XX_USBPD_TCDCR(port) = USBPD_REG_PLUG_IN_OUT_DETECT_STAT; -#endif //IT83XX_INTC_PLUG_IN_SUPPORT +#endif IT83XX_USBPD_CCPSR(port) = 0xff; /* cc connect */ IT83XX_USBPD_CCCSR(port) = 0; @@ -627,13 +627,14 @@ static int it83xx_tcpm_get_chip_info(int port, int live, static void it83xx_tcpm_sw_reset(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + #ifdef IT83XX_INTC_PLUG_IN_SUPPORT /* * Enable detect type-c plug in interrupt, since the pd task has * detected a type-c physical disconnected. */ IT83XX_USBPD_TCDCR(port) &= ~USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE; -#endif //IT83XX_INTC_PLUG_IN_SUPPORT +#endif /* exit BIST test data mode */ USBPD_SW_RESET(port); } diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h index 9e8bff1342..fe55813435 100644 --- a/driver/tcpm/it83xx_pd.h +++ b/driver/tcpm/it83xx_pd.h @@ -7,12 +7,185 @@ #ifndef __CROS_EC_DRIVER_TCPM_IT83XX_H #define __CROS_EC_DRIVER_TCPM_IT83XX_H +/* USBPD Controller */ +#if defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) +#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) +#define USBPD_REG_MASK_CC2_DISCONNECT BIT(7) +#define USBPD_REG_MASK_CC2_DISCONNECT_5_1K_TO_GND BIT(6) +#define USBPD_REG_MASK_CC1_DISCONNECT BIT(3) +#define USBPD_REG_MASK_CC1_DISCONNECT_5_1K_TO_GND BIT(2) +#ifdef IT83XX_USBPD_CC_VOLTAGE_DETECTOR_INDEPENDENT +#define USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR (BIT(5) | BIT(1)) +#else +#define USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR BIT(1) +#endif +#define IT83XX_USBPD_CCPSR(p) REG8(IT83XX_USBPD_BASE(p)+0x06) +#define USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB BIT(6) +#define USBPD_REG_MASK_DISCONNECT_POWER_CC2 BIT(5) +#define USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB BIT(2) +#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) +#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) + +#elif defined(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2) +#define IT83XX_USBPD_BASE(port) (0x00F03700 + (0x100 * (port) * (port))) + +#define IT83XX_USBPD_PDGCR(p) REG8(IT83XX_USBPD_BASE(p)+0x0) +#define USBPD_REG_MASK_SW_RESET_BIT BIT(7) +#define USBPD_REG_MASK_PROTOCOL_STATE_CLEAR BIT(6) +#define USBPD_REG_MASK_BIST_DATA_MODE BIT(4) +#define USBPD_REG_MASK_AUTO_BIST_RESPONSE BIT(3) +#define USBPD_REG_MASK_TX_MESSAGE_ENABLE BIT(2) +#define USBPD_REG_MASK_SNIFFER_MODE BIT(1) +#define USBPD_REG_MASK_BMC_PHY BIT(0) +#define IT83XX_USBPD_PDCSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x01) +#define IT83XX_USBPD_PDMSR(p) REG8(IT83XX_USBPD_BASE(p)+0x02) +#define USBPD_REG_MASK_DISABLE_AUTO_GEN_TX_HEADER BIT(7) +#define IT83XX_USBPD_PDCSR1(p) REG8(IT83XX_USBPD_BASE(p)+0x03) +#define USBPD_REG_MASK_CABLE_RESET_RX_ENABLE BIT(6) +#define USBPD_REG_MASK_HARD_RESET_RX_ENABLE BIT(5) +#define USBPD_REG_MASK_SOPPP_RX_ENABLE BIT(2) +#define USBPD_REG_MASK_SOPP_RX_ENABLE BIT(1) +#define USBPD_REG_MASK_SOP_RX_ENABLE BIT(0) +#define IT83XX_USBPD_CCGCR(p) REG8(IT83XX_USBPD_BASE(p)+0x04) +#define USBPD_REG_MASK_DISABLE_CC BIT(7) +#define USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR BIT(6) +#define USBPD_REG_MASK_CC_SELECT_RP_DEF (BIT(3) | BIT(2)) +#define USBPD_REG_MASK_CC_SELECT_RP_1A5 BIT(3) +#define USBPD_REG_MASK_CC_SELECT_RP_3A0 BIT(2) +#define USBPD_REG_MASK_CC1_CC2_SELECTION BIT(0) +#define IT83XX_USBPD_CCCSR(p) REG8(IT83XX_USBPD_BASE(p)+0x05) +#define USBPD_REG_MASK_CC2_DISCONNECT BIT(7) +#define USBPD_REG_MASK_CC2_DISCONNECT_5_1K_TO_GND BIT(6) +#define USBPD_REG_MASK_CC1_DISCONNECT BIT(3) +#define USBPD_REG_MASK_CC1_DISCONNECT_5_1K_TO_GND BIT(2) +#define USBPD_REG_MASK_CC1_CC2_RP_RD_SELECT BIT(1) +#define IT83XX_USBPD_CCPSR(p) REG8(IT83XX_USBPD_BASE(p)+0x06) +#define USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB BIT(6) +#define USBPD_REG_MASK_DISCONNECT_POWER_CC2 BIT(5) +#define USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB BIT(2) +#define USBPD_REG_MASK_DISCONNECT_POWER_CC1 BIT(1) +#define IT83XX_USBPD_SRCVCRR(p) REG8(IT83XX_USBPD_BASE(p)+0x08) +#define USBPD_REG_MASK_SRC_COMPARE_CC2_VOLT_H BIT(5) +#define USBPD_REG_MASK_SRC_COMPARE_CC2_VOLT_L BIT(4) +#define USBPD_REG_MASK_SRC_COMPARE_CC1_VOLT_H BIT(1) +#define USBPD_REG_MASK_SRC_COMPARE_CC1_VOLT_L BIT(0) +#define IT83XX_USBPD_SNKVCRR(p) REG8(IT83XX_USBPD_BASE(p)+0x09) +#define USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_H BIT(6) +#define USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_M BIT(5) +#define USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_L BIT(4) +#define USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_H BIT(2) +#define USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_M BIT(1) +#define USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_L BIT(0) +#define IT83XX_USBPD_ISR(p) REG8(IT83XX_USBPD_BASE(p)+0x14) +#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_TX_ERROR_STAT BIT(3) +#define USBPD_REG_MASK_CABLE_RESET_TX_DONE BIT(2) +#define USBPD_REG_MASK_HARD_RESET_TX_DONE BIT(1) +#define USBPD_REG_MASK_MSG_TX_DONE 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_TX_DISCARD_STAT BIT(7) +#define USBPD_REG_MASK_TX_NO_RESPONSE_STAT BIT(6) +#define USBPD_REG_MASK_TX_NOT_EN_STAT BIT(5) +#define USBPD_REG_MASK_CABLE_RESET BIT(3) +#define USBPD_REG_MASK_SEND_HW_RESET BIT(2) +#define USBPD_REG_MASK_SEND_BIST_MODE_2 BIT(1) +#define USBPD_REG_MASK_TX_START BIT(0) +#define IT83XX_USBPD_MTSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x19) +#define IT83XX_USBPD_MHSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x1A) +#define USBPD_REG_MASK_SOP_PORT_DATA_ROLE BIT(5) +#define IT83XX_USBPD_MHSR1(p) REG8(IT83XX_USBPD_BASE(p)+0x1B) +#define USBPD_REG_MASK_SOP_PORT_POWER_ROLE BIT(0) +#define IT83XX_USBPD_TDO(p) REG32(IT83XX_USBPD_BASE(p)+0x22) +#define IT83XX_USBPD_RMH(p) REG16(IT83XX_USBPD_BASE(p)+0x42) +#define IT83XX_USBPD_RDO(p) REG32(IT83XX_USBPD_BASE(p)+0x44) +#define IT83XX_USBPD_BMCDR0(p) REG8(IT83XX_USBPD_BASE(p)+0x61) +#define USBPD_REG_MASK_BMC_RX_THRESHOLD_SRC BIT(5) +#define USBPD_REG_MASK_BMC_RX_THRESHOLD_SNK BIT(1) +#define IT83XX_USBPD_TCDCR(p) REG8(IT83XX_USBPD_BASE(p)+0x67) +#define USBPD_REG_PLUG_OUT_DETECT_TYPE_SELECT BIT(7) +#define USBPD_REG_PLUG_IN_OUT_SELECT BIT(6) +#define USBPD_REG_PD3_0_SNK_TX_OK_DISABLE BIT(5) +#define USBPD_REG_PD3_0_SNK_TX_NG_DISABLE BIT(3) +#define USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE BIT(1) +#define USBPD_REG_PLUG_IN_OUT_DETECT_STAT BIT(0) +#define IT83XX_USBPD_CCPSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x70) +#endif /* !defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) */ + /* * Dedicated setting for CC pin. * This setting will connect CC pin to internal PD module directly without * applying any GPIO/ALT configuration. */ -#define IT83XX_USBPD_CC_PIN_CONFIG 0x86 +#define IT83XX_USBPD_CC_PIN_CONFIG 0x86 +#define IT83XX_USBPD_CC_PIN_CONFIG2 0x06 #define TASK_EVENT_PHY_TX_DONE TASK_EVENT_CUSTOM_BIT(PD_EVENT_FIRST_FREE_BIT) @@ -21,6 +194,7 @@ #define IS_MASK_SET(reg, bit_mask) (((reg) & (bit_mask)) != 0) #define IS_MASK_CLEAR(reg, bit_mask) (((reg) & (bit_mask)) == 0) +#if defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) /* macros for set */ #define USBPD_KICK_TX_START(port) \ SET_MASK(IT83XX_USBPD_MTCR(port), \ @@ -46,6 +220,12 @@ #define USBPD_DISABLE_SEND_BIST_MODE_2(port) \ CLEAR_MASK(IT83XX_USBPD_MTSR0(port), \ USBPD_REG_MASK_SEND_BIST_MODE_2) +#define USBPD_CC1_DISCONNECTED(p) \ + ((IT83XX_USBPD_CCCSR(p) | USBPD_REG_MASK_CC1_DISCONNECT) & \ + ~USBPD_REG_MASK_CC2_DISCONNECT) +#define USBPD_CC2_DISCONNECTED(p) \ + ((IT83XX_USBPD_CCCSR(p) | USBPD_REG_MASK_CC2_DISCONNECT) & \ + ~USBPD_REG_MASK_CC1_DISCONNECT) /* macros for get */ #define USBPD_GET_POWER_ROLE(port) \ @@ -63,6 +243,75 @@ #define USBPD_IS_TX_DISCARD(port) \ IS_MASK_SET(IT83XX_USBPD_MTCR(port), USBPD_REG_MASK_TX_DISCARD_STAT) +#elif defined(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2) +/* macros for set */ +#define USBPD_SW_RESET(port) \ + SET_MASK(IT83XX_USBPD_PDGCR(port), \ + USBPD_REG_MASK_SW_RESET_BIT) +#define USBPD_ENABLE_BMC_PHY(port) \ + SET_MASK(IT83XX_USBPD_PDGCR(port), \ + USBPD_REG_MASK_BMC_PHY) +#define USBPD_DISABLE_BMC_PHY(port) \ + CLEAR_MASK(IT83XX_USBPD_PDGCR(port), \ + USBPD_REG_MASK_BMC_PHY) +#define USBPD_START(port) \ + CLEAR_MASK(IT83XX_USBPD_CCGCR(port), \ + USBPD_REG_MASK_DISABLE_CC) +#define USBPD_SEND_HARD_RESET(port) \ + SET_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_SEND_HW_RESET) +#define USBPD_SEND_CABLE_RESET(port) \ + SET_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_CABLE_RESET) +#define USBPD_ENABLE_SEND_BIST_MODE_2(port) \ + SET_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_SEND_BIST_MODE_2) +#define USBPD_DISABLE_SEND_BIST_MODE_2(port) \ + CLEAR_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_SEND_BIST_MODE_2) +#define USBPD_KICK_TX_START(port) \ + SET_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_TX_START) +#define USBPD_CC1_DISCONNECTED(p) \ + ((IT83XX_USBPD_CCCSR(p) | USBPD_REG_MASK_CC1_DISCONNECT) & \ + ~USBPD_REG_MASK_CC2_DISCONNECT) +#define USBPD_CC2_DISCONNECTED(p) \ + ((IT83XX_USBPD_CCCSR(p) | USBPD_REG_MASK_CC2_DISCONNECT) & \ + ~USBPD_REG_MASK_CC1_DISCONNECT) + +/* macros for get */ +#define USBPD_GET_POWER_ROLE(port) \ + (IT83XX_USBPD_MHSR1(port) & BIT(0)) +#define USBPD_GET_CC1_PULL_REGISTER_SELECTION(port) \ + (IT83XX_USBPD_CCCSR(port) & BIT(1)) +#define USBPD_GET_CC2_PULL_REGISTER_SELECTION(port) \ + (IT83XX_USBPD_CCCSR(port) & BIT(1)) +#define USBPD_GET_PULL_CC_SELECTION(port) \ + (IT83XX_USBPD_CCGCR(port) & BIT(0)) +#define USBPD_GET_SNK_COMPARE_CC1_VOLT(port) \ + (IT83XX_USBPD_SNKVCRR(port) & \ + (USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_L | \ + USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_M | \ + USBPD_REG_MASK_SNK_COMPARE_CC1_VOLT_H)) +#define USBPD_GET_SNK_COMPARE_CC2_VOLT(port) \ + ((IT83XX_USBPD_SNKVCRR(port) & \ + (USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_L | \ + USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_M | \ + USBPD_REG_MASK_SNK_COMPARE_CC2_VOLT_H)) >> 4) +#define USBPD_GET_SRC_COMPARE_CC1_VOLT(port) \ + (IT83XX_USBPD_SRCVCRR(port) & \ + (USBPD_REG_MASK_SRC_COMPARE_CC1_VOLT_L | \ + USBPD_REG_MASK_SRC_COMPARE_CC1_VOLT_H)) +#define USBPD_GET_SRC_COMPARE_CC2_VOLT(port) \ + ((IT83XX_USBPD_SRCVCRR(port) & \ + (USBPD_REG_MASK_SRC_COMPARE_CC2_VOLT_L | \ + USBPD_REG_MASK_SRC_COMPARE_CC2_VOLT_H)) >> 4) + +/* macros for check */ +#define USBPD_IS_TX_ERR(port) \ + IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_TX_ERROR_STAT) +#endif /* !defined(CONFIG_USB_PD_TCPM_DRIVER_IT83XX) */ + /* macros for PD ISR */ #define USBPD_IS_HARD_RESET_DETECT(port) \ IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_HARD_RESET_DETECT) @@ -70,10 +319,14 @@ IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_TX_DONE) #define USBPD_IS_RX_DONE(port) \ IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_RX_DONE) -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT #define USBPD_IS_PLUG_IN_OUT_DETECT(port)\ IS_MASK_SET(IT83XX_USBPD_TCDCR(port), USBPD_REG_PLUG_IN_OUT_DETECT_STAT) -#endif //IT83XX_INTC_PLUG_IN_SUPPORT + +enum usbpd_port { + USBPD_PORT_A, + USBPD_PORT_B, + USBPD_PORT_C, +}; enum usbpd_ufp_volt_status { USBPD_UFP_STATE_SNK_OPEN = 0, @@ -103,7 +356,13 @@ struct usbpd_ctrl_t { extern const struct usbpd_ctrl_t usbpd_ctrl_regs[]; extern const struct tcpm_drv it83xx_tcpm_drv; +/* Disable cc module */ +void it83xx_disable_cc_module(int port); /* Disable integrated pd module */ void it83xx_disable_pd_module(int port); +#ifdef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 +void it83xx_clear_tx_error_status(enum usbpd_port port); +void it83xx_get_tx_error_status(enum usbpd_port port); +#endif #endif /* __CROS_EC_DRIVER_TCPM_IT83XX_H */ diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c new file mode 100644 index 0000000000..94d5d71839 --- /dev/null +++ b/driver/tcpm/it8xxx2.c @@ -0,0 +1,676 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* TCPM on ITE chip it8xxx2 with embedded TCPC */ + +#include "common.h" +#include "config.h" +#include "console.h" +#include "it83xx_pd.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "timer.h" +#include "util.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" +#include "hooks.h" + +#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) || \ + defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) || \ + defined(CONFIG_USB_PD_TCPC_LOW_POWER) || \ + defined(CONFIG_USB_PD_DISCHARGE_TCPC) +#error "Unsupported config options of IT83xx PD driver" +#endif + +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +/* Wait time for vconn power switch to turn off. */ +#ifndef PD_IT83XX_VCONN_TURN_OFF_DELAY_US +#define PD_IT83XX_VCONN_TURN_OFF_DELAY_US 500 +#endif + +static uint8_t tx_error_status[IT83XX_USBPD_PHY_PORT_COUNT] = {0}; + +const struct usbpd_ctrl_t usbpd_ctrl_regs[] = { + {&IT83XX_GPIO_GPCRF4, &IT83XX_GPIO_GPCRF5, IT83XX_IRQ_USBPD0}, + {&IT83XX_GPIO_GPCRH1, &IT83XX_GPIO_GPCRH2, IT83XX_IRQ_USBPD1}, + {&IT83XX_GPIO_GPCRP0, &IT83XX_GPIO_GPCRP1, IT83XX_IRQ_USBPD2}, +}; +BUILD_ASSERT(ARRAY_SIZE(usbpd_ctrl_regs) >= IT83XX_USBPD_PHY_PORT_COUNT); + +/* + * This function disables integrated pd module and enables 5.1K resistor for + * dead battery. A EC reset or calling _init() is able to re-active pd module. + */ +void it83xx_disable_pd_module(int port) +{ + uint8_t cc_config = (port == USBPD_PORT_C ? + IT83XX_USBPD_CC_PIN_CONFIG2 : + IT83XX_USBPD_CC_PIN_CONFIG); + + /* This only apply to PD port. */ + if (*usbpd_ctrl_regs[port].cc1 == cc_config && + *usbpd_ctrl_regs[port].cc2 == cc_config) { + /* Disable PD Tx and Rx BMC PHY */ + IT83XX_USBPD_PDGCR(port) &= ~USBPD_REG_MASK_BMC_PHY; + /* Disable CC module */ + it83xx_disable_cc_module(port); + /* Connect 5.1K dead battery resistor to CC */ + IT83XX_USBPD_CCPSR(port) &= + ~(USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB | + USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB); + } +} + +static enum tcpc_cc_voltage_status it83xx_get_cc( + enum usbpd_port port, + enum usbpd_cc_pin cc_pin) +{ + enum usbpd_ufp_volt_status ufp_volt; + enum usbpd_dfp_volt_status dfp_volt; + enum tcpc_cc_voltage_status cc_state = TYPEC_CC_VOLT_OPEN; + + /* + * Because the message header bit(8) field has different definition + * between SOP and SOP'/SOP'', in order to not happen misjudgement + * when we receive SOP or SOP'/SOP'', the getting power role synchronize + * with pd[port].power_role (also synchronization with tcpm_set_cc) + * instead of message header. + */ + /* Sink */ + if (pd_get_power_role(port) == PD_ROLE_SINK) { + if (cc_pin == USBPD_CC_PIN_1) + ufp_volt = USBPD_GET_SNK_COMPARE_CC1_VOLT(port); + else + ufp_volt = USBPD_GET_SNK_COMPARE_CC2_VOLT(port); + + switch (ufp_volt) { + case USBPD_UFP_STATE_SNK_DEF: + cc_state = TYPEC_CC_VOLT_RP_DEF; + break; + case USBPD_UFP_STATE_SNK_1_5: + cc_state = TYPEC_CC_VOLT_RP_1_5; + break; + case USBPD_UFP_STATE_SNK_3_0: + cc_state = TYPEC_CC_VOLT_RP_3_0; + break; + case USBPD_UFP_STATE_SNK_OPEN: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + default: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + } + /* Source */ + } else { + if (cc_pin == USBPD_CC_PIN_1) + dfp_volt = USBPD_GET_SRC_COMPARE_CC1_VOLT(port); + else + dfp_volt = USBPD_GET_SRC_COMPARE_CC2_VOLT(port); + + switch (dfp_volt) { + case USBPD_DFP_STATE_SRC_RA: + cc_state = TYPEC_CC_VOLT_RA; + break; + case USBPD_DFP_STATE_SRC_RD: + cc_state = TYPEC_CC_VOLT_RD; + break; + case USBPD_DFP_STATE_SRC_OPEN: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + default: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + } + } + + return cc_state; +} + +static int it83xx_tcpm_get_message_raw(int port, uint32_t *buf, int *head) +{ + int cnt = PD_HEADER_CNT(IT83XX_USBPD_RMH(port)); + + if (!USBPD_IS_RX_DONE(port)) + return EC_ERROR_UNKNOWN; + + /* Store header */ + *head = IT83XX_USBPD_RMH(port); + /* Check data message */ + if (cnt) + memcpy(buf, (uint32_t *)&IT83XX_USBPD_RDO(port), cnt * 4); + + return EC_SUCCESS; +} + +void it83xx_clear_tx_error_status(enum usbpd_port port) +{ + tx_error_status[port] = 0; +} + +void it83xx_get_tx_error_status(enum usbpd_port port) +{ + tx_error_status[port] = IT83XX_USBPD_MTCR(port) & + (USBPD_REG_MASK_TX_NOT_EN_STAT | + USBPD_REG_MASK_TX_DISCARD_STAT | + USBPD_REG_MASK_TX_NO_RESPONSE_STAT); +} + +static enum tcpc_transmit_complete it83xx_tx_data( + enum usbpd_port port, + enum tcpm_transmit_type type, + uint16_t header, + const uint32_t *buf) +{ + int r; + uint32_t evt; + uint8_t length = PD_HEADER_CNT(header); + + /* Set message header */ + IT83XX_USBPD_MHSR0(port) = (uint8_t)header; + IT83XX_USBPD_MHSR1(port) = (header >> 8); + + /* + * Bit[2:0] Tx message type + * 000b=SOP, 001b=SOP', 010b=SOP", 011b=Debug SOP', 100b=Debug SOP''. + */ + IT83XX_USBPD_MTSR0(port) = + (IT83XX_USBPD_MTSR0(port) & ~0x7) | (type & 0x7); + + /* Limited by PD_HEADER_CNT() */ + ASSERT(length <= 0x7); + + if (length) + /* Set data */ + memcpy((uint32_t *)&IT83XX_USBPD_TDO(port), buf, length * 4); + + for (r = 0; r <= PD_RETRY_COUNT; r++) { + /* Start Tx */ + USBPD_KICK_TX_START(port); + evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE, + PD_T_TCPC_TX_TIMEOUT); + + /* + * Check Tx error status (TCPC won't set multi tx errors at one + * time transmission): + * 1) If we doesn't enable Tx. + * 2) If discard, means HW doesn't send the msg and resend. + * 3) If port partner doesn't respond GoodCRC. + * 4) If Tx timeout. + */ + if (tx_error_status[port] || (evt & TASK_EVENT_TIMER)) { + if (tx_error_status[port] & + USBPD_REG_MASK_TX_NOT_EN_STAT) { + CPRINTS("p%d TxErr: Tx EN and resend", port); + tx_error_status[port] &= + ~USBPD_REG_MASK_TX_NOT_EN_STAT; + IT83XX_USBPD_PDGCR(port) |= + USBPD_REG_MASK_TX_MESSAGE_ENABLE; + continue; + } else if (tx_error_status[port] & + USBPD_REG_MASK_TX_DISCARD_STAT) { + CPRINTS("p%d TxErr: Discard and resend", port); + tx_error_status[port] &= + ~USBPD_REG_MASK_TX_DISCARD_STAT; + continue; + } else if (tx_error_status[port] & + USBPD_REG_MASK_TX_NO_RESPONSE_STAT) { + /* HW had automatically resent message twice */ + tx_error_status[port] &= + ~USBPD_REG_MASK_TX_NO_RESPONSE_STAT; + return TCPC_TX_COMPLETE_FAILED; + } else if (evt & TASK_EVENT_TIMER) { + CPRINTS("p%d TxErr: Timeout", port); + return TCPC_TX_UNSET; + } + } else + break; + } + + if (r > PD_RETRY_COUNT) + return TCPC_TX_COMPLETE_DISCARDED; + + return TCPC_TX_COMPLETE_SUCCESS; +} + +static enum tcpc_transmit_complete it83xx_send_hw_reset(enum usbpd_port port) +{ + /* Send hard reset */ + USBPD_SEND_HARD_RESET(port); + usleep(MSEC); + + if (!(IT83XX_USBPD_ISR(port) & USBPD_REG_MASK_HARD_RESET_TX_DONE)) + return TCPC_TX_COMPLETE_FAILED; + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_HARD_RESET_TX_DONE; + + return TCPC_TX_COMPLETE_SUCCESS; +} + +static enum tcpc_transmit_complete it83xx_send_cable_reset(enum usbpd_port port) +{ + /* Send cable reset */ + USBPD_SEND_CABLE_RESET(port); + usleep(MSEC); + + if (!(IT83XX_USBPD_ISR(port) & USBPD_REG_MASK_CABLE_RESET_TX_DONE)) + return TCPC_TX_COMPLETE_FAILED; + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_CABLE_RESET_TX_DONE; + + return TCPC_TX_COMPLETE_SUCCESS; +} + +static void it83xx_send_bist_mode2_pattern(enum usbpd_port port) +{ + USBPD_ENABLE_SEND_BIST_MODE_2(port); + usleep(PD_T_BIST_TRANSMIT); + USBPD_DISABLE_SEND_BIST_MODE_2(port); +} + +static void it83xx_enable_vconn(enum usbpd_port port, int enabled) +{ + enum usbpd_cc_pin cc_pin; + + if (USBPD_GET_PULL_CC_SELECTION(port)) + cc_pin = USBPD_CC_PIN_1; + else + cc_pin = USBPD_CC_PIN_2; + + if (enabled) { + /* Disable unused CC to become VCONN */ + if (cc_pin == USBPD_CC_PIN_1) { + IT83XX_USBPD_CCCSR(port) = USBPD_CC2_DISCONNECTED(port); + IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) + & ~USBPD_REG_MASK_DISCONNECT_POWER_CC2) + | USBPD_REG_MASK_DISCONNECT_POWER_CC1; + } else { + IT83XX_USBPD_CCCSR(port) = USBPD_CC1_DISCONNECTED(port); + IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) + & ~USBPD_REG_MASK_DISCONNECT_POWER_CC1) + | USBPD_REG_MASK_DISCONNECT_POWER_CC2; + } + } else { + /* Connect cc analog module (ex.UP/RD/DET/TX/RX) */ + IT83XX_USBPD_CCCSR(port) &= ~(USBPD_REG_MASK_CC2_DISCONNECT | + USBPD_REG_MASK_CC1_DISCONNECT); + /* Disable cc 5v tolerant */ + IT83XX_USBPD_CCPSR(port) |= + (USBPD_REG_MASK_DISCONNECT_POWER_CC1 | + USBPD_REG_MASK_DISCONNECT_POWER_CC2); + } +} + +static void it83xx_enable_cc(enum usbpd_port port, int enable) +{ + if (enable) + IT83XX_USBPD_CCGCR(port) &= ~USBPD_REG_MASK_DISABLE_CC; + else + IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_DISABLE_CC; +} + +static void it83xx_set_power_role(enum usbpd_port port, int power_role) +{ + /* 0: PD_ROLE_SINK, 1: PD_ROLE_SOURCE */ + if (power_role == PD_ROLE_SOURCE) { + /* + * Bit[0:6] BMC Rx threshold setting + * 000 1000b: power neutral + * 010 0000b: sinking power => + * High to low Y3Rx threshold = 0.38, + * Low to high Y3Rx threshold = 0.54. + * 000 0010b: sourcing power => + * High to low Y3Rx threshold = 0.64, + * Low to high Y3Rx threshold = 0.79. + */ + IT83XX_USBPD_BMCDR0(port) = USBPD_REG_MASK_BMC_RX_THRESHOLD_SRC; + /* Bit0: source */ + IT83XX_USBPD_MHSR1(port) |= USBPD_REG_MASK_SOP_PORT_POWER_ROLE; + /* Bit1: CC1 and CC2 select Rp */ + IT83XX_USBPD_CCCSR(port) |= USBPD_REG_MASK_CC1_CC2_RP_RD_SELECT; + } else { + /* + * Bit[0:6] BMC Rx threshold setting + * 000 1000b: power neutral + * 010 0000b: sinking power => + * High to low Y3Rx threshold = 0.38, + * Low to high Y3Rx threshold = 0.54. + * 000 0010b: sourcing power => + * High to low Y3Rx threshold = 0.64, + * Low to high Y3Rx threshold = 0.79. + */ + IT83XX_USBPD_BMCDR0(port) = USBPD_REG_MASK_BMC_RX_THRESHOLD_SNK; + /* Bit0: sink */ + IT83XX_USBPD_MHSR1(port) &= ~USBPD_REG_MASK_SOP_PORT_POWER_ROLE; + /* Bit1: CC1 and CC2 select Rd */ + IT83XX_USBPD_CCCSR(port) &= + ~USBPD_REG_MASK_CC1_CC2_RP_RD_SELECT; + } +} + +static void it83xx_set_data_role(enum usbpd_port port, int data_role) +{ + /* 0: PD_ROLE_UFP 1: PD_ROLE_DFP */ + if (data_role == PD_ROLE_DFP) + /* Bit5: DFP */ + IT83XX_USBPD_MHSR0(port) |= USBPD_REG_MASK_SOP_PORT_DATA_ROLE; + else + /* Bit5: UFP */ + IT83XX_USBPD_MHSR0(port) &= ~USBPD_REG_MASK_SOP_PORT_DATA_ROLE; +} + +static void it83xx_select_polarity(enum usbpd_port port, + enum usbpd_cc_pin cc_pin) +{ + /* CC1/CC2 selection */ + if (cc_pin == USBPD_CC_PIN_1) + IT83XX_USBPD_CCGCR(port) |= USBPD_REG_MASK_CC1_CC2_SELECTION; + else + IT83XX_USBPD_CCGCR(port) &= ~USBPD_REG_MASK_CC1_CC2_SELECTION; +} + +static int it83xx_set_cc(enum usbpd_port port, int pull) +{ + int enable_cc = 1; + + switch (pull) { + case TYPEC_CC_RD: + it83xx_set_power_role(port, PD_ROLE_SINK); + break; + case TYPEC_CC_RP: + it83xx_set_power_role(port, PD_ROLE_SOURCE); + break; + case TYPEC_CC_OPEN: + /* Power-down CC1 & CC2 to remove Rp/Rd */ + enable_cc = 0; + break; + default: + return EC_ERROR_UNIMPLEMENTED; + } + + it83xx_enable_cc(port, enable_cc); + return EC_SUCCESS; +} + +static int it83xx_tcpm_release(int port) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +static int it83xx_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, + enum tcpc_cc_voltage_status *cc2) +{ + *cc2 = it83xx_get_cc(port, USBPD_CC_PIN_2); + *cc1 = it83xx_get_cc(port, USBPD_CC_PIN_1); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_select_rp_value(int port, int rp_sel) +{ + uint8_t rp; + + /* + * Bit[3-1]: CC output current (effective when Rp assert in 05h Bit[1]) + * 111: reserved + * 010: 330uA outpt (3.0A) + * 100: 180uA outpt (1.5A) + * 110: 80uA outpt (USB default) + */ + switch (rp_sel) { + case TYPEC_RP_1A5: + rp = USBPD_REG_MASK_CC_SELECT_RP_1A5; + break; + case TYPEC_RP_3A0: + rp = USBPD_REG_MASK_CC_SELECT_RP_3A0; + break; + case TYPEC_RP_USB: + default: + rp = USBPD_REG_MASK_CC_SELECT_RP_DEF; + break; + } + IT83XX_USBPD_CCGCR(port) = (IT83XX_USBPD_CCGCR(port) & ~(7 << 1)) | rp; + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_cc(int port, int pull) +{ + return it83xx_set_cc(port, pull); +} + +static int it83xx_tcpm_set_polarity(int port, int polarity) +{ + it83xx_select_polarity(port, polarity); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_vconn(int port, int enable) +{ + /* + * IT83XX doesn't have integrated circuit to source CC lines for VCONN. + * An external device like PPC or Power Switch has to source the VCONN. + */ + if (IS_ENABLED(CONFIG_USBC_VCONN)) { + if (enable) { + /* + * Unused cc will become Vconn SRC, disable cc analog + * module (ex.UP/RD/DET/Tx/Rx) and enable 5v tolerant. + */ + it83xx_enable_vconn(port, enable); + if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) + /* Enable tcpc receive SOP' packet */ + IT83XX_USBPD_PDCSR1(port) |= + USBPD_REG_MASK_SOPP_RX_ENABLE; + } + /* Turn on/off vconn power switch. */ + board_pd_vconn_ctrl(port, + USBPD_GET_PULL_CC_SELECTION(port) ? + USBPD_CC_PIN_2 : USBPD_CC_PIN_1, enable); + if (!enable) { + if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) + /* Disable tcpc receive SOP' packet */ + IT83XX_USBPD_PDCSR1(port) &= + ~USBPD_REG_MASK_SOPP_RX_ENABLE; + /* + * We need to make sure cc voltage detector is enabled + * after vconn is turned off to avoid the potential risk + * of voltage fed back into Vcore. + */ + usleep(PD_IT83XX_VCONN_TURN_OFF_DELAY_US); + /* + * Since our cc are not Vconn SRC, enable cc analog + * module (ex.UP/RD/DET/Tx/Rx) and disable 5v tolerant. + */ + it83xx_enable_vconn(port, enable); + } + } + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_msg_header(int port, int power_role, int data_role) +{ + /* 0: PD_ROLE_SINK, 1: PD_ROLE_SOURCE */ + if (power_role == PD_ROLE_SOURCE) + /* Bit0: source */ + IT83XX_USBPD_MHSR1(port) |= USBPD_REG_MASK_SOP_PORT_POWER_ROLE; + else + /* Bit0: sink */ + IT83XX_USBPD_MHSR1(port) &= ~USBPD_REG_MASK_SOP_PORT_POWER_ROLE; + + it83xx_set_data_role(port, data_role); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_rx_enable(int port, int enable) +{ + int i; + + if (enable) { + IT83XX_USBPD_IMR(port) &= ~USBPD_REG_MASK_MSG_RX_DONE; + USBPD_ENABLE_BMC_PHY(port); + } else { + IT83XX_USBPD_IMR(port) |= USBPD_REG_MASK_MSG_RX_DONE; + USBPD_DISABLE_BMC_PHY(port); + } + + /* If any PD port Rx is enabled, then disable deep sleep */ + for (i = 0; i < board_get_usb_pd_port_count(); ++i) { + if (IT83XX_USBPD_PDGCR(i) & USBPD_REG_MASK_BMC_PHY) + break; + } + + if (i == board_get_usb_pd_port_count()) + enable_sleep(SLEEP_MASK_USB_PD); + else + disable_sleep(SLEEP_MASK_USB_PD); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_transmit(int port, + enum tcpm_transmit_type type, + uint16_t header, + const uint32_t *data) +{ + int status = TCPC_TX_COMPLETE_FAILED; + + switch (type) { + case TCPC_TX_SOP: + case TCPC_TX_SOP_PRIME: + case TCPC_TX_SOP_PRIME_PRIME: + case TCPC_TX_SOP_DEBUG_PRIME: + case TCPC_TX_SOP_DEBUG_PRIME_PRIME: + status = it83xx_tx_data(port, + type, + header, + data); + break; + case TCPC_TX_BIST_MODE_2: + it83xx_send_bist_mode2_pattern(port); + status = TCPC_TX_COMPLETE_SUCCESS; + break; + case TCPC_TX_HARD_RESET: + status = it83xx_send_hw_reset(port); + break; + case TCPC_TX_CABLE_RESET: + status = it83xx_send_cable_reset(port); + break; + default: + status = TCPC_TX_COMPLETE_FAILED; + break; + } + pd_transmit_complete(port, status); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_get_chip_info(int port, int live, + struct ec_response_pd_chip_info_v1 **chip_info) +{ + static struct ec_response_pd_chip_info_v1 i; + + *chip_info = &i; + i.vendor_id = USB_VID_ITE; + i.product_id = (IT83XX_GCTRL_CHIPID1 << 8) | IT83XX_GCTRL_CHIPID2; + i.device_id = IT83XX_GCTRL_CHIPVER & 0xf; + i.fw_version_number = 0xEC; + + return EC_SUCCESS; +} + +static void it83xx_init(enum usbpd_port port, int role) +{ + uint8_t cc_config = (port == USBPD_PORT_C ? + IT83XX_USBPD_CC_PIN_CONFIG2 : + IT83XX_USBPD_CC_PIN_CONFIG); + + /* Reset and disable HW auto generate message header */ + IT83XX_USBPD_PDMSR(port) &= ~USBPD_REG_MASK_DISABLE_AUTO_GEN_TX_HEADER; + USBPD_SW_RESET(port); + /* Enable rx decode SOP type packet and hard reset signal */ + IT83XX_USBPD_PDCSR1(port) = (USBPD_REG_MASK_HARD_RESET_RX_ENABLE | + USBPD_REG_MASK_SOP_RX_ENABLE); + /* Disable all interrupts */ + IT83XX_USBPD_IMR(port) = 0xff; + /* W/C status */ + IT83XX_USBPD_ISR(port) = 0xff; + /* Enable cc voltage detector */ + IT83XX_USBPD_CCGCR(port) &= ~USBPD_REG_MASK_DISABLE_CC_VOL_DETECTOR; + /* Select Rp value USB-DEFAULT (Rd value default connect with 5.1k) */ + it83xx_tcpm_select_rp_value(port, TYPEC_RP_USB); + /* Which cc pin connect in attached state. Default to cc1 */ + it83xx_select_polarity(port, USBPD_CC_PIN_1); + /* Change data role as the same power role */ + it83xx_set_data_role(port, role); + /* Set default power role and assert Rp/Rd */ + it83xx_set_power_role(port, role); + /* Disable vconn: connect cc analog module, disable cc 5v tolerant */ + it83xx_enable_vconn(port, 0); + /* Disconnect CC with 5.1K DB resister to GND */ + IT83XX_USBPD_CCPSR(port) |= (USBPD_REG_MASK_DISCONNECT_5_1K_CC2_DB | + USBPD_REG_MASK_DISCONNECT_5_1K_CC1_DB); + /* Enable tx done and hard reset detect interrupt */ + IT83XX_USBPD_IMR(port) &= ~(USBPD_REG_MASK_MSG_TX_DONE | + USBPD_REG_MASK_HARD_RESET_DETECT); +#ifdef IT83XX_INTC_PLUG_IN_SUPPORT + /* + * When tcpc detect type-c plug in (cc lines voltage change), it will + * interrupt fw to wake pd task, so task can react immediately. + * + * W/C status and enable type-c plug-in detect interrupt. + */ + IT83XX_USBPD_TCDCR(port) |= USBPD_REG_PLUG_IN_OUT_DETECT_STAT; + IT83XX_USBPD_TCDCR(port) &= ~USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE; +#endif + /* Set cc1/cc2 pins alternate mode */ + *usbpd_ctrl_regs[port].cc1 = cc_config; + *usbpd_ctrl_regs[port].cc2 = cc_config; + task_clear_pending_irq(usbpd_ctrl_regs[port].irq); + task_enable_irq(usbpd_ctrl_regs[port].irq); + USBPD_START(port); +} + +static int it83xx_tcpm_init(int port) +{ + /* Initialize physical layer */ + it83xx_init(port, PD_ROLE_DEFAULT(port)); + + return EC_SUCCESS; +} + +static void it83xx_tcpm_sw_reset(void) +{ + int port = TASK_ID_TO_PD_PORT(task_get_current()); + +#ifdef IT83XX_INTC_PLUG_IN_SUPPORT + /* + * Enable detect type-c plug in interrupt, since the pd task has + * detected a type-c physical disconnected. + */ + IT83XX_USBPD_TCDCR(port) &= ~USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE; +#endif + /* Exit BIST test data mode */ + USBPD_SW_RESET(port); +} + +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, it83xx_tcpm_sw_reset, HOOK_PRIO_DEFAULT); + +const struct tcpm_drv it83xx_tcpm_drv = { + .init = &it83xx_tcpm_init, + .release = &it83xx_tcpm_release, + .get_cc = &it83xx_tcpm_get_cc, + .select_rp_value = &it83xx_tcpm_select_rp_value, + .set_cc = &it83xx_tcpm_set_cc, + .set_polarity = &it83xx_tcpm_set_polarity, + .set_vconn = &it83xx_tcpm_set_vconn, + .set_msg_header = &it83xx_tcpm_set_msg_header, + .set_rx_enable = &it83xx_tcpm_set_rx_enable, + .get_message_raw = &it83xx_tcpm_get_message_raw, + .transmit = &it83xx_tcpm_transmit, + .get_chip_info = &it83xx_tcpm_get_chip_info, +}; diff --git a/include/config.h b/include/config.h index 591235ec43..87b05ed617 100644 --- a/include/config.h +++ b/include/config.h @@ -3904,7 +3904,7 @@ #undef CONFIG_USB_PD_TCPM_STUB #undef CONFIG_USB_PD_TCPM_TCPCI #undef CONFIG_USB_PD_TCPM_FUSB302 -#undef CONFIG_USB_PD_TCPM_ITE83XX +#undef CONFIG_USB_PD_TCPM_ITE_ON_CHIP #undef CONFIG_USB_PD_TCPM_ANX3429 #undef CONFIG_USB_PD_TCPM_ANX740X #undef CONFIG_USB_PD_TCPM_ANX741X @@ -3919,6 +3919,15 @@ #undef CONFIG_USB_PD_TCPM_RAA489000 /* + * Defined automatically by chip and depends on chip. This guards the onboard + * TCPM driver, but CONFIG_USB_PD_TCPM_ITE_ON_CHIP needs to be defined in + * board.h for either of these driver to actually be included in the final + * image. + */ +#undef CONFIG_USB_PD_TCPM_DRIVER_IT83XX +#undef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 + +/* * Type-C retimer mux configuration tends to be set on a specific * driver's need basis. After including the board/baseboard.h files * the drivers will be checked and if one of these are needed it will @@ -4802,11 +4811,10 @@ /*****************************************************************************/ /* - * Define CONFIG_USB_PD_TCPC_ON_CHIP if we use ITE83XX series TCPM driver + * Define CONFIG_USB_PD_TCPC_ON_CHIP if we use ITE series TCPM driver * on the board. */ -#if defined(CONFIG_USB_PD_TCPM_ITE83XX) || \ - defined(CONFIG_USB_PD_TCPM_ITE8XXX2) +#ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP #define CONFIG_USB_PD_TCPC_ON_CHIP #endif |