diff options
-rw-r--r-- | chip/ish/aontaskfw/ish_aontask.c | 71 | ||||
-rw-r--r-- | chip/ish/dma.c | 40 | ||||
-rw-r--r-- | chip/ish/ish_dma.h | 41 | ||||
-rw-r--r-- | chip/ish/registers.h | 54 |
4 files changed, 166 insertions, 40 deletions
diff --git a/chip/ish/aontaskfw/ish_aontask.c b/chip/ish/aontaskfw/ish_aontask.c index d167f3f5df..58d62d1891 100644 --- a/chip/ish/aontaskfw/ish_aontask.c +++ b/chip/ish/aontaskfw/ish_aontask.c @@ -91,6 +91,56 @@ static void handle_reset(enum ish_pm_state pm_state); +#if defined(CHIP_VARIANT_ISH5P4) +static void sb_upstream_write_raw_base(uint32_t addr, uint32_t attr, + uint32_t data, uint32_t sairs, + uint8_t addr48, uint16_t addr_hi) +{ + uint32_t eflags; + uint32_t addr_hi_32; + + addr_hi_32 = addr_hi | (1 << 31); + + eflags = interrupt_lock(); + + PMU_VNN_REQ = (1 << VNN_ID_SIDEBAND); + while (!(PMU_VNN_REQ_ACK & PMU_VNN_REQ_ACK_STATUS)) + continue; + + if (dma_poll(SBEP_REG_UP_MSG_STATUS_ADDR, 0, UP_STATUS_BUSY_MASK) == + DMA_RC_OK) { + SBEP_REG_UP_MSG_REQ_ADDR_LOW = addr; + + if (addr48) { + SBEP_REG_UP_MSG_REQ_ADDR_HIGH = addr_hi_32; + } else { + SBEP_REG_UP_MSG_REQ_ADDR_HIGH = 0; + } + + SBEP_REG_UP_MSG_REQ_ATTR = attr; + SBEP_REG_UP_MSG_REQ_DATA = data; + SBEP_REG_UP_MSG_REQ_EH = sairs; + SBEP_REG_UP_MSG_COMMAND = SBEP_CMD_WRITE; + + dma_poll(SBEP_REG_UP_MSG_STATUS_ADDR, 0, UP_STATUS_BUSY_MASK); + dma_poll(SBEP_REG_UP_MSG_STATUS_ADDR, UP_STATUS_MSG_SENT_MASK, + UP_STATUS_MSG_SENT_MASK); + SBEP_REG_UP_MSG_STATUS = UP_STATUS_MSG_SENT_CLR; + } + + PMU_VNN_REQ = (1 << VNN_ID_SIDEBAND); + interrupt_unlock(eflags); +} + +static void sb_upstream_write_raw(uint32_t addr, uint32_t attr, uint32_t data, + uint32_t sairs) +{ + addr = addr & 0x0000FFFF; + + sb_upstream_write_raw_base(addr, attr, data, sairs, 0, 0); +} +#endif + /* ISR for PMU wakeup interrupt */ static void pmu_wakeup_isr(void) { @@ -670,6 +720,13 @@ static void handle_d0i3(void) aon_share.pg_exit = 0; } +#if defined(CHIP_VARIANT_ISH5P4) + /* Set PMC LTR to 2ms before DMA copy */ + if (IS_ENABLED(CONFIG_ISH_NEW_PM)) + sb_upstream_write_raw(0, LTR_CMD_ATTR, LTR_CMD_DATA_2MS, + SBEP_PMC_SAIRS_VAL); +#endif + /* store main FW 's context to IMR DDR from main SRAM */ ret = store_main_fw(); @@ -680,6 +737,13 @@ static void handle_d0i3(void) /* power off main SRAM */ sram_power(0); +#if defined(CHIP_VARIANT_ISH5P4) + /* Set LTR to a large number after DMA copy done */ + if (IS_ENABLED(CONFIG_ISH_NEW_PM)) + sb_upstream_write_raw(0, LTR_CMD_ATTR, LTR_CMD_DATA_INFINITE, + SBEP_PMC_SAIRS_VAL); +#endif + set_vnnred_aoncg(); if (IS_ENABLED(CONFIG_ISH_IPAPG) && is_ipapg_allowed()) { @@ -712,6 +776,13 @@ static void handle_d0i3(void) aon_share.uma_msb); } +#if defined(CHIP_VARIANT_ISH5P4) + /* Set PMC LTR to 2ms before DMA copy */ + if (IS_ENABLED(CONFIG_ISH_NEW_PM)) + sb_upstream_write_raw(0, LTR_CMD_ATTR, LTR_CMD_DATA_2MS, + SBEP_PMC_SAIRS_VAL); +#endif + /* restore main FW 's context to main SRAM from IMR DDR */ ret = restore_main_fw(); diff --git a/chip/ish/dma.c b/chip/ish/dma.c index 48a27a0463..e2f1aba8ed 100644 --- a/chip/ish/dma.c +++ b/chip/ish/dma.c @@ -13,28 +13,6 @@ static int dma_init_called; /* If ish_dma_init is called */ -static int dma_poll(uint32_t addr, uint32_t expected, uint32_t mask) -{ - int retval = -1; - uint32_t counter = 0; - - /* - * The timeout is approximately 2.2 seconds according to - * value of UINT32_MAX, 120MHZ ISH clock frequency and - * instruction count which is around 4. - */ - while (counter < (UINT32_MAX / 64)) { - /* test condition */ - if ((REG32(addr) & mask) == expected) { - retval = DMA_RC_OK; - break; - } - counter++; - } - - return retval; -} - void ish_dma_ocp_timeout_disable(void) { if (!IS_ENABLED(CONFIG_ISH_NEW_PM)) { @@ -44,24 +22,6 @@ void ish_dma_ocp_timeout_disable(void) } } -static inline uint32_t interrupt_lock(void) -{ - uint32_t eflags = 0; - __asm__ volatile("pushfl;" /* save eflag value */ - "popl %0;" - "cli;" - : "=r"(eflags)); /* shut off interrupts */ - return eflags; -} - -static inline void interrupt_unlock(uint32_t eflags) -{ - __asm__ volatile("pushl %0;" /* restore elfag values */ - "popfl;" - : - : "r"(eflags)); -} - void dma_configure_psize(void) { /* Give chan0 512 bytes for high performance, and chan1 128 bytes. */ diff --git a/chip/ish/ish_dma.h b/chip/ish/ish_dma.h index fb9c4f4f06..89d6cb7342 100644 --- a/chip/ish/ish_dma.h +++ b/chip/ish/ish_dma.h @@ -27,6 +27,47 @@ #define PAGE_SIZE 4096 +static inline uint32_t interrupt_lock(void) +{ + uint32_t eflags = 0; + + __asm__ volatile("pushfl;" /* save eflag value */ + "popl %0;" + "cli;" + : "=r"(eflags)); /* shut off interrupts */ + return eflags; +} + +static inline void interrupt_unlock(uint32_t eflags) +{ + __asm__ volatile("pushl %0;" /* restore elfag values */ + "popfl;" + : + : "r"(eflags)); +} + +static inline int dma_poll(uint32_t addr, uint32_t expected, uint32_t mask) +{ + int retval = -1; + uint32_t counter = 0; + + /* + * The timeout is approximately 2.2 seconds according to + * value of UINT32_MAX, 120MHZ ISH clock frequency and + * instruction count which is around 4. + */ + while (counter < (UINT32_MAX / 64)) { + /* test condition */ + if ((REG32(addr) & mask) == expected) { + retval = DMA_RC_OK; + break; + } + counter++; + } + + return retval; +} + /** * SRAM: ISH local static ram * UMA: Protected system DRAM region dedicated for ISH diff --git a/chip/ish/registers.h b/chip/ish/registers.h index ba83b7bef8..7fe5d2c5ab 100644 --- a/chip/ish/registers.h +++ b/chip/ish/registers.h @@ -136,6 +136,59 @@ enum ish_i2c_port { #define SB_CLK_GATE_EN_TRUNK_CLK_GATE BIT(1) #endif +#define SBEP_REG_UP_MSG_STATUS_ADDR (ISH_SBEP_BASE + 0x0040) +#define SBEP_REG_UP_MSG_STATUS REG32(ISH_SBEP_BASE + 0x0040) +#define SBEP_REG_UP_MSG_COMMAND REG32(ISH_SBEP_BASE + 0x0044) +#define SBEP_REG_UP_MSG_REQ_ADDR_LOW REG32(ISH_SBEP_BASE + 0x0048) +#define SBEP_REG_UP_MSG_REQ_ADDR_HIGH REG32(ISH_SBEP_BASE + 0x004C) +#define SBEP_REG_UP_MSG_REQ_DATA REG32(ISH_SBEP_BASE + 0x0050) +#define SBEP_REG_UP_MSG_REQ_ATTR REG32(ISH_SBEP_BASE + 0x0054) +#define SBEP_REG_UP_MSG_REQ_EH REG32(ISH_SBEP_BASE + 0x0058) + +#define UP_STATUS_BUSY_MASK 0x01 +#define UP_STATUS_MSG_SENT_MASK 0x02 +#define UP_STATUS_MSG_SENT_CLR 0x02 + +#define SBEP_CMD_ACTION 0x1 +#define SBEP_CMD_TYPE_WRITE 0x0 +#define SBEP_CMD_TYPE_READ 0x1 +#define SBEP_CMD_POSTED 0x1 +#define SBEP_CMD_NON_POSTED 0x0 +#define SBEP_CMD_INT_ENABLED 0x1 +#define SBEP_CMD_ACTION_OFF 0 +#define SBEP_CMD_TYPE_OFF 1 +#define SBEP_CMD_POSTED_OFF 2 +#define SBEP_CMD_INT_OFF 3 + +#define SBEP_CMD_WRITE \ + ((SBEP_CMD_ACTION << SBEP_CMD_ACTION_OFF) | \ + (SBEP_CMD_TYPE_WRITE << SBEP_CMD_TYPE_OFF) | \ + (SBEP_CMD_POSTED << SBEP_CMD_POSTED_OFF) | \ + (SBEP_CMD_INT_ENABLED << SBEP_CMD_INT_OFF)) + +#define SBEP_ATTR_LTR_OPCODE 0x43 +#define SBEP_ATTR_PMC_DEST_ID 0xCC +#define SBEP_ATTR_DEST_ID_OFF 0 +#define SBEP_ATTR_OPCODE_OFF 8 +#define SBEP_ATTR_WRITE_ALL_BYTES 0xF +#define SBEP_ATTR_BYTE_ENABLE_OFF 16 +#define LTR_CMD_ATTR \ + ((SBEP_ATTR_PMC_DEST_ID << SBEP_ATTR_DEST_ID_OFF) | \ + (SBEP_ATTR_LTR_OPCODE << SBEP_ATTR_OPCODE_OFF) | \ + (SBEP_ATTR_WRITE_ALL_BYTES << SBEP_ATTR_BYTE_ENABLE_OFF)) +#define LTR_CMD_DATA_2MS 0x90029002 +#define LTR_CMD_DATA_INFINITE 0 + +#define SBEP_SAIRS_ROOT_SPACE_PMC 0 + +#define SBEP_SAIRS_EH_PRESENT 1 +#define SBEP_SAIRS_ROOT_SPACE_OFF 16 +#define SBEP_SAIRS_EH_PRESENT_OFF 31 + +#define SBEP_PMC_SAIRS_VAL \ + ((SBEP_SAIRS_ROOT_SPACE_PMC << SBEP_SAIRS_ROOT_SPACE_OFF) | \ + (SBEP_SAIRS_EH_PRESENT << SBEP_SAIRS_EH_PRESENT_OFF)) + /* APIC interrupt vectors */ #define ISH_TS_VECTOR 0x20 /* Task switch vector */ #define LAPIC_LVT_ERROR_VECTOR 0x21 /* Clears IOAPIC/LAPIC sync errors */ @@ -269,6 +322,7 @@ enum ish_i2c_port { #define VNN_ID_DMA0 4 #define VNN_ID_DMA(chan) (VNN_ID_DMA0 + chan) +#define VNN_ID_SIDEBAND 21 /* OCP registers */ #define OCP_IOSF2OCP_BRIDGE (ISH_OCP_BASE + 0x9400) |