summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub/stmp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stub/stmp')
-rw-r--r--utils/hwstub/stub/stmp/target.c132
1 files changed, 42 insertions, 90 deletions
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c
index 98f65da625..8d48707088 100644
--- a/utils/hwstub/stub/stmp/target.c
+++ b/utils/hwstub/stub/stmp/target.c
@@ -22,6 +22,7 @@
22#include "target.h" 22#include "target.h"
23#include "system.h" 23#include "system.h"
24#include "logf.h" 24#include "logf.h"
25#include "memory.h"
25 26
26#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1))) 27#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
27#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2))) 28#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
@@ -50,34 +51,6 @@ enum stmp_family_t
50}; 51};
51 52
52static enum stmp_family_t g_stmp_family = UNKNOWN; 53static enum stmp_family_t g_stmp_family = UNKNOWN;
53static int g_atexit = HWSTUB_ATEXIT_OFF;
54
55/**
56 *
57 * Power
58 *
59 */
60
61#define HW_POWER_BASE 0x80044000
62
63void power_off(void)
64{
65 switch(g_stmp_family)
66 {
67 case STMP3600:
68 *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770014;
69 break;
70 case STMP3700:
71 case STMP3770:
72 *(volatile uint32_t *)(HW_POWER_BASE + 0xe0) = 0x3e770001;
73 break;
74 case STMP3780:
75 *(volatile uint32_t *)(HW_POWER_BASE + 0x100) = 0x3e770001;
76 break;
77 default:
78 break;
79 }
80}
81 54
82/** 55/**
83 * 56 *
@@ -114,25 +87,6 @@ void power_off(void)
114#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) 87#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
115#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) 88#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
116 89
117void clkctrl_reset(void)
118{
119 switch(g_stmp_family)
120 {
121 case STMP3600:
122 *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770002;
123 break;
124 case STMP3700:
125 case STMP3770:
126 *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0) = 0x1;
127 break;
128 case STMP3780:
129 *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120) = 0x1;
130 break;
131 default:
132 break;
133 }
134}
135
136/** 90/**
137 * 91 *
138 * Digctl 92 * Digctl
@@ -143,11 +97,18 @@ void clkctrl_reset(void)
143#define HW_DIGCTL_BASE 0x8001C000 97#define HW_DIGCTL_BASE 0x8001C000
144#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) 98#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
145#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) 99#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
100#define HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600 (1 << 0)
101
102#define HW_DIGCTL_STATUS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x10))
103#define HW_DIGCTL_STATUS__PACKAGE_TYPE_BP 1
104#define HW_DIGCTL_STATUS__PACKAGE_TYPE_BM (7 << 1)
105#define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BP 1
106#define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BM (1 << 1)
146 107
147/* STMP3700+ */ 108/* STMP3700+ */
148#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) 109#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
149/* STMP3600 */ 110/* STMP3600 */
150#define HW_DIGCTL_MICROSECONDS2 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0)) 111#define HW_DIGCTL_MICROSECONDS_STMP3600 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0))
151 112
152#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) 113#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
153#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 114#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16
@@ -177,8 +138,25 @@ void clkctrl_reset(void)
177#define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0)) 138#define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0))
178#define HW_RTC_CTRL__WATCHDOGEN (1 << 4) 139#define HW_RTC_CTRL__WATCHDOGEN (1 << 4)
179 140
141struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor =
142{
143 sizeof(struct hwstub_target_desc_t),
144 HWSTUB_DT_TARGET,
145 HWSTUB_TARGET_STMP,
146 "STMP3600 / STMP3700 / STMP3780 (i.MX233)"
147};
148
149static struct hwstub_stmp_desc_t __attribute__((aligned(2))) stmp_descriptor =
150{
151 sizeof(struct hwstub_stmp_desc_t),
152 HWSTUB_DT_STMP,
153 0, 0, 0
154};
155
180void target_init(void) 156void target_init(void)
181{ 157{
158 stmp_descriptor.wChipID = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
159 stmp_descriptor.bRevision = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
182 /* detect family */ 160 /* detect family */
183 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); 161 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
184 if(product_code >= 0x3600 && product_code < 0x3700) 162 if(product_code >= 0x3600 && product_code < 0x3700)
@@ -208,6 +186,7 @@ void target_init(void)
208 186
209 if(g_stmp_family == STMP3600) 187 if(g_stmp_family == STMP3600)
210 { 188 {
189 stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE);
211 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will 190 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
212 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed 191 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
213 * (1.2MHz) for a safe transition */ 192 * (1.2MHz) for a safe transition */
@@ -230,7 +209,13 @@ void target_init(void)
230 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE; 209 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
231 } 210 }
232 else 211 else
212 {
213 __REG_SET(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600;
214 stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE_STMP3600);
215 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600;
216
233 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; 217 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
218 }
234 /* enable USB PHY PLL */ 219 /* enable USB PHY PLL */
235 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 220 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
236 /* power up USB PHY */ 221 /* power up USB PHY */
@@ -240,57 +225,24 @@ void target_init(void)
240 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; 225 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
241} 226}
242 227
243static struct usb_resp_info_stmp_t g_stmp; 228void target_get_desc(int desc, void **buffer)
244static struct usb_resp_info_target_t g_target =
245{
246 .id = HWSTUB_TARGET_STMP,
247 .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)"
248};
249
250int target_get_info(int info, void **buffer)
251{ 229{
252 if(info == HWSTUB_INFO_STMP) 230 if(desc == HWSTUB_DT_STMP)
253 { 231 *buffer = &stmp_descriptor;
254 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
255 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
256 g_stmp.is_supported = g_stmp_family != 0;
257 *buffer = &g_stmp;
258 return sizeof(g_stmp);
259 }
260 else if(info == HWSTUB_INFO_TARGET)
261 {
262 *buffer = &g_target;
263 return sizeof(g_target);
264 }
265 else 232 else
266 return -1; 233 *buffer = NULL;
267} 234}
268 235
269int target_atexit(int method) 236void target_get_config_desc(void *buffer, int *size)
270{ 237{
271 g_atexit = method; 238 memcpy(buffer, &stmp_descriptor, sizeof(stmp_descriptor));
272 return 0; 239 *size += sizeof(stmp_descriptor);
273}
274
275void target_exit(void)
276{
277 switch(g_atexit)
278 {
279 case HWSTUB_ATEXIT_OFF:
280 power_off();
281 // fallthrough in case of return
282 case HWSTUB_ATEXIT_REBOOT:
283 clkctrl_reset();
284 // fallthrough in case of return
285 case HWSTUB_ATEXIT_NOP:
286 default:
287 return;
288 }
289} 240}
290 241
291void target_udelay(int us) 242void target_udelay(int us)
292{ 243{
293 volatile uint32_t *reg = g_stmp_family == STMP3600 ? &HW_DIGCTL_MICROSECONDS2 : &HW_DIGCTL_MICROSECONDS; 244 volatile uint32_t *reg = g_stmp_family == STMP3600 ?
245 &HW_DIGCTL_MICROSECONDS_STMP3600 : &HW_DIGCTL_MICROSECONDS;
294 uint32_t cur = *reg; 246 uint32_t cur = *reg;
295 uint32_t end = cur + us; 247 uint32_t end = cur + us;
296 if(cur < end) 248 if(cur < end)