From 140783ef66eef379feedcfef5403c5729d38936a Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sat, 13 Jul 2013 17:35:53 +0200 Subject: 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 --- utils/hwstub/stub/stmp/Makefile | 14 +++ utils/hwstub/stub/stmp/target-config.h | 9 ++ utils/hwstub/stub/stmp/target.c | 205 +++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 utils/hwstub/stub/stmp/Makefile create mode 100644 utils/hwstub/stub/stmp/target-config.h create mode 100644 utils/hwstub/stub/stmp/target.c (limited to 'utils/hwstub/stub/stmp') 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 @@ +# +# common +# +CC=arm-elf-eabi-gcc +LD=arm-elf-eabi-gcc +AS=arm-elf-eabi-gcc +OC=arm-elf-eabi-objcopy +DEFINES= +INCLUDES=-I$(CURDIR) +GCCOPTS=-mcpu=arm926ej-s +BUILD_DIR=$(CURDIR)/build/ +ROOT_DIR=$(CURDIR)/.. + +include ../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 @@ +#define CONFIG_STMP +#define IRAM_ORIG 0 +#define IRAM_SIZE 0x8000 +#define DRAM_ORIG 0x40000000 +#define DRAM_SIZE (MEMORYSIZE * 0x100000) +#define CPU_ARM +#define ARM_ARCH 5 +#define USB_BASE 0x80080000 +#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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2013 by Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "stddef.h" +#include "target.h" +#include "system.h" +#include "logf.h" + +#define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) +#define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) +#define __REG_TOG(reg) (*((volatile uint32_t *)(® + 3))) + +#define __BLOCK_SFTRST (1 << 31) +#define __BLOCK_CLKGATE (1 << 30) + +#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP) +#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP) +#define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP) + +/** + * + * Global + * + */ + +enum stmp_family_t +{ + UNKNOWN, + STMP3600, + STMP3700, + STMP3770, + STMP3780 +}; + +enum stmp_family_t g_stmp_family = UNKNOWN; + +/** + * + * Clkctrl + * + */ + +#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_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10)) +#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31) + +/* 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) + +/* STMP3600 */ +#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30)) + +/* 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 + +/* 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) + +/** + * + * Digctl + * + */ + +/* Digital control */ +#define HW_DIGCTL_BASE 0x8001C000 +#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) +#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) + +#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) + +#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) +#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 +#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000 +#define HW_DIGCTL_CHIPID__REVISION_BP 0 +#define HW_DIGCTL_CHIPID__REVISION_BM 0xff + +#define HZ 1000000 + +/** + * + * USB PHY + * + */ +/* USB Phy */ +#define HW_USBPHY_BASE 0x8007C000 +#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0)) + +#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30)) + +void target_init(void) +{ + /* 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); + + 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; + HW_USBPHY_PWD = 0; + /* enable USB controller */ + __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; +} + +static struct usb_resp_info_stmp_t g_stmp; +static struct usb_resp_info_target_t g_target = +{ + .id = HWSTUB_TARGET_STMP, + .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)" +}; + +int target_get_info(int info, void **buffer) +{ + if(info == HWSTUB_INFO_STMP) + { + g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); + g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION); + g_stmp.is_supported = g_stmp_family != 0; + *buffer = &g_stmp; + return sizeof(g_stmp); + } + else + return -1; +} + +void target_exit(void) +{ +} -- cgit v1.2.3