summaryrefslogtreecommitdiff
path: root/utils/hwstub/stmp/main.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-13 02:02:53 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-13 02:25:15 +0200
commitc5357940ab0108b4102442d07825c44d5be0d22f (patch)
treeddfdd9744b1f0ac037fed1c802329cb4542f376b /utils/hwstub/stmp/main.c
parent934e1e15af6f2b7bcfdd9dbe8a3a6393ffe5a4a1 (diff)
downloadrockbox-c5357940ab0108b4102442d07825c44d5be0d22f.tar.gz
rockbox-c5357940ab0108b4102442d07825c44d5be0d22f.zip
hwstub: major improvement in the stub and the tools
Fix the stub in many way to correctly detect the STMP family and act upon that. Drop some unused commands and bump version. Rewrite the tool to allows scripting in lua and load the register description from an XML file using the regtools. Introduce a new tool to load and run code using the hwstub (either binary format or Rockbox additive scramble format). Also switch to an optimise version of the memcpy/move/set functions to correctly handle alignement issue (like writing a full word/half-word when possible for registers which is crucial) Change-Id: Id1d5cfe0b1b47e8b43900d32c5cd6eafae6414f6
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 */