summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub/stmp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-07-13 17:35:53 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-07-13 17:47:01 +0200
commit140783ef66eef379feedcfef5403c5729d38936a (patch)
tree0185a6a6ef80ab134150454674a1d7e1333b8757 /utils/hwstub/stub/stmp
parent3dd5e983db8d83113cc76ee0f5c02e158380606a (diff)
downloadrockbox-140783ef66eef379feedcfef5403c5729d38936a.tar.gz
rockbox-140783ef66eef379feedcfef5403c5729d38936a.zip
hwstub: split target specific code from the common part
Completely rewrite the Mafile, properly put the usb driver in its own file and the target specific files in a subdirectory. Change-Id: Iaeee0128e021d5dad76b4d6035a63e33e2d946c1
Diffstat (limited to 'utils/hwstub/stub/stmp')
-rw-r--r--utils/hwstub/stub/stmp/Makefile14
-rw-r--r--utils/hwstub/stub/stmp/target-config.h9
-rw-r--r--utils/hwstub/stub/stmp/target.c205
3 files changed, 228 insertions, 0 deletions
diff --git a/utils/hwstub/stub/stmp/Makefile b/utils/hwstub/stub/stmp/Makefile
new file mode 100644
index 0000000000..14e6d0fbba
--- /dev/null
+++ b/utils/hwstub/stub/stmp/Makefile
@@ -0,0 +1,14 @@
1#
2# common
3#
4CC=arm-elf-eabi-gcc
5LD=arm-elf-eabi-gcc
6AS=arm-elf-eabi-gcc
7OC=arm-elf-eabi-objcopy
8DEFINES=
9INCLUDES=-I$(CURDIR)
10GCCOPTS=-mcpu=arm926ej-s
11BUILD_DIR=$(CURDIR)/build/
12ROOT_DIR=$(CURDIR)/..
13
14include ../hwstub.make \ No newline at end of file
diff --git a/utils/hwstub/stub/stmp/target-config.h b/utils/hwstub/stub/stmp/target-config.h
new file mode 100644
index 0000000000..aba2cf564b
--- /dev/null
+++ b/utils/hwstub/stub/stmp/target-config.h
@@ -0,0 +1,9 @@
1#define CONFIG_STMP
2#define IRAM_ORIG 0
3#define IRAM_SIZE 0x8000
4#define DRAM_ORIG 0x40000000
5#define DRAM_SIZE (MEMORYSIZE * 0x100000)
6#define CPU_ARM
7#define ARM_ARCH 5
8#define USB_BASE 0x80080000
9#define USB_NUM_ENDPOINTS 2 \ No newline at end of file
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c
new file mode 100644
index 0000000000..60411f908e
--- /dev/null
+++ b/utils/hwstub/stub/stmp/target.c
@@ -0,0 +1,205 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "stddef.h"
22#include "target.h"
23#include "system.h"
24#include "logf.h"
25
26#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
27#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
28#define __REG_TOG(reg) (*((volatile uint32_t *)(&reg + 3)))
29
30#define __BLOCK_SFTRST (1 << 31)
31#define __BLOCK_CLKGATE (1 << 30)
32
33#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
34#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
35#define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP)
36
37/**
38 *
39 * Global
40 *
41 */
42
43enum stmp_family_t
44{
45 UNKNOWN,
46 STMP3600,
47 STMP3700,
48 STMP3770,
49 STMP3780
50};
51
52enum stmp_family_t g_stmp_family = UNKNOWN;
53
54/**
55 *
56 * Clkctrl
57 *
58 */
59
60#define HW_CLKCTRL_BASE 0x80040000
61
62#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
63#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
64#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
65#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
66
67#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
68#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
69
70/* STMP3600 only */
71#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
72#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
73#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
74#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
75
76/* STMP3600 */
77#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
78
79/* STMP3600 only */
80#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
81#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
82#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
83
84/* STMP3600 only */
85#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
86#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
87#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
88
89/**
90 *
91 * Digctl
92 *
93 */
94
95/* Digital control */
96#define HW_DIGCTL_BASE 0x8001C000
97#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
98#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
99
100#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
101
102#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
103#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16
104#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000
105#define HW_DIGCTL_CHIPID__REVISION_BP 0
106#define HW_DIGCTL_CHIPID__REVISION_BM 0xff
107
108#define HZ 1000000
109
110/**
111 *
112 * USB PHY
113 *
114 */
115/* USB Phy */
116#define HW_USBPHY_BASE 0x8007C000
117#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
118
119#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
120
121void target_init(void)
122{
123 /* detect family */
124 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
125 if(product_code >= 0x3600 && product_code < 0x3700)
126 {
127 logf("identified STMP3600 family\n");
128 g_stmp_family = STMP3600;
129 }
130 else if(product_code == 0x3700)
131 {
132 logf("identified STMP3700 family\n");
133 g_stmp_family = STMP3700;
134 }
135 else if(product_code == 0x37b0)
136 {
137 logf("identified STMP3770 family\n");
138 g_stmp_family = STMP3770;
139 }
140 else if(product_code == 0x3780)
141 {
142 logf("identified STMP3780 family\n");
143 g_stmp_family = STMP3780;
144 }
145 else
146 logf("cannot identify family: 0x%x\n", product_code);
147
148 if(g_stmp_family == STMP3600)
149 {
150 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
151 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
152 * (1.2MHz) for a safe transition */
153 HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
154 /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
155 * switch so lower XBUS too */
156 HW_CLKCTRL_XBUSCLKCTRL = 20;
157 /* Power PLL */
158 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
159 HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
160 /* Wait lock */
161 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
162 /* Switch to PLL source */
163 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
164 /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
165 HW_CLKCTRL_CPUCLKCTRL = 7;
166 HW_CLKCTRL_HBUSCLKCTRL = 7;
167 HW_CLKCTRL_XBUSCLKCTRL = 1;
168 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
169 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
170 }
171 else
172 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
173 /* enable USB PHY PLL */
174 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
175 /* power up USB PHY */
176 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
177 HW_USBPHY_PWD = 0;
178 /* enable USB controller */
179 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
180}
181
182static struct usb_resp_info_stmp_t g_stmp;
183static struct usb_resp_info_target_t g_target =
184{
185 .id = HWSTUB_TARGET_STMP,
186 .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)"
187};
188
189int target_get_info(int info, void **buffer)
190{
191 if(info == HWSTUB_INFO_STMP)
192 {
193 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
194 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
195 g_stmp.is_supported = g_stmp_family != 0;
196 *buffer = &g_stmp;
197 return sizeof(g_stmp);
198 }
199 else
200 return -1;
201}
202
203void target_exit(void)
204{
205}