summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/ish/aontaskfw/ish_aontask.c71
-rw-r--r--chip/ish/dma.c40
-rw-r--r--chip/ish/ish_dma.h41
-rw-r--r--chip/ish/registers.h54
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)