summaryrefslogtreecommitdiffstats
path: root/utils/hwstub/stmp/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stmp/main.c')
-rw-r--r--utils/hwstub/stmp/main.c536
1 files changed, 116 insertions, 420 deletions
diff --git a/utils/hwstub/stmp/main.c b/utils/hwstub/stmp/main.c
index 09bb6c7714..845f3842ea 100644
--- a/utils/hwstub/stmp/main.c
+++ b/utils/hwstub/stmp/main.c
@@ -34,118 +34,20 @@ extern unsigned char oc_bufferend[];
/**
*
- * Pin control
+ * Global
*
*/
-#define HW_PINCTRL_BASE 0x80018000
-
-#define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0))
-#define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10))
-#define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10))
-#ifdef HAVE_STMP3700
-#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x300 + (i) * 0x10))
-#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
-#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
-#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
-#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
-#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
-#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
-#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
-#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
-#else
-#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
-#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
-#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
-#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
-#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
-#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
-#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
-#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
-#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10))
-#endif
-
-#define PINCTRL_FUNCTION_MAIN 0
-#define PINCTRL_FUNCTION_ALT1 1
-#define PINCTRL_FUNCTION_ALT2 2
-#define PINCTRL_FUNCTION_GPIO 3
-
-#define PINCTRL_DRIVE_4mA 0
-#define PINCTRL_DRIVE_8mA 1
-#define PINCTRL_DRIVE_12mA 2
-#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
-
-typedef void (*pin_irq_cb_t)(int bank, int pin);
-
-static inline void imx233_pinctrl_init(void)
+enum stmp_family_t
{
- __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
-}
-
-static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength)
-{
- __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8));
- __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8));
-}
-
-static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable)
-{
- if(enable)
- __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin;
- else
- __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin;
-}
-
-static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable)
-{
- if(enable)
- __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask;
- else
- __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask;
-}
-
-static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value)
-{
- if(value)
- __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin;
- else
- __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin;
-}
-
-static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value)
-{
- if(value)
- __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask;
- else
- __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask;
-}
-
-static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask)
-{
- return HW_PINCTRL_DIN(bank) & pin_mask;
-}
-
-static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function)
-{
- __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16));
- __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16));
-}
-
-static inline void imx233_enable_pin_pullup(unsigned bank, unsigned pin, bool enable)
-{
- if(enable)
- __REG_SET(HW_PINCTRL_PULL(bank)) = 1 << pin;
- else
- __REG_CLR(HW_PINCTRL_PULL(bank)) = 1 << pin;
-}
+ UNKNOWN,
+ STMP3600,
+ STMP3700,
+ STMP3770,
+ STMP3780
+};
-static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk, bool enable)
-{
- if(enable)
- __REG_SET(HW_PINCTRL_PULL(bank)) = pin_msk;
- else
- __REG_CLR(HW_PINCTRL_PULL(bank)) = pin_msk;
-}
+enum stmp_family_t g_stmp_family = UNKNOWN;
/**
*
@@ -458,287 +360,38 @@ static void usb_drv_configure_endpoint(int ep_num, int type)
/**
*
- * Clock control
+ * Clkctrl
*
- **/
-#define __CLK_CLKGATE (1 << 31)
-#define __CLK_BUSY (1 << 29)
+ */
#define HW_CLKCTRL_BASE 0x80040000
#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
+#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
-#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
-#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
+#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
-#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
-#define HW_CLKCTRL_CPU__DIV_CPU_BP 0
-#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f
-#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12)
-#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16
-#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
-#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
-#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
-
-#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
-#define HW_CLKCTRL_HBUS__DIV_BP 0
-#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
-#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
-#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
-#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
-#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
-
-#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
-#define HW_CLKCTRL_XBUS__DIV_BP 0
-#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
-#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
-
-#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
-#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
-#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
-#define HW_CLKCTRL_XTAL__PWM_CLK24M_GATE (1 << 29)
-#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
-
-#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
-#define HW_CLKCTRL_PIX__DIV_BP 0
-#define HW_CLKCTRL_PIX__DIV_BM 0xfff
-
-#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
-#define HW_CLKCTRL_SSP__DIV_BP 0
-#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
-
-#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
-#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
-#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
-#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
-#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
-#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
-#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
-#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
-
-#ifdef HAVE_STMP3770
-#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xe0))
-#else
-#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
-#endif
-#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
-#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
-#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
-#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
-
-#ifdef HAVE_STMP3770
-#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xd0))
-#else
-#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
-#endif
-#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
-#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
-#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
-#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
-#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
-#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
-#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
-
-#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
-#define HW_CLKCTRL_RESET_CHIP 0x2
-#define HW_CLKCTRL_RESET_DIG 0x1
-
-/**
- *
- * DMA
- *
- */
-
-/********
- * APHB *
- ********/
-
-#define HW_APBH_BASE 0x80004000
-
-/* APHB channels */
-#define HW_APBH_SSP(ssp) ssp
-
-#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
-#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
-#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
-#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
-#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
-#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
-
-#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
-#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
-#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
-
-#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
-#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
-#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
-
-#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
-
-#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
-
-#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
-
-#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
-
-#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
-
-#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
-
-#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
-#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
-#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
-#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
-#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
-
-/********
- * APHX *
- ********/
-
-/* APHX channels */
-#define HW_APBX_AUDIO_ADC 0
-#define HW_APBX_AUDIO_DAC 1
-#define HW_APBX_I2C 3
-
-#define HW_APBX_BASE 0x80024000
-
-#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
-
-#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
-#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
-#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
-
-#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
-#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
-#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
+/* STMP3600 only */
+#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
+#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
+#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
+#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
-#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30))
-#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i))
-#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
+/* STMP3600 */
+#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
-#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70))
+/* STMP3600 only */
+#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
+#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
+#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
-#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70))
-
-#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70))
-
-#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
-
-#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70))
-
-#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
-
-#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
-#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
-#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
-#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
-#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
-
-/**********
- * COMMON *
- **********/
-
-struct apb_dma_command_t
-{
- struct apb_dma_command_t *next;
- uint32_t cmd;
- void *buffer;
- /* PIO words follow */
-};
-
-#define APBH_DMA_CHANNEL(i) i
-#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
-#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
-#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
-
-#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
-#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
-#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
-#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
-
-#define HW_APB_CHx_CMD__COMMAND_BM 0x3
-#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0
-#define HW_APB_CHx_CMD__COMMAND__WRITE 1
-#define HW_APB_CHx_CMD__COMMAND__READ 2
-#define HW_APB_CHx_CMD__COMMAND__SENSE 3
-#define HW_APB_CHx_CMD__CHAIN (1 << 2)
-#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
-/* those two are only available on APHB */
-#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4)
-#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
-#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
-#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
-/* An errata advise not to use it */
-//#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
-#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
-#define HW_APB_CHx_CMD__CMDWORDS_BP 12
-#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
-#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
-/* For software use */
-#define HW_APB_CHx_CMD__UNUSED_BP 8
-#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
-#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
-
-#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
-#define HW_APB_CHx_SEMA__PHORE_BP 16
-
-/* A single descriptor cannot transfer more than 2^16 bytes */
-#define IMX233_MAX_SINGLE_DMA_XFER_SIZE (1 << 16)
-
-static void imx233_dma_init(void)
-{
- __REG_CLR(HW_APBH_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
- __REG_CLR(HW_APBX_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
-}
-
-static void imx233_dma_reset_channel(unsigned chan)
-{
- volatile uint32_t *ptr;
- uint32_t bm;
- if(APB_IS_APBX_CHANNEL(chan))
- {
- ptr = &HW_APBX_CHANNEL_CTRL;
- bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
- }
- else
- {
- ptr = &HW_APBH_CTRL0;
- bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
- }
- __REG_SET(*ptr) = bm;
- /* wait for end of reset */
- while(*ptr & bm)
- ;
-}
-
-static void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
-{
- if(APB_IS_APBX_CHANNEL(chan))
- {
- HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
- HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
- }
- else
- {
- HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
- HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
- }
-}
-
-static void imx233_dma_wait_completion(unsigned chan)
-{
- volatile uint32_t *sema;
- if(APB_IS_APBX_CHANNEL(chan))
- sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
- else
- sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
-
- while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
- ;
-}
+/* STMP3600 only */
+#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
+#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
+#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
/**
*
@@ -751,8 +404,6 @@ static void imx233_dma_wait_completion(unsigned chan)
#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
-#define HW_DIGCTL_HCLKCOUNT (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x20))
-
#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
@@ -786,7 +437,6 @@ static void udelay(unsigned us)
/* USB Phy */
#define HW_USBPHY_BASE 0x8007C000
#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
-#define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17)
#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
@@ -852,17 +502,9 @@ struct dcp_packet_t
*
*/
-void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length)
-{
- for(uint32_t i = 0; i < length; i++)
- dst[i] = src[i];
-}
-
-void memset(uint8_t *dst, uint8_t fill, uint32_t length)
-{
- for(uint32_t i = 0; i < length; i++)
- dst[i] = fill;
-}
+void memcpy(void *dest, const void *src, size_t n);
+void memmove(void *dest, const void *src, size_t n);
+void memset(void *dst, int value, size_t n);
/**
*
@@ -880,9 +522,9 @@ static struct usb_device_descriptor __attribute__((aligned(2)))
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
- .idVendor = HWEMUL_USB_VID,
- .idProduct = HWEMUL_USB_PID,
- .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR,
+ .idVendor = HWSTUB_USB_VID,
+ .idProduct = HWSTUB_USB_PID,
+ .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
@@ -913,9 +555,9 @@ static struct usb_interface_descriptor __attribute__((aligned(2)))
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 3,
- .bInterfaceClass = HWEMUL_CLASS,
- .bInterfaceSubClass = HWEMUL_SUBCLASS,
- .bInterfaceProtocol = HWEMUL_PROTOCOL,
+ .bInterfaceClass = HWSTUB_CLASS,
+ .bInterfaceSubClass = HWSTUB_SUBCLASS,
+ .bInterfaceProtocol = HWSTUB_PROTOCOL,
.iInterface = 4
};
@@ -966,9 +608,9 @@ static struct usb_string_descriptor __attribute__((aligned(2)))
28,
USB_DT_STRING,
{'A', 'c', 'i', 'd', ' ',
- '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.',
- '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.',
- '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) }
+ '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.',
+ '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.',
+ '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) }
};
/* this is stringid #0: languages supported */
@@ -1138,9 +780,9 @@ static void handle_std_req(struct usb_ctrlrequest *req)
struct usb_resp_info_version_t g_version =
{
- .major = HWEMUL_VERSION_MAJOR,
- .minor = HWEMUL_VERSION_MINOR,
- .revision = HWEMUL_VERSION_REV
+ .major = HWSTUB_VERSION_MAJOR,
+ .minor = HWSTUB_VERSION_MINOR,
+ .revision = HWSTUB_VERSION_REV
};
struct usb_resp_info_layout_t g_layout;
@@ -1149,8 +791,8 @@ struct usb_resp_info_stmp_t g_stmp;
struct usb_resp_info_features_t g_features =
{
- .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM |
- HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP
+ .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM |
+ HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | HWSTUB_FEATURE_AES_OTP
};
static void fill_layout_info(void)
@@ -1177,21 +819,21 @@ static void handle_get_info(struct usb_ctrlrequest *req)
int size = 0;
switch(req->wIndex)
{
- case HWEMUL_INFO_VERSION:
+ case HWSTUB_INFO_VERSION:
ptr = &g_version;
size = sizeof(g_version);
break;
- case HWEMUL_INFO_LAYOUT:
+ case HWSTUB_INFO_LAYOUT:
fill_layout_info();
ptr = &g_layout;
size = sizeof(g_layout);
break;
- case HWEMUL_INFO_STMP:
+ case HWSTUB_INFO_STMP:
fill_stmp_info();
ptr = &g_stmp;
size = sizeof(g_stmp);
break;
- case HWEMUL_INFO_FEATURES:
+ case HWSTUB_INFO_FEATURES:
ptr = &g_features;
size = sizeof(g_features);
break;
@@ -1249,17 +891,22 @@ static void handle_call_jump(struct usb_ctrlrequest *req)
{
uint32_t addr = req->wValue | req->wIndex << 16;
- if(req->bRequest == HWEMUL_CALL)
+ if(req->bRequest == HWSTUB_CALL)
((void (*)(void))addr)();
else
+ {
+ /* disconnect to make sure usb/dma won't interfere */
+ REG_USBCMD &= ~USBCMD_RUN;
+ REG_USBCMD |= USBCMD_CTRL_RESET;
asm volatile("bx %0\n" : : "r" (addr) : "memory");
+ }
}
static void do_aes_otp(void *buffer, unsigned length, unsigned params)
{
static struct dcp_packet_t dcp_packet;
- bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT);
+ bool encrypt = !!(params & HWSTUB_AES_OTP_ENCRYPT);
/* reset DCP */
__REG_SET(HW_DCP_CTRL) = 0x80000000;
/* clear clock gate */
@@ -1307,20 +954,20 @@ static void handle_class_dev_req(struct usb_ctrlrequest *req)
{
switch(req->bRequest)
{
- case HWEMUL_GET_INFO:
+ case HWSTUB_GET_INFO:
handle_get_info(req);
break;
- case HWEMUL_GET_LOG:
+ case HWSTUB_GET_LOG:
handle_get_log(req);
break;
- case HWEMUL_RW_MEM:
+ case HWSTUB_RW_MEM:
handle_rw_mem(req);
break;
- case HWEMUL_CALL:
- case HWEMUL_JUMP:
+ case HWSTUB_CALL:
+ case HWSTUB_JUMP:
handle_call_jump(req);
break;
- case HWEMUL_AES_OTP:
+ case HWSTUB_AES_OTP:
handle_aes_otp(req);
break;
default:
@@ -1348,19 +995,68 @@ static void handle_class_req(struct usb_ctrlrequest *req)
void main(uint32_t arg)
{
usb_buffer_size = oc_buffersize;
-
- logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR,
- HWEMUL_VERSION_REV);
+
+ logf("hwstub %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR,
+ HWSTUB_VERSION_REV);
logf("argument: 0x%08x\n", arg);
+ /* detect family */
+ uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
+ if(product_code >= 0x3600 && product_code < 0x3700)
+ {
+ logf("identified STMP3600 family\n");
+ g_stmp_family = STMP3600;
+ }
+ else if(product_code == 0x3700)
+ {
+ logf("identified STMP3700 family\n");
+ g_stmp_family = STMP3700;
+ }
+ else if(product_code == 0x37b0)
+ {
+ logf("identified STMP3770 family\n");
+ g_stmp_family = STMP3770;
+ }
+ else if(product_code == 0x3780)
+ {
+ logf("identified STMP3780 family\n");
+ g_stmp_family = STMP3780;
+ }
+ else
+ logf("cannot identify family: 0x%x\n", product_code);
+
/* we don't know if USB was connected or not. In USB recovery mode it will
* but in other cases it might not be. In doubt, disconnect */
REG_USBCMD &= ~USBCMD_RUN;
+ if(g_stmp_family == STMP3600)
+ {
+ /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
+ * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
+ * (1.2MHz) for a safe transition */
+ HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
+ /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
+ * switch so lower XBUS too */
+ HW_CLKCTRL_XBUSCLKCTRL = 20;
+ /* Power PLL */
+ __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
+ HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
+ /* Wait lock */
+ while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
+ /* Switch to PLL source */
+ __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
+ /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
+ HW_CLKCTRL_CPUCLKCTRL = 7;
+ HW_CLKCTRL_HBUSCLKCTRL = 7;
+ HW_CLKCTRL_XBUSCLKCTRL = 1;
+ __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
+ __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
+ }
+ else
+ __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
/* enable USB PHY PLL */
__REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
/* power up USB PHY */
__REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
- //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL;
HW_USBPHY_PWD = 0;
/* enable USB controller */
__REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
@@ -1382,7 +1078,7 @@ void main(uint32_t arg)
REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
/* run! */
REG_USBCMD |= USBCMD_RUN;
-
+
while(1)
{
/* wait for setup */