summaryrefslogtreecommitdiff
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[];
34 34
35/** 35/**
36 * 36 *
37 * Pin control 37 * Global
38 * 38 *
39 */ 39 */
40 40
41#define HW_PINCTRL_BASE 0x80018000 41enum stmp_family_t
42
43#define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0))
44#define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10))
45#define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10))
46#ifdef HAVE_STMP3700
47#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x300 + (i) * 0x10))
48#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
49#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
50#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
51#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
52#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
53#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
54#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
55#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
56#else
57#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
58#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
59#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
60#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
61#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
62#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
63#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
64#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
65#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10))
66#endif
67
68#define PINCTRL_FUNCTION_MAIN 0
69#define PINCTRL_FUNCTION_ALT1 1
70#define PINCTRL_FUNCTION_ALT2 2
71#define PINCTRL_FUNCTION_GPIO 3
72
73#define PINCTRL_DRIVE_4mA 0
74#define PINCTRL_DRIVE_8mA 1
75#define PINCTRL_DRIVE_12mA 2
76#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
77
78typedef void (*pin_irq_cb_t)(int bank, int pin);
79
80static inline void imx233_pinctrl_init(void)
81{ 42{
82 __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; 43 UNKNOWN,
83} 44 STMP3600,
84 45 STMP3700,
85static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength) 46 STMP3770,
86{ 47 STMP3780
87 __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8)); 48};
88 __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8));
89}
90
91static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable)
92{
93 if(enable)
94 __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin;
95 else
96 __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin;
97}
98
99static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable)
100{
101 if(enable)
102 __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask;
103 else
104 __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask;
105}
106
107static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value)
108{
109 if(value)
110 __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin;
111 else
112 __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin;
113}
114
115static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value)
116{
117 if(value)
118 __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask;
119 else
120 __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask;
121}
122
123static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask)
124{
125 return HW_PINCTRL_DIN(bank) & pin_mask;
126}
127
128static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function)
129{
130 __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16));
131 __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16));
132}
133
134static inline void imx233_enable_pin_pullup(unsigned bank, unsigned pin, bool enable)
135{
136 if(enable)
137 __REG_SET(HW_PINCTRL_PULL(bank)) = 1 << pin;
138 else
139 __REG_CLR(HW_PINCTRL_PULL(bank)) = 1 << pin;
140}
141 49
142static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk, bool enable) 50enum stmp_family_t g_stmp_family = UNKNOWN;
143{
144 if(enable)
145 __REG_SET(HW_PINCTRL_PULL(bank)) = pin_msk;
146 else
147 __REG_CLR(HW_PINCTRL_PULL(bank)) = pin_msk;
148}
149 51
150/** 52/**
151 * 53 *
@@ -458,287 +360,38 @@ static void usb_drv_configure_endpoint(int ep_num, int type)
458 360
459/** 361/**
460 * 362 *
461 * Clock control 363 * Clkctrl
462 * 364 *
463 **/ 365 */
464#define __CLK_CLKGATE (1 << 31)
465#define __CLK_BUSY (1 << 29)
466 366
467#define HW_CLKCTRL_BASE 0x80040000 367#define HW_CLKCTRL_BASE 0x80040000
468 368
469#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0)) 369#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
370#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
470#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16) 371#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
471#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18) 372#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
472#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
473#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
474 373
475#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10)) 374#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
375#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
476 376
477#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20)) 377/* STMP3600 only */
478#define HW_CLKCTRL_CPU__DIV_CPU_BP 0 378#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
479#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f 379#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
480#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12) 380#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
481#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16 381#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
482#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
483#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
484#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
485
486#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
487#define HW_CLKCTRL_HBUS__DIV_BP 0
488#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
489#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
490#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
491#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
492#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
493
494#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
495#define HW_CLKCTRL_XBUS__DIV_BP 0
496#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
497#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
498
499#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
500#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
501#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
502#define HW_CLKCTRL_XTAL__PWM_CLK24M_GATE (1 << 29)
503#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
504
505#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
506#define HW_CLKCTRL_PIX__DIV_BP 0
507#define HW_CLKCTRL_PIX__DIV_BM 0xfff
508
509#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
510#define HW_CLKCTRL_SSP__DIV_BP 0
511#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
512
513#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
514#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
515#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
516#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
517#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
518#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
519#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
520#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
521
522#ifdef HAVE_STMP3770
523#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xe0))
524#else
525#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
526#endif
527#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
528#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
529#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
530#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
531
532#ifdef HAVE_STMP3770
533#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xd0))
534#else
535#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
536#endif
537#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
538#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
539#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
540#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
541#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
542#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
543#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
544
545#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
546#define HW_CLKCTRL_RESET_CHIP 0x2
547#define HW_CLKCTRL_RESET_DIG 0x1
548
549/**
550 *
551 * DMA
552 *
553 */
554
555/********
556 * APHB *
557 ********/
558
559#define HW_APBH_BASE 0x80004000
560
561/* APHB channels */
562#define HW_APBH_SSP(ssp) ssp
563
564#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
565#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
566#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
567#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
568#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
569#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
570
571#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
572#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
573#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
574
575#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
576#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
577#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
578
579#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
580
581#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
582
583#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
584
585#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
586
587#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
588
589#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
590
591#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
592#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
593#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
594#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
595#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
596
597/********
598 * APHX *
599 ********/
600
601/* APHX channels */
602#define HW_APBX_AUDIO_ADC 0
603#define HW_APBX_AUDIO_DAC 1
604#define HW_APBX_I2C 3
605
606#define HW_APBX_BASE 0x80024000
607
608#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
609
610#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
611#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
612#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
613
614#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
615#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
616#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
617 382
618#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30)) 383/* STMP3600 */
619#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i)) 384#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
620#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
621 385
622#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70)) 386/* STMP3600 only */
387#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
388#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
389#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
623 390
624#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70)) 391/* STMP3600 only */
625 392#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
626#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70)) 393#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
627 394#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
628#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
629
630#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70))
631
632#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
633
634#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
635#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
636#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
637#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
638#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
639
640/**********
641 * COMMON *
642 **********/
643
644struct apb_dma_command_t
645{
646 struct apb_dma_command_t *next;
647 uint32_t cmd;
648 void *buffer;
649 /* PIO words follow */
650};
651
652#define APBH_DMA_CHANNEL(i) i
653#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
654#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
655#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
656
657#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
658#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
659#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
660#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
661
662#define HW_APB_CHx_CMD__COMMAND_BM 0x3
663#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0
664#define HW_APB_CHx_CMD__COMMAND__WRITE 1
665#define HW_APB_CHx_CMD__COMMAND__READ 2
666#define HW_APB_CHx_CMD__COMMAND__SENSE 3
667#define HW_APB_CHx_CMD__CHAIN (1 << 2)
668#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
669/* those two are only available on APHB */
670#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4)
671#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
672#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
673#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
674/* An errata advise not to use it */
675//#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
676#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
677#define HW_APB_CHx_CMD__CMDWORDS_BP 12
678#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
679#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
680/* For software use */
681#define HW_APB_CHx_CMD__UNUSED_BP 8
682#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
683#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
684
685#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
686#define HW_APB_CHx_SEMA__PHORE_BP 16
687
688/* A single descriptor cannot transfer more than 2^16 bytes */
689#define IMX233_MAX_SINGLE_DMA_XFER_SIZE (1 << 16)
690
691static void imx233_dma_init(void)
692{
693 __REG_CLR(HW_APBH_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
694 __REG_CLR(HW_APBX_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
695}
696
697static void imx233_dma_reset_channel(unsigned chan)
698{
699 volatile uint32_t *ptr;
700 uint32_t bm;
701 if(APB_IS_APBX_CHANNEL(chan))
702 {
703 ptr = &HW_APBX_CHANNEL_CTRL;
704 bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
705 }
706 else
707 {
708 ptr = &HW_APBH_CTRL0;
709 bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
710 }
711 __REG_SET(*ptr) = bm;
712 /* wait for end of reset */
713 while(*ptr & bm)
714 ;
715}
716
717static void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
718{
719 if(APB_IS_APBX_CHANNEL(chan))
720 {
721 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
722 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
723 }
724 else
725 {
726 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
727 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
728 }
729}
730
731static void imx233_dma_wait_completion(unsigned chan)
732{
733 volatile uint32_t *sema;
734 if(APB_IS_APBX_CHANNEL(chan))
735 sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
736 else
737 sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
738
739 while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
740 ;
741}
742 395
743/** 396/**
744 * 397 *
@@ -751,8 +404,6 @@ static void imx233_dma_wait_completion(unsigned chan)
751#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) 404#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
752#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) 405#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
753 406
754#define HW_DIGCTL_HCLKCOUNT (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x20))
755
756#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) 407#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
757 408
758#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) 409#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
@@ -786,7 +437,6 @@ static void udelay(unsigned us)
786/* USB Phy */ 437/* USB Phy */
787#define HW_USBPHY_BASE 0x8007C000 438#define HW_USBPHY_BASE 0x8007C000
788#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0)) 439#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
789#define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17)
790 440
791#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30)) 441#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
792 442
@@ -852,17 +502,9 @@ struct dcp_packet_t
852 * 502 *
853 */ 503 */
854 504
855void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length) 505void memcpy(void *dest, const void *src, size_t n);
856{ 506void memmove(void *dest, const void *src, size_t n);
857 for(uint32_t i = 0; i < length; i++) 507void memset(void *dst, int value, size_t n);
858 dst[i] = src[i];
859}
860
861void memset(uint8_t *dst, uint8_t fill, uint32_t length)
862{
863 for(uint32_t i = 0; i < length; i++)
864 dst[i] = fill;
865}
866 508
867/** 509/**
868 * 510 *
@@ -880,9 +522,9 @@ static struct usb_device_descriptor __attribute__((aligned(2)))
880 .bDeviceSubClass = 0, 522 .bDeviceSubClass = 0,
881 .bDeviceProtocol = 0, 523 .bDeviceProtocol = 0,
882 .bMaxPacketSize0 = 64, 524 .bMaxPacketSize0 = 64,
883 .idVendor = HWEMUL_USB_VID, 525 .idVendor = HWSTUB_USB_VID,
884 .idProduct = HWEMUL_USB_PID, 526 .idProduct = HWSTUB_USB_PID,
885 .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR, 527 .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR,
886 .iManufacturer = 1, 528 .iManufacturer = 1,
887 .iProduct = 2, 529 .iProduct = 2,
888 .iSerialNumber = 3, 530 .iSerialNumber = 3,
@@ -913,9 +555,9 @@ static struct usb_interface_descriptor __attribute__((aligned(2)))
913 .bInterfaceNumber = 0, 555 .bInterfaceNumber = 0,
914 .bAlternateSetting = 0, 556 .bAlternateSetting = 0,
915 .bNumEndpoints = 3, 557 .bNumEndpoints = 3,
916 .bInterfaceClass = HWEMUL_CLASS, 558 .bInterfaceClass = HWSTUB_CLASS,
917 .bInterfaceSubClass = HWEMUL_SUBCLASS, 559 .bInterfaceSubClass = HWSTUB_SUBCLASS,
918 .bInterfaceProtocol = HWEMUL_PROTOCOL, 560 .bInterfaceProtocol = HWSTUB_PROTOCOL,
919 .iInterface = 4 561 .iInterface = 4
920}; 562};
921 563
@@ -966,9 +608,9 @@ static struct usb_string_descriptor __attribute__((aligned(2)))
966 28, 608 28,
967 USB_DT_STRING, 609 USB_DT_STRING,
968 {'A', 'c', 'i', 'd', ' ', 610 {'A', 'c', 'i', 'd', ' ',
969 '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.', 611 '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.',
970 '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.', 612 '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.',
971 '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) } 613 '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) }
972}; 614};
973 615
974/* this is stringid #0: languages supported */ 616/* this is stringid #0: languages supported */
@@ -1138,9 +780,9 @@ static void handle_std_req(struct usb_ctrlrequest *req)
1138 780
1139struct usb_resp_info_version_t g_version = 781struct usb_resp_info_version_t g_version =
1140{ 782{
1141 .major = HWEMUL_VERSION_MAJOR, 783 .major = HWSTUB_VERSION_MAJOR,
1142 .minor = HWEMUL_VERSION_MINOR, 784 .minor = HWSTUB_VERSION_MINOR,
1143 .revision = HWEMUL_VERSION_REV 785 .revision = HWSTUB_VERSION_REV
1144}; 786};
1145 787
1146struct usb_resp_info_layout_t g_layout; 788struct usb_resp_info_layout_t g_layout;
@@ -1149,8 +791,8 @@ struct usb_resp_info_stmp_t g_stmp;
1149 791
1150struct usb_resp_info_features_t g_features = 792struct usb_resp_info_features_t g_features =
1151{ 793{
1152 .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM | 794 .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM |
1153 HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP 795 HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | HWSTUB_FEATURE_AES_OTP
1154}; 796};
1155 797
1156static void fill_layout_info(void) 798static void fill_layout_info(void)
@@ -1177,21 +819,21 @@ static void handle_get_info(struct usb_ctrlrequest *req)
1177 int size = 0; 819 int size = 0;
1178 switch(req->wIndex) 820 switch(req->wIndex)
1179 { 821 {
1180 case HWEMUL_INFO_VERSION: 822 case HWSTUB_INFO_VERSION:
1181 ptr = &g_version; 823 ptr = &g_version;
1182 size = sizeof(g_version); 824 size = sizeof(g_version);
1183 break; 825 break;
1184 case HWEMUL_INFO_LAYOUT: 826 case HWSTUB_INFO_LAYOUT:
1185 fill_layout_info(); 827 fill_layout_info();
1186 ptr = &g_layout; 828 ptr = &g_layout;
1187 size = sizeof(g_layout); 829 size = sizeof(g_layout);
1188 break; 830 break;
1189 case HWEMUL_INFO_STMP: 831 case HWSTUB_INFO_STMP:
1190 fill_stmp_info(); 832 fill_stmp_info();
1191 ptr = &g_stmp; 833 ptr = &g_stmp;
1192 size = sizeof(g_stmp); 834 size = sizeof(g_stmp);
1193 break; 835 break;
1194 case HWEMUL_INFO_FEATURES: 836 case HWSTUB_INFO_FEATURES:
1195 ptr = &g_features; 837 ptr = &g_features;
1196 size = sizeof(g_features); 838 size = sizeof(g_features);
1197 break; 839 break;
@@ -1249,17 +891,22 @@ static void handle_call_jump(struct usb_ctrlrequest *req)
1249{ 891{
1250 uint32_t addr = req->wValue | req->wIndex << 16; 892 uint32_t addr = req->wValue | req->wIndex << 16;
1251 893
1252 if(req->bRequest == HWEMUL_CALL) 894 if(req->bRequest == HWSTUB_CALL)
1253 ((void (*)(void))addr)(); 895 ((void (*)(void))addr)();
1254 else 896 else
897 {
898 /* disconnect to make sure usb/dma won't interfere */
899 REG_USBCMD &= ~USBCMD_RUN;
900 REG_USBCMD |= USBCMD_CTRL_RESET;
1255 asm volatile("bx %0\n" : : "r" (addr) : "memory"); 901 asm volatile("bx %0\n" : : "r" (addr) : "memory");
902 }
1256} 903}
1257 904
1258static void do_aes_otp(void *buffer, unsigned length, unsigned params) 905static void do_aes_otp(void *buffer, unsigned length, unsigned params)
1259{ 906{
1260 static struct dcp_packet_t dcp_packet; 907 static struct dcp_packet_t dcp_packet;
1261 908
1262 bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT); 909 bool encrypt = !!(params & HWSTUB_AES_OTP_ENCRYPT);
1263 /* reset DCP */ 910 /* reset DCP */
1264 __REG_SET(HW_DCP_CTRL) = 0x80000000; 911 __REG_SET(HW_DCP_CTRL) = 0x80000000;
1265 /* clear clock gate */ 912 /* clear clock gate */
@@ -1307,20 +954,20 @@ static void handle_class_dev_req(struct usb_ctrlrequest *req)
1307{ 954{
1308 switch(req->bRequest) 955 switch(req->bRequest)
1309 { 956 {
1310 case HWEMUL_GET_INFO: 957 case HWSTUB_GET_INFO:
1311 handle_get_info(req); 958 handle_get_info(req);
1312 break; 959 break;
1313 case HWEMUL_GET_LOG: 960 case HWSTUB_GET_LOG:
1314 handle_get_log(req); 961 handle_get_log(req);
1315 break; 962 break;
1316 case HWEMUL_RW_MEM: 963 case HWSTUB_RW_MEM:
1317 handle_rw_mem(req); 964 handle_rw_mem(req);
1318 break; 965 break;
1319 case HWEMUL_CALL: 966 case HWSTUB_CALL:
1320 case HWEMUL_JUMP: 967 case HWSTUB_JUMP:
1321 handle_call_jump(req); 968 handle_call_jump(req);
1322 break; 969 break;
1323 case HWEMUL_AES_OTP: 970 case HWSTUB_AES_OTP:
1324 handle_aes_otp(req); 971 handle_aes_otp(req);
1325 break; 972 break;
1326 default: 973 default:
@@ -1348,19 +995,68 @@ static void handle_class_req(struct usb_ctrlrequest *req)
1348void main(uint32_t arg) 995void main(uint32_t arg)
1349{ 996{
1350 usb_buffer_size = oc_buffersize; 997 usb_buffer_size = oc_buffersize;
1351 998
1352 logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, 999 logf("hwstub %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR,
1353 HWEMUL_VERSION_REV); 1000 HWSTUB_VERSION_REV);
1354 logf("argument: 0x%08x\n", arg); 1001 logf("argument: 0x%08x\n", arg);
1355 1002
1003 /* detect family */
1004 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
1005 if(product_code >= 0x3600 && product_code < 0x3700)
1006 {
1007 logf("identified STMP3600 family\n");
1008 g_stmp_family = STMP3600;
1009 }
1010 else if(product_code == 0x3700)
1011 {
1012 logf("identified STMP3700 family\n");
1013 g_stmp_family = STMP3700;
1014 }
1015 else if(product_code == 0x37b0)
1016 {
1017 logf("identified STMP3770 family\n");
1018 g_stmp_family = STMP3770;
1019 }
1020 else if(product_code == 0x3780)
1021 {
1022 logf("identified STMP3780 family\n");
1023 g_stmp_family = STMP3780;
1024 }
1025 else
1026 logf("cannot identify family: 0x%x\n", product_code);
1027
1356 /* we don't know if USB was connected or not. In USB recovery mode it will 1028 /* we don't know if USB was connected or not. In USB recovery mode it will
1357 * but in other cases it might not be. In doubt, disconnect */ 1029 * but in other cases it might not be. In doubt, disconnect */
1358 REG_USBCMD &= ~USBCMD_RUN; 1030 REG_USBCMD &= ~USBCMD_RUN;
1031 if(g_stmp_family == STMP3600)
1032 {
1033 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
1034 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
1035 * (1.2MHz) for a safe transition */
1036 HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
1037 /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
1038 * switch so lower XBUS too */
1039 HW_CLKCTRL_XBUSCLKCTRL = 20;
1040 /* Power PLL */
1041 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1042 HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
1043 /* Wait lock */
1044 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
1045 /* Switch to PLL source */
1046 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
1047 /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
1048 HW_CLKCTRL_CPUCLKCTRL = 7;
1049 HW_CLKCTRL_HBUSCLKCTRL = 7;
1050 HW_CLKCTRL_XBUSCLKCTRL = 1;
1051 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
1052 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
1053 }
1054 else
1055 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1359 /* enable USB PHY PLL */ 1056 /* enable USB PHY PLL */
1360 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 1057 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
1361 /* power up USB PHY */ 1058 /* power up USB PHY */
1362 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; 1059 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
1363 //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL;
1364 HW_USBPHY_PWD = 0; 1060 HW_USBPHY_PWD = 0;
1365 /* enable USB controller */ 1061 /* enable USB controller */
1366 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; 1062 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
@@ -1382,7 +1078,7 @@ void main(uint32_t arg)
1382 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0; 1078 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1383 /* run! */ 1079 /* run! */
1384 REG_USBCMD |= USBCMD_RUN; 1080 REG_USBCMD |= USBCMD_RUN;
1385 1081
1386 while(1) 1082 while(1)
1387 { 1083 {
1388 /* wait for setup */ 1084 /* wait for setup */