mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 01:10:20 +08:00
Add dm365 porting.
This commit is contained in:
22
bsp/dm365/platform/SConscript
Normal file
22
bsp/dm365/platform/SConscript
Normal file
@@ -0,0 +1,22 @@
|
||||
Import('RTT_ROOT')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Split("""
|
||||
start_gcc.S
|
||||
dm365.c
|
||||
dma.c
|
||||
findbit.S
|
||||
interrupt.c
|
||||
psc.c
|
||||
reset.c
|
||||
system_clock.c
|
||||
trap.c
|
||||
""")
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
path = [cwd]
|
||||
|
||||
group = DefineGroup('Startup', src, depend = [''], CPPPATH = path)
|
||||
|
||||
Return('group')
|
||||
344
bsp/dm365/platform/dm365.c
Normal file
344
bsp/dm365/platform/dm365.c
Normal file
@@ -0,0 +1,344 @@
|
||||
#include <edma.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
static rt_uint32_t commonrate;
|
||||
static rt_uint32_t div_by_four;
|
||||
static rt_uint32_t div_by_six;
|
||||
static rt_uint32_t armrate;
|
||||
static rt_uint32_t fixedrate;
|
||||
static rt_uint32_t ddrrate;
|
||||
static rt_uint32_t voicerate;
|
||||
static rt_uint32_t mmcsdrate;
|
||||
static rt_uint32_t vpssrate, vencrate_sd, vencrate_hd;
|
||||
|
||||
|
||||
/* Four Transfer Controllers on DM365 */
|
||||
static const rt_int8_t
|
||||
dm365_queue_tc_mapping[][2] = {
|
||||
/* {event queue no, TC no} */
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static const rt_int8_t
|
||||
dm365_queue_priority_mapping[][2] = {
|
||||
/* {event queue no, Priority} */
|
||||
{0, 7},
|
||||
{1, 7},
|
||||
{2, 7},
|
||||
{3, 0},
|
||||
{-1, -1},
|
||||
};
|
||||
|
||||
static struct edma_soc_info edma_cc0_info = {
|
||||
.n_channel = 64,
|
||||
.n_region = 4,
|
||||
.n_slot = 256,
|
||||
.n_tc = 4,
|
||||
.n_cc = 1,
|
||||
.queue_tc_mapping = dm365_queue_tc_mapping,
|
||||
.queue_priority_mapping = dm365_queue_priority_mapping,
|
||||
.default_queue = EVENTQ_3,
|
||||
};
|
||||
|
||||
static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
|
||||
&edma_cc0_info,
|
||||
};
|
||||
|
||||
static rt_list_t clocks;
|
||||
|
||||
struct clk {
|
||||
char name[32];
|
||||
rt_uint32_t *rate_hz;
|
||||
struct clk *parent;
|
||||
rt_list_t node;
|
||||
};
|
||||
|
||||
static struct clk davinci_dm365_clks[] = {
|
||||
{
|
||||
.name = "ARMCLK",
|
||||
.rate_hz = &armrate,
|
||||
},
|
||||
{
|
||||
.name = "UART0",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "UART1",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "HPI",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "EMACCLK",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "I2CCLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "McBSPCLK",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "MMCSDCLK0",
|
||||
.rate_hz = &mmcsdrate,
|
||||
},
|
||||
{
|
||||
.name = "MMCSDCLK1",
|
||||
.rate_hz = &mmcsdrate,
|
||||
},
|
||||
{
|
||||
.name = "SPICLK",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "gpio",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "AEMIFCLK",
|
||||
.rate_hz = &commonrate,
|
||||
},
|
||||
{
|
||||
.name = "PWM0_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "PWM1_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "PWM2_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "PWM3_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "USBCLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "VOICECODEC_CLK",
|
||||
.rate_hz = &voicerate,
|
||||
},
|
||||
{
|
||||
.name = "RTC_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "KEYSCAN_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
{
|
||||
.name = "ADCIF_CLK",
|
||||
.rate_hz = &fixedrate,
|
||||
},
|
||||
};
|
||||
|
||||
/* clocks cannot be de-registered no refcounting necessary */
|
||||
struct clk *clk_get(const char *id)
|
||||
{
|
||||
struct clk *clk;
|
||||
rt_list_t *list;
|
||||
|
||||
for (list = (&clocks)->next; list != &clocks; list = list->next)
|
||||
{
|
||||
clk = (struct clk *)rt_list_entry(list, struct clk, node);
|
||||
if (rt_strcmp(id, clk->name) == 0)
|
||||
return clk;
|
||||
}
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
rt_uint32_t clk_get_rate(struct clk *clk)
|
||||
{
|
||||
rt_uint32_t flags;
|
||||
rt_uint32_t *rate;
|
||||
|
||||
for (;;) {
|
||||
rate = clk->rate_hz;
|
||||
if (rate || !clk->parent)
|
||||
break;
|
||||
clk = clk->parent;
|
||||
}
|
||||
return *rate;
|
||||
}
|
||||
|
||||
void clk_register(struct clk *clk)
|
||||
{
|
||||
rt_list_insert_after(&clocks, &clk->node);
|
||||
}
|
||||
|
||||
int davinci_register_clks(struct clk *clk_list, int num_clks)
|
||||
{
|
||||
struct clk *clkp;
|
||||
int i;
|
||||
|
||||
for (i = 0, clkp = clk_list; i < num_clks; i++, clkp++)
|
||||
{
|
||||
//rt_kprintf("1:%s\n", clkp->name);
|
||||
clk_register(clkp);
|
||||
//rt_kprintf("2:%s\n", clkp->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PLL/Reset register offsets */
|
||||
#define PLLM 0x110
|
||||
#define PREDIV 0x114
|
||||
#define PLLDIV2 0x11C
|
||||
#define POSTDIV 0x128
|
||||
#define PLLDIV4 0x160
|
||||
#define PLLDIV5 0x164
|
||||
#define PLLDIV6 0x168
|
||||
#define PLLDIV7 0x16C
|
||||
#define PLLDIV8 0x170
|
||||
|
||||
|
||||
int davinci_clk_init(void)
|
||||
{
|
||||
struct clk *clk_list;
|
||||
int num_clks;
|
||||
rt_uint32_t pll0_mult, pll1_mult;
|
||||
|
||||
unsigned long prediv, postdiv;
|
||||
unsigned long pll_rate;
|
||||
unsigned long pll_div2, pll_div4, pll_div5,
|
||||
pll_div6, pll_div7, pll_div8;
|
||||
|
||||
rt_list_init(&clocks);
|
||||
|
||||
//davinci_psc_register(davinci_psc_base, 1);
|
||||
|
||||
pll0_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
|
||||
pll1_mult = davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLM);
|
||||
|
||||
commonrate = ((pll0_mult + 1) * 27000000) / 6;
|
||||
armrate = ((pll0_mult + 1) * 27000000) / 2;
|
||||
|
||||
fixedrate = 24000000;
|
||||
|
||||
/* Read PLL0 configuration */
|
||||
prediv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PREDIV) &
|
||||
0x1f) + 1;
|
||||
postdiv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + POSTDIV) &
|
||||
0x1f) + 1;
|
||||
|
||||
/* PLL0 dividers */
|
||||
pll_div4 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV4) &
|
||||
0x1f) + 1; /* EDMA, EMAC, config, common */
|
||||
pll_div5 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV5) &
|
||||
0x1f) + 1; /* VPSS */
|
||||
pll_div6 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV6) &
|
||||
0x1f) + 1; /* VENC */
|
||||
pll_div7 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV7) &
|
||||
0x1f) + 1; /* DDR */
|
||||
pll_div8 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV8) &
|
||||
0x1f) + 1; /* MMC/SD */
|
||||
|
||||
pll_rate = ((fixedrate / prediv) * (2 * pll0_mult)) / postdiv;
|
||||
|
||||
commonrate = pll_rate / pll_div4; /* 486/4 = 121.5MHz */
|
||||
vpssrate = pll_rate / pll_div5; /* 486/2 = 243MHz */
|
||||
vencrate_sd = pll_rate / pll_div6; /* 486/18 = 27MHz */
|
||||
ddrrate = pll_rate / pll_div7; /* 486/2 = 243MHz */
|
||||
mmcsdrate = pll_rate / pll_div8; /* 486/4 = 121.5MHz */
|
||||
|
||||
rt_kprintf(
|
||||
"PLL0: fixedrate: %d, commonrate: %d, vpssrate: %d\n",
|
||||
fixedrate, commonrate, vpssrate);
|
||||
rt_kprintf(
|
||||
"PLL0: vencrate_sd: %d, ddrrate: %d mmcsdrate: %d\n",
|
||||
vencrate_sd, (ddrrate/2), mmcsdrate);
|
||||
|
||||
/* Read PLL1 configuration */
|
||||
prediv = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PREDIV) &
|
||||
0x1f) + 1;
|
||||
postdiv = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + POSTDIV) &
|
||||
0x1f) + 1;
|
||||
pll_rate = ((fixedrate / prediv) * (2 * pll1_mult)) / postdiv;
|
||||
|
||||
/* PLL1 dividers */
|
||||
pll_div2 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV2) &
|
||||
0x1f) + 1; /* ARM */
|
||||
pll_div4 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV4) &
|
||||
0x1f) + 1; /* VOICE */
|
||||
pll_div5 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV5) &
|
||||
0x1f) + 1; /* VENC */
|
||||
|
||||
armrate = pll_rate / pll_div2; /* 594/2 = 297MHz */
|
||||
voicerate = pll_rate / pll_div4; /* 594/6 = 99MHz */
|
||||
vencrate_hd = pll_rate / pll_div5; /* 594/8 = 74.25MHz */
|
||||
|
||||
rt_kprintf(
|
||||
"PLL1: armrate: %d, voicerate: %d, vencrate_hd: %d\n",
|
||||
armrate, voicerate, vencrate_hd);
|
||||
|
||||
clk_list = davinci_dm365_clks;
|
||||
num_clks = ARRAY_SIZE(davinci_dm365_clks);
|
||||
|
||||
return davinci_register_clks(clk_list, num_clks);
|
||||
}
|
||||
|
||||
void platform_init(void)
|
||||
{
|
||||
edma_init(dm365_edma_info);
|
||||
}
|
||||
|
||||
|
||||
/* Reset board using the watchdog timer */
|
||||
void reset_system(void)
|
||||
{
|
||||
rt_uint32_t tgcr, wdtcr;
|
||||
rt_uint32_t base = DAVINCI_WDOG_BASE;
|
||||
|
||||
/* Disable, internal clock source */
|
||||
davinci_writel(0, base + TCR);
|
||||
|
||||
/* Reset timer, set mode to 64-bit watchdog, and unreset */
|
||||
davinci_writel(0, base + TGCR);
|
||||
tgcr = (TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT) |
|
||||
(TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
|
||||
(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
|
||||
davinci_writel(tgcr, base + TGCR);
|
||||
|
||||
/* Clear counter and period regs */
|
||||
davinci_writel(0, base + TIM12);
|
||||
davinci_writel(0, base + TIM34);
|
||||
davinci_writel(0, base + PRD12);
|
||||
davinci_writel(0, base + PRD34);
|
||||
|
||||
/* Enable periodic mode */
|
||||
davinci_writel(TCR_ENAMODE_PERIODIC << ENAMODE12_SHIFT, base + TCR);
|
||||
|
||||
/* Put watchdog in pre-active state */
|
||||
wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
|
||||
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
|
||||
davinci_writel(wdtcr, base + WDTCR);
|
||||
|
||||
/* Put watchdog in active state */
|
||||
wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
|
||||
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
|
||||
davinci_writel(wdtcr, base + WDTCR);
|
||||
|
||||
/*
|
||||
* Write an invalid value to the WDKEY field to trigger
|
||||
* a watchdog reset.
|
||||
*/
|
||||
wdtcr = 0xDEADBEEF;
|
||||
davinci_writel(wdtcr, base + WDTCR);
|
||||
}
|
||||
|
||||
|
||||
61
bsp/dm365/platform/dm365_timer.h
Normal file
61
bsp/dm365/platform/dm365_timer.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* DaVinci timer definitions
|
||||
*
|
||||
* Author: Kevin Hilman, MontaVista Software, Inc.
|
||||
* (C) 2007-2008 MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_TIME_H
|
||||
#define __ASM_ARCH_TIME_H
|
||||
|
||||
/* Timer register offsets */
|
||||
#define PID12 0x0
|
||||
#define TIM12 0x10
|
||||
#define TIM34 0x14
|
||||
#define PRD12 0x18
|
||||
#define PRD34 0x1c
|
||||
#define TCR 0x20
|
||||
#define TGCR 0x24
|
||||
#define WDTCR 0x28
|
||||
#define CMP12(n) (0x60 + ((n) << 2))
|
||||
|
||||
/* Timer register bitfields */
|
||||
#define ENAMODE12_SHIFT 6
|
||||
#define ENAMODE34_SHIFT 22
|
||||
#define TCR_ENAMODE_DISABLE 0x0
|
||||
#define TCR_ENAMODE_ONESHOT 0x1
|
||||
#define TCR_ENAMODE_PERIODIC 0x2
|
||||
#define TCR_ENAMODE_MASK 0x3
|
||||
|
||||
#define TGCR_TIMMODE_SHIFT 2
|
||||
#define TGCR_TIMMODE_64BIT_GP 0x0
|
||||
#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
|
||||
#define TGCR_TIMMODE_64BIT_WDOG 0x2
|
||||
#define TGCR_TIMMODE_32BIT_CHAINED 0x3
|
||||
|
||||
#define TGCR_TIM12RS_SHIFT 0
|
||||
#define TGCR_TIM34RS_SHIFT 1
|
||||
#define TGCR_RESET 0x0
|
||||
#define TGCR_UNRESET 0x1
|
||||
#define TGCR_RESET_MASK 0x3
|
||||
|
||||
#define WDTCR_WDEN_SHIFT 14
|
||||
#define WDTCR_WDEN_DISABLE 0x0
|
||||
#define WDTCR_WDEN_ENABLE 0x1
|
||||
#define WDTCR_WDKEY_SHIFT 16
|
||||
#define WDTCR_WDKEY_SEQ0 0xA5C6
|
||||
#define WDTCR_WDKEY_SEQ1 0xDA7E
|
||||
|
||||
enum {
|
||||
T0_BOT,
|
||||
T0_TOP,
|
||||
T1_BOT,
|
||||
T1_TOP,
|
||||
NUM_TIMERS
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARCH_TIME_H__ */
|
||||
|
||||
228
bsp/dm365/platform/dm36x.h
Normal file
228
bsp/dm365/platform/dm36x.h
Normal file
@@ -0,0 +1,228 @@
|
||||
#ifndef __DM36X_H__
|
||||
#define __DM36X_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "psc.h"
|
||||
#include "irqs.h"
|
||||
#include "dm365_timer.h"
|
||||
|
||||
/**
|
||||
* @addtogroup DM36X
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/*
|
||||
* Base register addresses
|
||||
*/
|
||||
#define DAVINCI_DMA_3PCC_BASE (0x01C00000)
|
||||
#define DAVINCI_DMA_3PTC0_BASE (0x01C10000)
|
||||
#define DAVINCI_DMA_3PTC1_BASE (0x01C10400)
|
||||
#define DAVINCI_I2C_BASE (0x01C21000)
|
||||
#define DAVINCI_TIMER0_BASE (0x01C21400)
|
||||
#define DAVINCI_TIMER1_BASE (0x01C21800)
|
||||
#define DAVINCI_WDOG_BASE (0x01C21C00)
|
||||
#define DAVINCI_PWM0_BASE (0x01C22000)
|
||||
#define DAVINCI_PWM1_BASE (0x01C22400)
|
||||
#define DAVINCI_PWM2_BASE (0x01C22800)
|
||||
#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000)
|
||||
#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800)
|
||||
#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00)
|
||||
#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000)
|
||||
#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000)
|
||||
#define DAVINCI_IEEE1394_BASE (0x01C60000)
|
||||
#define DAVINCI_USB_OTG_BASE (0x01C64000)
|
||||
#define DAVINCI_CFC_ATA_BASE (0x01C66000)
|
||||
#define DAVINCI_SPI_BASE (0x01C66800)
|
||||
#define DAVINCI_GPIO_BASE (0x01C67000)
|
||||
#define DAVINCI_UHPI_BASE (0x01C67800)
|
||||
#define DAVINCI_VPSS_REGS_BASE (0x01C70000)
|
||||
#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000)
|
||||
#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000)
|
||||
#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000)
|
||||
#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000)
|
||||
#define DAVINCI_IMCOP_BASE (0x01CC0000)
|
||||
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
|
||||
#define DAVINCI_VLYNQ_BASE (0x01E01000)
|
||||
#define DAVINCI_MCBSP_BASE (0x01E02000)
|
||||
#define DAVINCI_MMC_SD_BASE (0x01E10000)
|
||||
#define DAVINCI_MS_BASE (0x01E20000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000)
|
||||
#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000)
|
||||
|
||||
|
||||
/*
|
||||
* We can have multiple VLYNQ IPs in our system.
|
||||
* Define 'LOW_VLYNQ_CONTROL_BASE' with the VLYNQ
|
||||
* IP having lowest base address.
|
||||
* Define 'HIGH_VLYNQ_CONTROL_BASE' with the VLYNQ
|
||||
* IP having highest base address.
|
||||
* In case of only one VLYNQ IP, define only the
|
||||
* 'LOW_VLYNQ_CONTROL_BASE'.
|
||||
*/
|
||||
#define LOW_VLYNQ_CONTROL_BASE DAVINCI_VLYNQ_BASE
|
||||
|
||||
#define DM365_EMAC_BASE (0x01D07000)
|
||||
#define DM365_EMAC_CNTRL_OFFSET (0x0000)
|
||||
#define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000)
|
||||
#define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000)
|
||||
#define DM365_EMAC_MDIO_OFFSET (0x4000)
|
||||
#define DM365_EMAC_CNTRL_RAM_SIZE (0x2000)
|
||||
|
||||
|
||||
/*
|
||||
* Macro to access device power control
|
||||
*/
|
||||
#define DAVINCI_VDD3P3V_PWDN (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
|
||||
#define DAVINCI_VSCLKDIS (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
|
||||
|
||||
/*
|
||||
* System module registers
|
||||
*/
|
||||
#define PINMUX0 (DAVINCI_SYSTEM_MODULE_BASE + 0x00)
|
||||
#define PINMUX1 (DAVINCI_SYSTEM_MODULE_BASE + 0x04)
|
||||
#define PINMUX2 (DAVINCI_SYSTEM_MODULE_BASE + 0x08)
|
||||
#define PINMUX3 (DAVINCI_SYSTEM_MODULE_BASE + 0x0c)
|
||||
#define PINMUX4 (DAVINCI_SYSTEM_MODULE_BASE + 0x10)
|
||||
|
||||
#define DM365_ARM_INTMUX (DAVINCI_SYSTEM_MODULE_BASE + 0x18)
|
||||
#define DM365_EDMA_EVTMUX (DAVINCI_SYSTEM_MODULE_BASE + 0x1C)
|
||||
#define DAVINCI_PUPDCTL1 (DAVINCI_SYSTEM_MODULE_BASE + 0x7C)
|
||||
|
||||
|
||||
|
||||
#define ASYNC_EMIF_REVID 0x00
|
||||
#define ASYNC_EMIF_AWCCR 0x04
|
||||
#define ASYNC_EMIF_A1CR 0x10
|
||||
#define ASYNC_EMIF_A2CR 0x14
|
||||
#define ASYNC_EMIF_A3CR 0x18
|
||||
|
||||
/*
|
||||
* Base register addresses common across DM355 and DM365
|
||||
*/
|
||||
#define DM3XX_TIMER2_BASE (0x01C20800)
|
||||
#define DM3XX_REALTIME_BASE (0x01C20C00)
|
||||
#define DM3XX_PWM3_BASE (0x01C22C00)
|
||||
#define DM3XX_SPI_BASE (0x01C66000)
|
||||
#define DM3XX_SPI0_BASE DM3XX_SPI_BASE
|
||||
#define DM3XX_SPI1_BASE (0x01C66800)
|
||||
#define DM3XX_SPI2_BASE (0x01C67800)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* DM365 base register address
|
||||
*/
|
||||
#define DM365_DMA_3PTC2_BASE (0x01C10800)
|
||||
#define DM365_DMA_3PTC3_BASE (0x01C10C00)
|
||||
#define DM365_TIMER3_BASE (0x01C23800)
|
||||
#define DM365_ADCIF_BASE (0x01C23C00)
|
||||
#define DM365_SPI3_BASE (0x01C68000)
|
||||
#define DM365_SPI4_BASE (0x01C23000)
|
||||
#define DM365_RTC_BASE (0x01C69000)
|
||||
#define DM365_KEYSCAN_BASE (0x01C69400)
|
||||
#define DM365_UHPI_BASE (0x01C69800)
|
||||
#define DM365_IMCOP_BASE (0x01CA0000)
|
||||
#define DM365_MMC_SD1_BASE (0x01D00000)
|
||||
#define DM365_MCBSP_BASE (0x01D02000)
|
||||
#define DM365_UART1_BASE (0x01D06000)
|
||||
#define DM365_EMAC_CNTRL_BASE (0x01D07000)
|
||||
#define DM365_EMAC_WRAP_RAM_BASE (0x01D08000)
|
||||
#define DM365_EMAC_WRAP_CNTRL_BASE (0x01D0A000)
|
||||
#define DM365_EMAC_MDIO_BASE (0x01D0B000)
|
||||
#define DM365_VOICE_CODEC_BASE (0x01D0C000)
|
||||
#define DM365_ASYNC_EMIF_CNTRL_BASE (0x01D10000)
|
||||
#define DM365_MMC_SD0_BASE (0x01D11000)
|
||||
#define DM365_MS_BASE (0x01D20000)
|
||||
#define DM365_KALEIDO_BASE (0x01E00000)
|
||||
|
||||
#define DAVINCI_UART0_BASE (0x01C20000)
|
||||
|
||||
#define PSC_MDCTL_BASE (0x01c41a00)
|
||||
#define PSC_MDSTAT_BASE (0x01c41800)
|
||||
#define PSC_PTCMD (0x01c41120)
|
||||
#define PSC_PTSTAT (0x01c41128)
|
||||
|
||||
#define DM365_EINT_ENABLE0 0x01c48018
|
||||
#define DM365_EINT_ENABLE1 0x01c4801c
|
||||
|
||||
#define davinci_readb(a) (*(volatile unsigned char *)(a))
|
||||
#define davinci_readw(a) (*(volatile unsigned short *)(a))
|
||||
#define davinci_readl(a) (*(volatile unsigned int *)(a))
|
||||
|
||||
#define davinci_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
|
||||
#define davinci_writew(v,a) (*(volatile unsigned short *)(a) = (v))
|
||||
#define davinci_writel(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#define readb(a) davinci_readb(a)
|
||||
#define readw(a) davinci_readw(a)
|
||||
#define readl(a) davinci_readl(a)
|
||||
|
||||
#define write(v,a) davinci_writeb(v,a)
|
||||
#define writew(v,a) davinci_writew(v,a)
|
||||
#define writel(v,a) davinci_writel(v,a)
|
||||
|
||||
/* define timer register struct*/
|
||||
typedef struct timer_regs_s {
|
||||
rt_uint32_t pid12; /* 0x0 */
|
||||
rt_uint32_t emumgt_clksped; /* 0x4 */
|
||||
rt_uint32_t gpint_en; /* 0x8 */
|
||||
rt_uint32_t gpdir_dat; /* 0xC */
|
||||
rt_uint32_t tim12; /* 0x10 */
|
||||
rt_uint32_t tim34; /* 0x14 */
|
||||
rt_uint32_t prd12; /* 0x18 */
|
||||
rt_uint32_t prd34; /* 0x1C */
|
||||
rt_uint32_t tcr; /* 0x20 */
|
||||
rt_uint32_t tgcr; /* 0x24 */
|
||||
rt_uint32_t wdtcr; /* 0x28 */
|
||||
rt_uint32_t tlgc; /* 0x2C */
|
||||
rt_uint32_t tlmr; /* 0x30 */
|
||||
} timer_regs_t;
|
||||
|
||||
/*****************************/
|
||||
/* CPU Mode */
|
||||
/*****************************/
|
||||
#define USERMODE 0x10
|
||||
#define FIQMODE 0x11
|
||||
#define IRQMODE 0x12
|
||||
#define SVCMODE 0x13
|
||||
#define ABORTMODE 0x17
|
||||
#define UNDEFMODE 0x1b
|
||||
#define MODEMASK 0x1f
|
||||
#define NOINT 0xc0
|
||||
|
||||
struct rt_hw_register
|
||||
{
|
||||
rt_uint32_t cpsr;
|
||||
rt_uint32_t r0;
|
||||
rt_uint32_t r1;
|
||||
rt_uint32_t r2;
|
||||
rt_uint32_t r3;
|
||||
rt_uint32_t r4;
|
||||
rt_uint32_t r5;
|
||||
rt_uint32_t r6;
|
||||
rt_uint32_t r7;
|
||||
rt_uint32_t r8;
|
||||
rt_uint32_t r9;
|
||||
rt_uint32_t r10;
|
||||
rt_uint32_t fp;
|
||||
rt_uint32_t ip;
|
||||
rt_uint32_t sp;
|
||||
rt_uint32_t lr;
|
||||
rt_uint32_t pc;
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1587
bsp/dm365/platform/dma.c
Normal file
1587
bsp/dm365/platform/dma.c
Normal file
File diff suppressed because it is too large
Load Diff
308
bsp/dm365/platform/edma.h
Normal file
308
bsp/dm365/platform/edma.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* TI DAVINCI dma definitions
|
||||
*
|
||||
* Copyright (C) 2006-2009 Texas Instruments.
|
||||
*
|
||||
* 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 PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This EDMA3 programming framework exposes two basic kinds of resource:
|
||||
*
|
||||
* Channel Triggers transfers, usually from a hardware event but
|
||||
* also manually or by "chaining" from DMA completions.
|
||||
* Each channel is coupled to a Parameter RAM (PaRAM) slot.
|
||||
*
|
||||
* Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM
|
||||
* "set"), source and destination addresses, a link to a
|
||||
* next PaRAM slot (if any), options for the transfer, and
|
||||
* instructions for updating those addresses. There are
|
||||
* more than twice as many slots as event channels.
|
||||
*
|
||||
* Each PaRAM set describes a sequence of transfers, either for one large
|
||||
* buffer or for several discontiguous smaller buffers. An EDMA transfer
|
||||
* is driven only from a channel, which performs the transfers specified
|
||||
* in its PaRAM slot until there are no more transfers. When that last
|
||||
* transfer completes, the "link" field may be used to reload the channel's
|
||||
* PaRAM slot with a new transfer descriptor.
|
||||
*
|
||||
* The EDMA Channel Controller (CC) maps requests from channels into physical
|
||||
* Transfer Controller (TC) requests when the channel triggers (by hardware
|
||||
* or software events, or by chaining). The two physical DMA channels provided
|
||||
* by the TCs are thus shared by many logical channels.
|
||||
*
|
||||
* DaVinci hardware also has a "QDMA" mechanism which is not currently
|
||||
* supported through this interface. (DSP firmware uses it though.)
|
||||
*/
|
||||
|
||||
#ifndef EDMA_H_
|
||||
#define EDMA_H_
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <dm36x.h>
|
||||
|
||||
#ifdef RT_EDMA_DEBUG
|
||||
#define edma_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define edma_dbg(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* PaRAM slots are laid out like this */
|
||||
struct edmacc_param {
|
||||
unsigned int opt;
|
||||
unsigned int src;
|
||||
unsigned int a_b_cnt;
|
||||
unsigned int dst;
|
||||
unsigned int src_dst_bidx;
|
||||
unsigned int link_bcntrld;
|
||||
unsigned int src_dst_cidx;
|
||||
unsigned int ccnt;
|
||||
};
|
||||
|
||||
#define CCINT0_INTERRUPT 16
|
||||
#define CCERRINT_INTERRUPT 17
|
||||
#define TCERRINT0_INTERRUPT 18
|
||||
#define TCERRINT1_INTERRUPT 19
|
||||
|
||||
/* fields in edmacc_param.opt */
|
||||
#define SAM BIT(0)
|
||||
#define DAM BIT(1)
|
||||
#define SYNCDIM BIT(2)
|
||||
#define STATIC BIT(3)
|
||||
#define EDMA_FWID (0x07 << 8)
|
||||
#define TCCMODE BIT(11)
|
||||
#define EDMA_TCC(t) ((t) << 12)
|
||||
#define TCINTEN BIT(20)
|
||||
#define ITCINTEN BIT(21)
|
||||
#define TCCHEN BIT(22)
|
||||
#define ITCCHEN BIT(23)
|
||||
|
||||
#define TRWORD (0x7<<2)
|
||||
#define PAENTRY (0x1ff<<5)
|
||||
|
||||
/* DM365 specific EDMA3 Events Information */
|
||||
enum dm365_edma_ch {
|
||||
DM365_DMA_TIMER3_TINT6,
|
||||
DM365_DMA_TIMER3_TINT7,
|
||||
DM365_DMA_MCBSP_TX = 2,
|
||||
DM365_DMA_VCIF_TX = 2,
|
||||
DM365_DMA_MCBSP_RX = 3,
|
||||
DM365_DMA_VCIF_RX = 3,
|
||||
DM365_DMA_VPSS_EVT1,
|
||||
DM365_DMA_VPSS_EVT2,
|
||||
DM365_DMA_VPSS_EVT3,
|
||||
DM365_DMA_VPSS_EVT4,
|
||||
DM365_DMA_TIMER2_TINT4,
|
||||
DM365_DMA_TIMER2_TINT5,
|
||||
DM365_DMA_SPI2XEVT,
|
||||
DM365_DMA_SPI2REVT,
|
||||
DM365_DMA_IMCOP_IMX0INT = 12,
|
||||
DM365_DMA_KALEIDO_ARMINT = 12,
|
||||
DM365_DMA_IMCOP_SEQINT,
|
||||
DM365_DMA_SPI1XEVT,
|
||||
DM365_DMA_SPI1REVT,
|
||||
DM365_DMA_SPI0XEVT,
|
||||
DM365_DMA_SPI0REVT,
|
||||
DM365_DMA_URXEVT0 = 18,
|
||||
DM365_DMA_SPI3XEVT = 18,
|
||||
DM365_DMA_UTXEVT0 = 19,
|
||||
DM365_DMA_SPI3REVT = 19,
|
||||
DM365_DMA_URXEVT1,
|
||||
DM365_DMA_UTXEVT1,
|
||||
DM365_DMA_TIMER4_TINT8,
|
||||
DM365_DMA_TIMER4_TINT9,
|
||||
DM365_DMA_RTOINT,
|
||||
DM365_DMA_GPIONT9,
|
||||
DM365_DMA_MMC0RXEVT = 26,
|
||||
DM365_DMA_MEMSTK_MSEVT = 26,
|
||||
DM365_DMA_MMC0TXEVT,
|
||||
DM365_DMA_I2C_ICREVT,
|
||||
DM365_DMA_I2C_ICXEVT,
|
||||
DM365_DMA_MMC1RXEVT,
|
||||
DM365_DMA_MMC1TXEVT,
|
||||
DM365_DMA_GPIOINT0,
|
||||
DM365_DMA_GPIOINT1,
|
||||
DM365_DMA_GPIOINT2,
|
||||
DM365_DMA_GPIOINT3,
|
||||
DM365_DMA_GPIOINT4,
|
||||
DM365_DMA_GPIOINT5,
|
||||
DM365_DMA_GPIOINT6,
|
||||
DM365_DMA_GPIOINT7,
|
||||
DM365_DMA_GPIOINT10 = 40,
|
||||
DM365_DMA_EMAC_RXTHREESH = 40,
|
||||
DM365_DMA_GPIOINT11 = 41,
|
||||
DM365_DMA_EMAC_RXPULSE = 41,
|
||||
DM365_DMA_GPIOINT12 = 42,
|
||||
DM365_DMA_EMAC_TXPULSE = 42,
|
||||
DM365_DMA_GPIOINT13 = 43,
|
||||
DM365_DMA_EMAC_MISCPULSE = 43,
|
||||
DM365_DMA_GPIOINT14 = 44,
|
||||
DM365_DMA_SPI4XEVT = 44,
|
||||
DM365_DMA_GPIOINT15 = 45,
|
||||
DM365_DMA_SPI4REVT = 45,
|
||||
DM365_DMA_ADC_ADINT,
|
||||
DM365_DMA_GPIOINT8,
|
||||
DM365_DMA_TIMER0_TINT0,
|
||||
DM365_DMA_TIMER0_TINT1,
|
||||
DM365_DMA_TIMER1_TINT2,
|
||||
DM365_DMA_TIMER1_TINT3,
|
||||
DM365_DMA_PWM0,
|
||||
DM365_DMA_PWM1 = 53,
|
||||
DM365_DMA_IMCOP_IMX1INT = 53,
|
||||
DM365_DMA_PWM2 = 54,
|
||||
DM365_DMA_IMCOP_NSFINT = 54,
|
||||
DM365_DMA_PWM3 = 55,
|
||||
DM365_DMA_KALEIDO6_CP_UNDEF = 55,
|
||||
DM365_DMA_IMCOP_VLCDINT = 56,
|
||||
DM365_DMA_KALEIDO5_CP_ECDCMP = 56,
|
||||
DM365_DMA_IMCOP_BIMINT = 57,
|
||||
DM365_DMA_KALEIDO8_CP_ME = 57,
|
||||
DM365_DMA_IMCOP_DCTINT = 58,
|
||||
DM365_DMA_KALEIDO1_CP_CALC = 58,
|
||||
DM365_DMA_IMCOP_QIQINT = 59,
|
||||
DM365_DMA_KALEIDO7_CP_IPE = 59,
|
||||
DM365_DMA_IMCOP_BPSINT = 60,
|
||||
DM365_DMA_KALEIDO2_CP_BS = 60,
|
||||
DM365_DMA_IMCOP_VLCDERRINT = 61,
|
||||
DM365_DMA_KALEIDO0_CP_LPF = 61,
|
||||
DM365_DMA_IMCOP_RCNTINT = 62,
|
||||
DM365_DMA_KALEIDO3_CP_MC = 62,
|
||||
DM365_DMA_IMCOP_COPCINT = 63,
|
||||
DM365_DMA_KALEIDO4_CP_ECDEND = 63,
|
||||
};
|
||||
/* end DM365 specific info */
|
||||
|
||||
|
||||
/*ch_status paramater of callback function possible values*/
|
||||
#define DMA_COMPLETE 1
|
||||
#define DMA_CC_ERROR 2
|
||||
#define DMA_TC1_ERROR 3
|
||||
#define DMA_TC2_ERROR 4
|
||||
|
||||
enum address_mode {
|
||||
INCR = 0,
|
||||
FIFO = 1
|
||||
};
|
||||
|
||||
enum fifo_width {
|
||||
W8BIT = 0,
|
||||
W16BIT = 1,
|
||||
W32BIT = 2,
|
||||
W64BIT = 3,
|
||||
W128BIT = 4,
|
||||
W256BIT = 5
|
||||
};
|
||||
|
||||
enum dma_event_q {
|
||||
EVENTQ_0 = 0,
|
||||
EVENTQ_1 = 1,
|
||||
EVENTQ_2 = 2,
|
||||
EVENTQ_3 = 3,
|
||||
EVENTQ_DEFAULT = -1
|
||||
};
|
||||
|
||||
enum sync_dimension {
|
||||
ASYNC = 0,
|
||||
ABSYNC = 1
|
||||
};
|
||||
|
||||
#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan))
|
||||
#define EDMA_CTLR(i) ((i) >> 16)
|
||||
#define EDMA_CHAN_SLOT(i) ((i) & 0xffff)
|
||||
|
||||
#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
|
||||
#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
|
||||
#define EDMA_CONT_PARAMS_ANY 1001
|
||||
#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
|
||||
#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
|
||||
|
||||
#define EDMA_MAX_CC 2
|
||||
|
||||
/* alloc/free DMA channels and their dedicated parameter RAM slots */
|
||||
int edma_alloc_channel(int channel,
|
||||
void (*callback)(unsigned channel, rt_uint16_t ch_status, void *data),
|
||||
void *data, enum dma_event_q);
|
||||
void edma_free_channel(unsigned channel);
|
||||
|
||||
/* alloc/free parameter RAM slots */
|
||||
int edma_alloc_slot(unsigned ctlr, int slot);
|
||||
void edma_free_slot(unsigned slot);
|
||||
|
||||
/* alloc/free a set of contiguous parameter RAM slots */
|
||||
int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
|
||||
int edma_free_cont_slots(unsigned slot, int count);
|
||||
|
||||
/* calls that operate on part of a parameter RAM slot */
|
||||
void edma_set_src(unsigned slot, rt_uint32_t src_port,
|
||||
enum address_mode mode, enum fifo_width);
|
||||
void edma_set_dest(unsigned slot, rt_uint32_t dest_port,
|
||||
enum address_mode mode, enum fifo_width);
|
||||
void edma_get_position(unsigned slot, rt_uint32_t *src, rt_uint32_t *dst);
|
||||
void edma_set_src_index(unsigned slot, rt_int16_t src_bidx, rt_int16_t src_cidx);
|
||||
void edma_set_dest_index(unsigned slot, rt_int16_t dest_bidx, rt_int16_t dest_cidx);
|
||||
void edma_set_transfer_params(unsigned slot, rt_uint16_t acnt, rt_uint16_t bcnt, rt_uint16_t ccnt,
|
||||
rt_uint16_t bcnt_rld, enum sync_dimension sync_mode);
|
||||
void edma_link(unsigned from, unsigned to);
|
||||
void edma_unlink(unsigned from);
|
||||
|
||||
/* calls that operate on an entire parameter RAM slot */
|
||||
void edma_write_slot(unsigned slot, const struct edmacc_param *params);
|
||||
void edma_read_slot(unsigned slot, struct edmacc_param *params);
|
||||
|
||||
/* channel control operations */
|
||||
int edma_start(unsigned channel);
|
||||
void edma_stop(unsigned channel);
|
||||
void edma_clean_channel(unsigned channel);
|
||||
void edma_clear_event(unsigned channel);
|
||||
void edma_pause(unsigned channel);
|
||||
void edma_resume(unsigned channel);
|
||||
|
||||
|
||||
struct edma_rsv_info {
|
||||
|
||||
const rt_int16_t (*rsv_chans)[2];
|
||||
const rt_int16_t (*rsv_slots)[2];
|
||||
};
|
||||
|
||||
/* platform_data for EDMA driver */
|
||||
struct edma_soc_info {
|
||||
|
||||
/* how many dma resources of each type */
|
||||
unsigned n_channel;
|
||||
unsigned n_region;
|
||||
unsigned n_slot;
|
||||
unsigned n_tc;
|
||||
unsigned n_cc;
|
||||
enum dma_event_q default_queue;
|
||||
|
||||
/* Resource reservation for other cores */
|
||||
struct edma_rsv_info *rsv;
|
||||
|
||||
const rt_int8_t (*queue_tc_mapping)[2];
|
||||
const rt_int8_t (*queue_priority_mapping)[2];
|
||||
};
|
||||
|
||||
int edma_init(struct edma_soc_info **info);
|
||||
|
||||
|
||||
#endif
|
||||
199
bsp/dm365/platform/findbit.S
Normal file
199
bsp/dm365/platform/findbit.S
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* linux/arch/arm/lib/findbit.S
|
||||
*
|
||||
* Copyright (C) 1995-2000 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 16th March 2001 - John Ripley <jripley@sonicblue.com>
|
||||
* Fixed so that "size" is an exclusive not an inclusive quantity.
|
||||
* All users of these functions expect exclusive sizes, and may
|
||||
* also call with zero size.
|
||||
* Reworked by rmk.
|
||||
*/
|
||||
//#include <rtthread.h>
|
||||
//.text
|
||||
|
||||
/*
|
||||
* Purpose : Find a 'zero' bit
|
||||
* Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
|
||||
*/
|
||||
.globl _find_first_zero_bit_le
|
||||
_find_first_zero_bit_le:
|
||||
teq r1, #0
|
||||
beq 3f
|
||||
mov r2, #0
|
||||
1:
|
||||
ldrb r3, [r0, r2, lsr #3]
|
||||
lsr r3, r2, #3
|
||||
ldrb r3, [r0, r3]
|
||||
eors r3, r3, #0xff @ invert bits
|
||||
bne .L_found @ any now set - found zero bit
|
||||
add r2, r2, #8 @ next bit pointer
|
||||
2: cmp r2, r1 @ any more?
|
||||
blo 1b
|
||||
3: mov r0, r1 @ no free bits
|
||||
mov pc, lr
|
||||
//ENDPROC(_find_first_zero_bit_le)
|
||||
|
||||
/*
|
||||
* Purpose : Find next 'zero' bit
|
||||
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
||||
*/
|
||||
.globl _find_next_zero_bit_le
|
||||
_find_next_zero_bit_le:
|
||||
teq r1, #0
|
||||
beq 3b
|
||||
ands ip, r2, #7
|
||||
beq 1b @ If new byte, goto old routine
|
||||
ldrb r3, [r0, r2, lsr #3]
|
||||
lsr r3, r2, #3
|
||||
ldrb r3, [r0, r3]
|
||||
eor r3, r3, #0xff @ now looking for a 1 bit
|
||||
movs r3, r3, lsr ip @ shift off unused bits
|
||||
bne .L_found
|
||||
orr r2, r2, #7 @ if zero, then no bits here
|
||||
add r2, r2, #1 @ align bit pointer
|
||||
b 2b @ loop for next bit
|
||||
//ENDPROC(_find_next_zero_bit_le)
|
||||
|
||||
/*
|
||||
* Purpose : Find a 'one' bit
|
||||
* Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
|
||||
*/
|
||||
.globl _find_first_bit_le
|
||||
_find_first_bit_le:
|
||||
teq r1, #0
|
||||
beq 3f
|
||||
mov r2, #0
|
||||
1:
|
||||
ldrb r3, [r0, r2, lsr #3]
|
||||
lsr r3, r2, #3
|
||||
ldrb r3, [r0, r3]
|
||||
movs r3, r3
|
||||
bne .L_found @ any now set - found zero bit
|
||||
add r2, r2, #8 @ next bit pointer
|
||||
2: cmp r2, r1 @ any more?
|
||||
blo 1b
|
||||
3: mov r0, r1 @ no free bits
|
||||
mov pc, lr
|
||||
//ENDPROC(_find_first_bit_le)
|
||||
|
||||
/*
|
||||
* Purpose : Find next 'one' bit
|
||||
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
||||
*/
|
||||
.globl _find_next_bit_le
|
||||
_find_next_bit_le:
|
||||
teq r1, #0
|
||||
beq 3b
|
||||
ands ip, r2, #7
|
||||
beq 1b @ If new byte, goto old routine
|
||||
ldrb r3, [r0, r2, lsr #3]
|
||||
lsr r3, r2, #3
|
||||
ldrb r3, [r0, r3]
|
||||
movs r3, r3, lsr ip @ shift off unused bits
|
||||
bne .L_found
|
||||
orr r2, r2, #7 @ if zero, then no bits here
|
||||
add r2, r2, #1 @ align bit pointer
|
||||
b 2b @ loop for next bit
|
||||
//ENDPROC(_find_next_bit_le)
|
||||
|
||||
#ifdef __ARMEB__
|
||||
|
||||
ENTRY(_find_first_zero_bit_be)
|
||||
teq r1, #0
|
||||
beq 3f
|
||||
mov r2, #0
|
||||
1: eor r3, r2, #0x18 @ big endian byte ordering
|
||||
ARM( ldrb r3, [r0, r3, lsr #3] )
|
||||
THUMB( lsr r3, #3 )
|
||||
THUMB( ldrb r3, [r0, r3] )
|
||||
eors r3, r3, #0xff @ invert bits
|
||||
bne .L_found @ any now set - found zero bit
|
||||
add r2, r2, #8 @ next bit pointer
|
||||
2: cmp r2, r1 @ any more?
|
||||
blo 1b
|
||||
3: mov r0, r1 @ no free bits
|
||||
mov pc, lr
|
||||
ENDPROC(_find_first_zero_bit_be)
|
||||
|
||||
ENTRY(_find_next_zero_bit_be)
|
||||
teq r1, #0
|
||||
beq 3b
|
||||
ands ip, r2, #7
|
||||
beq 1b @ If new byte, goto old routine
|
||||
eor r3, r2, #0x18 @ big endian byte ordering
|
||||
ARM( ldrb r3, [r0, r3, lsr #3] )
|
||||
THUMB( lsr r3, #3 )
|
||||
THUMB( ldrb r3, [r0, r3] )
|
||||
eor r3, r3, #0xff @ now looking for a 1 bit
|
||||
movs r3, r3, lsr ip @ shift off unused bits
|
||||
bne .L_found
|
||||
orr r2, r2, #7 @ if zero, then no bits here
|
||||
add r2, r2, #1 @ align bit pointer
|
||||
b 2b @ loop for next bit
|
||||
ENDPROC(_find_next_zero_bit_be)
|
||||
|
||||
ENTRY(_find_first_bit_be)
|
||||
teq r1, #0
|
||||
beq 3f
|
||||
mov r2, #0
|
||||
1: eor r3, r2, #0x18 @ big endian byte ordering
|
||||
ARM( ldrb r3, [r0, r3, lsr #3] )
|
||||
THUMB( lsr r3, #3 )
|
||||
THUMB( ldrb r3, [r0, r3] )
|
||||
movs r3, r3
|
||||
bne .L_found @ any now set - found zero bit
|
||||
add r2, r2, #8 @ next bit pointer
|
||||
2: cmp r2, r1 @ any more?
|
||||
blo 1b
|
||||
3: mov r0, r1 @ no free bits
|
||||
mov pc, lr
|
||||
ENDPROC(_find_first_bit_be)
|
||||
|
||||
ENTRY(_find_next_bit_be)
|
||||
teq r1, #0
|
||||
beq 3b
|
||||
ands ip, r2, #7
|
||||
beq 1b @ If new byte, goto old routine
|
||||
eor r3, r2, #0x18 @ big endian byte ordering
|
||||
ARM( ldrb r3, [r0, r3, lsr #3] )
|
||||
THUMB( lsr r3, #3 )
|
||||
THUMB( ldrb r3, [r0, r3] )
|
||||
movs r3, r3, lsr ip @ shift off unused bits
|
||||
bne .L_found
|
||||
orr r2, r2, #7 @ if zero, then no bits here
|
||||
add r2, r2, #1 @ align bit pointer
|
||||
b 2b @ loop for next bit
|
||||
ENDPROC(_find_next_bit_be)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* One or more bits in the LSB of r3 are assumed to be set.
|
||||
*/
|
||||
.L_found:
|
||||
#if 1 //__LINUX_ARM_ARCH__ >= 5
|
||||
rsb r0, r3, #0
|
||||
and r3, r3, r0
|
||||
clz r3, r3
|
||||
rsb r3, r3, #31
|
||||
add r0, r2, r3
|
||||
#else
|
||||
tst r3, #0x0f
|
||||
addeq r2, r2, #4
|
||||
movne r3, r3, lsl #4
|
||||
tst r3, #0x30
|
||||
addeq r2, r2, #2
|
||||
movne r3, r3, lsl #2
|
||||
tst r3, #0x40
|
||||
addeq r2, r2, #1
|
||||
mov r0, r2
|
||||
#endif
|
||||
cmp r1, r0 @ Clamp to maxbit
|
||||
movlo r0, r1
|
||||
mov pc, lr
|
||||
|
||||
298
bsp/dm365/platform/interrupt.c
Normal file
298
bsp/dm365/platform/interrupt.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2010-11-13 weety first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include "dm36x.h"
|
||||
|
||||
#define MAX_HANDLERS 64
|
||||
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
|
||||
struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
||||
|
||||
/* exception and interrupt handler table */
|
||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||
|
||||
#define IRQ_BIT(irq) ((irq) & 0x1f)
|
||||
|
||||
#define FIQ_REG0_OFFSET 0x0000
|
||||
#define FIQ_REG1_OFFSET 0x0004
|
||||
#define IRQ_REG0_OFFSET 0x0008
|
||||
#define IRQ_REG1_OFFSET 0x000C
|
||||
#define IRQ_ENT_REG0_OFFSET 0x0018
|
||||
#define IRQ_ENT_REG1_OFFSET 0x001C
|
||||
#define IRQ_INCTL_REG_OFFSET 0x0020
|
||||
#define IRQ_EABASE_REG_OFFSET 0x0024
|
||||
#define IRQ_INTPRI0_REG_OFFSET 0x0030
|
||||
#define IRQ_INTPRI7_REG_OFFSET 0x004C
|
||||
|
||||
/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
|
||||
static const rt_uint8_t dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
|
||||
[IRQ_DM3XX_VPSSINT0] = 2,
|
||||
[IRQ_DM3XX_VPSSINT1] = 6,
|
||||
[IRQ_DM3XX_VPSSINT2] = 6,
|
||||
[IRQ_DM3XX_VPSSINT3] = 6,
|
||||
[IRQ_DM3XX_VPSSINT4] = 6,
|
||||
[IRQ_DM3XX_VPSSINT5] = 6,
|
||||
[IRQ_DM3XX_VPSSINT6] = 6,
|
||||
[IRQ_DM3XX_VPSSINT7] = 7,
|
||||
[IRQ_DM3XX_VPSSINT8] = 6,
|
||||
[IRQ_ASQINT] = 6,
|
||||
[IRQ_DM365_IMXINT0] = 6,
|
||||
[IRQ_DM3XX_IMCOPINT] = 6,
|
||||
[IRQ_USBINT] = 4,
|
||||
[IRQ_DM3XX_RTOINT] = 4,
|
||||
[IRQ_DM3XX_TINT5] = 7,
|
||||
[IRQ_DM3XX_TINT6] = 7,
|
||||
[IRQ_CCINT0] = 5, /* dma */
|
||||
[IRQ_DM3XX_SPINT1_0] = 5, /* dma */
|
||||
[IRQ_DM3XX_SPINT1_1] = 5, /* dma */
|
||||
[IRQ_DM3XX_SPINT2_0] = 5, /* dma */
|
||||
[IRQ_DM365_PSCINT] = 7,
|
||||
[IRQ_DM3XX_SPINT2_1] = 7,
|
||||
[IRQ_DM3XX_TINT7] = 4,
|
||||
[IRQ_DM3XX_SDIOINT0] = 7,
|
||||
[IRQ_DM365_MBXINT] = 7,
|
||||
[IRQ_DM365_MBRINT] = 7,
|
||||
[IRQ_DM3XX_MMCINT0] = 7,
|
||||
[IRQ_DM3XX_MMCINT1] = 7,
|
||||
[IRQ_DM3XX_PWMINT3] = 7,
|
||||
[IRQ_DM365_DDRINT] = 7,
|
||||
[IRQ_DM365_AEMIFINT] = 7,
|
||||
[IRQ_DM3XX_SDIOINT1] = 4,
|
||||
[IRQ_DM365_TINT0] = 2, /* clockevent */
|
||||
[IRQ_DM365_TINT1] = 2, /* clocksource */
|
||||
[IRQ_DM365_TINT2] = 7, /* DSP timer */
|
||||
[IRQ_DM365_TINT3] = 7, /* system tick */
|
||||
[IRQ_PWMINT0] = 7,
|
||||
[IRQ_PWMINT1] = 7,
|
||||
[IRQ_DM365_PWMINT2] = 7,
|
||||
[IRQ_DM365_IICINT] = 3,
|
||||
[IRQ_UARTINT0] = 3,
|
||||
[IRQ_UARTINT1] = 3,
|
||||
[IRQ_DM3XX_SPINT0_0] = 3,
|
||||
[IRQ_DM3XX_SPINT0_1] = 3,
|
||||
[IRQ_DM3XX_GPIO0] = 3,
|
||||
[IRQ_DM3XX_GPIO1] = 7,
|
||||
[IRQ_DM3XX_GPIO2] = 4,
|
||||
[IRQ_DM3XX_GPIO3] = 4,
|
||||
[IRQ_DM3XX_GPIO4] = 7,
|
||||
[IRQ_DM3XX_GPIO5] = 7,
|
||||
[IRQ_DM3XX_GPIO6] = 7,
|
||||
[IRQ_DM3XX_GPIO7] = 7,
|
||||
[IRQ_DM3XX_GPIO8] = 7,
|
||||
[IRQ_DM3XX_GPIO9] = 7,
|
||||
[IRQ_DM365_GPIO10] = 7,
|
||||
[IRQ_DM365_GPIO11] = 7,
|
||||
[IRQ_DM365_GPIO12] = 7,
|
||||
[IRQ_DM365_GPIO13] = 7,
|
||||
[IRQ_DM365_GPIO14] = 7,
|
||||
[IRQ_DM365_GPIO15] = 7,
|
||||
[IRQ_DM365_KEYINT] = 7,
|
||||
[IRQ_DM365_COMMTX] = 7,
|
||||
[IRQ_DM365_COMMRX] = 7,
|
||||
[IRQ_EMUINT] = 7,
|
||||
};
|
||||
|
||||
static inline unsigned int davinci_irq_readl(int offset)
|
||||
{
|
||||
return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
|
||||
}
|
||||
|
||||
static inline void davinci_irq_writel(unsigned long value, int offset)
|
||||
{
|
||||
davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup DM36X
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
rt_isr_handler_t rt_hw_interrupt_handle(int vector, void *param)
|
||||
{
|
||||
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will initialize hardware interrupt
|
||||
*/
|
||||
void rt_hw_interrupt_init(void)
|
||||
{
|
||||
int i;
|
||||
register rt_uint32_t idx;
|
||||
const rt_uint8_t *priority;
|
||||
priority = dm365_default_priorities;
|
||||
|
||||
/* Clear all interrupt requests */
|
||||
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
|
||||
davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
|
||||
davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
|
||||
davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
|
||||
|
||||
/* Disable all interrupts */
|
||||
davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
|
||||
davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);
|
||||
|
||||
/* Interrupts disabled immediately, IRQ entry reflects all */
|
||||
davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);
|
||||
|
||||
/* we don't use the hardware vector table, just its entry addresses */
|
||||
davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);
|
||||
|
||||
/* Clear all interrupt requests */
|
||||
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
|
||||
davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
|
||||
davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
|
||||
davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
|
||||
|
||||
for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
|
||||
unsigned j;
|
||||
rt_uint32_t pri;
|
||||
|
||||
for (j = 0, pri = 0; j < 32; j += 4, priority++)
|
||||
pri |= (*priority & 0x07) << j;
|
||||
davinci_irq_writel(pri, i);
|
||||
}
|
||||
|
||||
/* init exceptions table */
|
||||
for(idx=0; idx < MAX_HANDLERS; idx++)
|
||||
{
|
||||
|
||||
irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
|
||||
irq_desc[idx].param = RT_NULL;
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
|
||||
irq_desc[idx].counter = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* init interrupt nest, and context in thread sp */
|
||||
rt_interrupt_nest = 0;
|
||||
rt_interrupt_from_thread = 0;
|
||||
rt_interrupt_to_thread = 0;
|
||||
rt_thread_switch_interrupt_flag = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_mask(int irq)
|
||||
{
|
||||
unsigned int mask;
|
||||
rt_uint32_t l;
|
||||
|
||||
mask = 1 << IRQ_BIT(irq);
|
||||
|
||||
if (irq > 31) {
|
||||
l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
|
||||
l &= ~mask;
|
||||
davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
|
||||
} else {
|
||||
l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
|
||||
l &= ~mask;
|
||||
davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_umask(int irq)
|
||||
{
|
||||
unsigned int mask;
|
||||
rt_uint32_t l;
|
||||
|
||||
mask = 1 << IRQ_BIT(irq);
|
||||
|
||||
if (irq > 31) {
|
||||
l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
|
||||
l |= mask;
|
||||
davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
|
||||
} else {
|
||||
l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
|
||||
l |= mask;
|
||||
davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will install a interrupt service routine to a interrupt.
|
||||
* @param vector the interrupt number
|
||||
* @param handler the interrupt service routine to be installed
|
||||
* @param param the interrupt service function parameter
|
||||
* @param name the interrupt name
|
||||
* @return old handler
|
||||
*/
|
||||
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
void *param, char *name)
|
||||
{
|
||||
rt_isr_handler_t old_handler = RT_NULL;
|
||||
|
||||
if(vector < MAX_HANDLERS)
|
||||
{
|
||||
old_handler = irq_desc[vector].handler;
|
||||
if (handler != RT_NULL)
|
||||
{
|
||||
irq_desc[vector].handler = (rt_isr_handler_t)handler;
|
||||
irq_desc[vector].param = param;
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
|
||||
irq_desc[vector].counter = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return old_handler;
|
||||
|
||||
}
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
void list_irq(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
rt_kprintf("number\tcount\tname\n");
|
||||
for (irq = 0; irq < MAX_HANDLERS; irq++)
|
||||
{
|
||||
if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default")))
|
||||
{
|
||||
rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <finsh.h>
|
||||
FINSH_FUNCTION_EXPORT(list_irq, list system irq);
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
int cmd_list_irq(int argc, char** argv)
|
||||
{
|
||||
list_irq();
|
||||
return 0;
|
||||
}
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(cmd_list_irq, __cmd_list_irq, list system irq.);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
181
bsp/dm365/platform/irqs.h
Normal file
181
bsp/dm365/platform/irqs.h
Normal file
@@ -0,0 +1,181 @@
|
||||
#ifndef __DM36X_IRQS_H__
|
||||
#define __DM36X_IRQS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Base address */
|
||||
#define DAVINCI_ARM_INTC_BASE 0x01C48000
|
||||
|
||||
#define DAVINCI_N_AINTC_IRQ 64
|
||||
|
||||
/* Interrupt lines */
|
||||
#define IRQ_VDINT0 0
|
||||
#define IRQ_VDINT1 1
|
||||
#define IRQ_VDINT2 2
|
||||
#define IRQ_HISTINT 3
|
||||
#define IRQ_H3AINT 4
|
||||
#define IRQ_PRVUINT 5
|
||||
#define IRQ_RSZINT 6
|
||||
#define IRQ_VFOCINT 7
|
||||
#define IRQ_VENCINT 8
|
||||
#define IRQ_ASQINT 9
|
||||
#define IRQ_IMXINT 10
|
||||
#define IRQ_VLCDINT 11
|
||||
#define IRQ_USBINT 12
|
||||
#define IRQ_EMACINT 13
|
||||
|
||||
#define IRQ_CCINT0 16
|
||||
#define IRQ_CCERRINT 17
|
||||
#define IRQ_TCERRINT0 18
|
||||
#define IRQ_TCERRINT 19
|
||||
#define IRQ_PSCIN 20
|
||||
|
||||
#define IRQ_IDE 22
|
||||
#define IRQ_HPIINT 23
|
||||
#define IRQ_MBXINT 24
|
||||
#define IRQ_MBRINT 25
|
||||
#define IRQ_MMCINT 26
|
||||
#define IRQ_SDIOINT 27
|
||||
#define IRQ_MSINT 28
|
||||
#define IRQ_DDRINT 29
|
||||
#define IRQ_AEMIFINT 30
|
||||
#define IRQ_VLQINT 31
|
||||
#define IRQ_TINT0_TINT12 32
|
||||
#define IRQ_TINT0_TINT34 33
|
||||
#define IRQ_TINT1_TINT12 34
|
||||
#define IRQ_TINT1_TINT34 35
|
||||
#define IRQ_PWMINT0 36
|
||||
#define IRQ_PWMINT1 37
|
||||
#define IRQ_PWMINT2 38
|
||||
#define IRQ_I2C 39
|
||||
#define IRQ_UARTINT0 40
|
||||
#define IRQ_UARTINT1 41
|
||||
#define IRQ_UARTINT2 42
|
||||
#define IRQ_SPINT0 43
|
||||
#define IRQ_SPINT1 44
|
||||
|
||||
#define IRQ_DSP2ARM0 46
|
||||
#define IRQ_DSP2ARM1 47
|
||||
#define IRQ_GPIO0 48
|
||||
#define IRQ_GPIO1 49
|
||||
#define IRQ_GPIO2 50
|
||||
#define IRQ_GPIO3 51
|
||||
#define IRQ_GPIO4 52
|
||||
#define IRQ_GPIO5 53
|
||||
#define IRQ_GPIO6 54
|
||||
#define IRQ_GPIO7 55
|
||||
#define IRQ_GPIOBNK0 56
|
||||
#define IRQ_GPIOBNK1 57
|
||||
#define IRQ_GPIOBNK2 58
|
||||
#define IRQ_GPIOBNK3 59
|
||||
#define IRQ_GPIOBNK4 60
|
||||
#define IRQ_COMMTX 61
|
||||
#define IRQ_COMMRX 62
|
||||
#define IRQ_EMUINT 63
|
||||
|
||||
/*
|
||||
* Base Interrupts common across DM355 and DM365
|
||||
*/
|
||||
#define IRQ_DM3XX_VPSSINT0 0
|
||||
#define IRQ_DM3XX_VPSSINT1 1
|
||||
#define IRQ_DM3XX_VPSSINT2 2
|
||||
#define IRQ_DM3XX_VPSSINT3 3
|
||||
#define IRQ_DM3XX_VPSSINT4 4
|
||||
#define IRQ_DM3XX_VPSSINT5 5
|
||||
#define IRQ_DM3XX_VPSSINT6 6
|
||||
#define IRQ_DM3XX_VPSSINT7 7
|
||||
#define IRQ_DM3XX_VPSSINT8 8
|
||||
#define IRQ_DM3XX_IMCOPINT 11
|
||||
#define IRQ_DM3XX_RTOINT 13
|
||||
#define IRQ_DM3XX_TINT4 13
|
||||
#define IRQ_DM3XX_TINT2_TINT12 13
|
||||
#define IRQ_DM3XX_TINT5 14
|
||||
#define IRQ_DM3XX_TINT2_TINT34 14
|
||||
#define IRQ_DM3XX_TINT6 15
|
||||
#define IRQ_DM3XX_TINT3_TINT12 15
|
||||
#define IRQ_DM3XX_SPINT1_0 17
|
||||
#define IRQ_DM3XX_SPINT1_1 18
|
||||
#define IRQ_DM3XX_SPINT2_0 19
|
||||
#define IRQ_DM3XX_SPINT2_1 21
|
||||
#define IRQ_DM3XX_TINT7 22
|
||||
#define IRQ_DM3XX_TINT3_TINT34 22
|
||||
#define IRQ_DM3XX_SDIOINT0 23
|
||||
#define IRQ_DM3XX_MMCINT0 26
|
||||
#define IRQ_DM3XX_MSINT 26
|
||||
#define IRQ_DM3XX_MMCINT1 27
|
||||
#define IRQ_DM3XX_PWMINT3 28
|
||||
#define IRQ_DM3XX_SDIOINT1 31
|
||||
#define IRQ_DM3XX_SPINT0_0 42
|
||||
#define IRQ_DM3XX_SPINT0_1 43
|
||||
#define IRQ_DM3XX_GPIO0 44
|
||||
#define IRQ_DM3XX_GPIO1 45
|
||||
#define IRQ_DM3XX_GPIO2 46
|
||||
#define IRQ_DM3XX_GPIO3 47
|
||||
#define IRQ_DM3XX_GPIO4 48
|
||||
#define IRQ_DM3XX_GPIO5 49
|
||||
#define IRQ_DM3XX_GPIO6 50
|
||||
#define IRQ_DM3XX_GPIO7 51
|
||||
#define IRQ_DM3XX_GPIO8 52
|
||||
#define IRQ_DM3XX_GPIO9 53
|
||||
|
||||
/* DaVinci DM365-specific Interrupts */
|
||||
#define IRQ_DM365_INSFINT 7
|
||||
#define IRQ_DM365_IMXINT1 8
|
||||
#define IRQ_DM365_IMXINT0 10
|
||||
#define IRQ_DM365_KLD_ARMINT 10
|
||||
#define IRQ_DM365_CCERRINT 17
|
||||
#define IRQ_DM365_TCERRINT0 18
|
||||
#define IRQ_DM365_SPINT2_0 19
|
||||
#define IRQ_DM365_PSCINT 20
|
||||
#define IRQ_DM365_TVINT 20
|
||||
#define IRQ_DM365_SPINT4_0 21
|
||||
#define IRQ_DM365_MBXINT 24
|
||||
#define IRQ_DM365_VCINT 24
|
||||
#define IRQ_DM365_MBRINT 25
|
||||
#define IRQ_DM365_TINT9 28
|
||||
#define IRQ_DM365_TINT4_TINT34 28
|
||||
#define IRQ_DM365_DDRINT 29
|
||||
#define IRQ_DM365_RTCINT 29
|
||||
#define IRQ_DM365_AEMIFINT 30
|
||||
#define IRQ_DM365_HPIINT 30
|
||||
#define IRQ_DM365_TINT0 32
|
||||
#define IRQ_DM365_TINT0_TINT12 32
|
||||
#define IRQ_DM365_TINT1 33
|
||||
#define IRQ_DM365_TINT0_TINT34 33
|
||||
#define IRQ_DM365_TINT2 34
|
||||
#define IRQ_DM365_TINT1_TINT12 34
|
||||
#define IRQ_DM365_TINT3 35
|
||||
#define IRQ_DM365_TINT1_TINT34 35
|
||||
#define IRQ_DM365_PWMINT2 38
|
||||
#define IRQ_DM365_TINT8 38
|
||||
#define IRQ_DM365_TINT4_TINT12 38
|
||||
#define IRQ_DM365_IICINT 39
|
||||
#define IRQ_DM365_SPINT3_0 43
|
||||
#define IRQ_DM365_EMAC_RXTHRESH 52
|
||||
#define IRQ_DM365_EMAC_RXPULSE 53
|
||||
#define IRQ_DM365_GPIO10 54
|
||||
#define IRQ_DM365_EMAC_TXPULSE 54
|
||||
#define IRQ_DM365_GPIO11 55
|
||||
#define IRQ_DM365_EMAC_MISCPULSE 55
|
||||
#define IRQ_DM365_GPIO12 56
|
||||
#define IRQ_DM365_PWRGIO0 56
|
||||
#define IRQ_DM365_GPIO13 57
|
||||
#define IRQ_DM365_PWRGIO1 57
|
||||
#define IRQ_DM365_GPIO14 58
|
||||
#define IRQ_DM365_PWRGIO2 58
|
||||
#define IRQ_DM365_GPIO15 59
|
||||
#define IRQ_DM365_ADCINT 59
|
||||
#define IRQ_DM365_KEYINT 60
|
||||
#define IRQ_DM365_COMMTX 61
|
||||
#define IRQ_DM365_TCERRINT2 61
|
||||
#define IRQ_DM365_COMMRX 62
|
||||
#define IRQ_DM365_TCERRINT3 62
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
48
bsp/dm365/platform/psc.c
Normal file
48
bsp/dm365/platform/psc.c
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
#include "dm36x.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ *
|
||||
* psc_change_state( id, state ) *
|
||||
* id = Domain #ID *
|
||||
* state = ( ENABLE, DISABLE, SYNCRESET, RESET ) *
|
||||
* ( =3 , =2 , =1 , =0 ) *
|
||||
* ------------------------------------------------------------------------ */
|
||||
void psc_change_state(int id, int state)
|
||||
{
|
||||
rt_uint32_t mdstat, mdctl;
|
||||
|
||||
if (id > DAVINCI_DM365_LPSC_KALEIDO)
|
||||
return;
|
||||
|
||||
mdstat = PSC_MDSTAT_BASE + (id * 4);
|
||||
mdctl = PSC_MDCTL_BASE + (id * 4);
|
||||
|
||||
/*
|
||||
* Step 0 - Ignore request if the state is already set as is
|
||||
*/
|
||||
if ((readl(mdstat) & 0x1f) == state)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Step 1 - Wait for PTSTAT.GOSTAT to clear
|
||||
*/
|
||||
while (readl(PSC_PTSTAT) & 1) ;
|
||||
|
||||
/*
|
||||
* Step 2 - Set MDCTLx.NEXT to new state
|
||||
*/
|
||||
writel(readl(mdctl) & (~0x1f), mdctl);
|
||||
writel(readl(mdctl) | state, mdctl);
|
||||
|
||||
/*
|
||||
* Step 3 - Start power transition ( set PTCMD.GO to 1 )
|
||||
*/
|
||||
writel(readl(PSC_PTCMD) | 1, PSC_PTCMD);
|
||||
|
||||
/*
|
||||
* Step 4 - Wait for PTSTAT.GOSTAT to clear
|
||||
*/
|
||||
while (readl(PSC_PTSTAT) & 1) ;
|
||||
}
|
||||
|
||||
86
bsp/dm365/platform/psc.h
Normal file
86
bsp/dm365/platform/psc.h
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
#ifndef __DM36X_PSC_H
|
||||
#define __DM36X_PSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* PSC register offsets */
|
||||
#define EPCPR 0x070
|
||||
#define PTCMD 0x120
|
||||
#define PTSTAT 0x128
|
||||
#define PDSTAT 0x200
|
||||
#define PDCTL1 0x304
|
||||
#define MDSTAT(n) (0x800 + (n) * 4)
|
||||
#define MDCTL(n) (0xA00 + (n) * 4)
|
||||
|
||||
/* Power and Sleep Controller (PSC) Domains */
|
||||
#define DAVINCI_GPSC_ARMDOMAIN 0
|
||||
#define DAVINCI_GPSC_DSPDOMAIN 1
|
||||
|
||||
|
||||
#define DAVINCI_DM365_LPSC_TPCC 0
|
||||
#define DAVINCI_DM365_LPSC_TPTC0 1
|
||||
#define DAVINCI_DM365_LPSC_TPTC1 2
|
||||
#define DAVINCI_DM365_LPSC_TPTC2 3
|
||||
#define DAVINCI_DM365_LPSC_TPTC3 4
|
||||
#define DAVINCI_DM365_LPSC_TIMER3 5
|
||||
#define DAVINCI_DM365_LPSC_SPI1 6
|
||||
#define DAVINCI_DM365_LPSC_MMC_SD1 7
|
||||
#define DAVINCI_DM365_LPSC_McBSP 8
|
||||
#define DAVINCI_DM365_LPSC_USB 9
|
||||
#define DAVINCI_DM365_LPSC_PWM3 10
|
||||
#define DAVINCI_DM365_LPSC_SPI2 11
|
||||
#define DAVINCI_DM365_LPSC_RTO 12
|
||||
#define DAVINCI_DM365_LPSC_DDR_EMIF 13
|
||||
#define DAVINCI_DM365_LPSC_AEMIF 14
|
||||
#define DAVINCI_DM365_LPSC_MMC_SD 15
|
||||
#define DAVINCI_DM365_LPSC_MMC_SD0 15
|
||||
#define DAVINCI_DM365_LPSC_MEMSTICK 16
|
||||
#define DAVINCI_DM365_LPSC_TIMER4 17
|
||||
#define DAVINCI_DM365_LPSC_I2C 18
|
||||
#define DAVINCI_DM365_LPSC_UART0 19
|
||||
#define DAVINCI_DM365_LPSC_UART1 20
|
||||
#define DAVINCI_DM365_LPSC_UHPI 21
|
||||
#define DAVINCI_DM365_LPSC_SPI0 22
|
||||
#define DAVINCI_DM365_LPSC_PWM0 23
|
||||
#define DAVINCI_DM365_LPSC_PWM1 24
|
||||
#define DAVINCI_DM365_LPSC_PWM2 25
|
||||
#define DAVINCI_DM365_LPSC_GPIO 26
|
||||
#define DAVINCI_DM365_LPSC_TIMER0 27
|
||||
#define DAVINCI_DM365_LPSC_TIMER1 28
|
||||
#define DAVINCI_DM365_LPSC_TIMER2 29
|
||||
#define DAVINCI_DM365_LPSC_SYSTEM_SUBSYS 30
|
||||
#define DAVINCI_DM365_LPSC_ARM 31
|
||||
#define DAVINCI_DM365_LPSC_SCR0 33
|
||||
#define DAVINCI_DM365_LPSC_SCR1 34
|
||||
#define DAVINCI_DM365_LPSC_EMU 35
|
||||
#define DAVINCI_DM365_LPSC_CHIPDFT 36
|
||||
#define DAVINCI_DM365_LPSC_PBIST 37
|
||||
#define DAVINCI_DM365_LPSC_SPI3 38
|
||||
#define DAVINCI_DM365_LPSC_SPI4 39
|
||||
#define DAVINCI_DM365_LPSC_CPGMAC 40
|
||||
#define DAVINCI_DM365_LPSC_RTC 41
|
||||
#define DAVINCI_DM365_LPSC_KEYSCAN 42
|
||||
#define DAVINCI_DM365_LPSC_ADCIF 43
|
||||
#define DAVINCI_DM365_LPSC_VOICE_CODEC 44
|
||||
#define DAVINCI_DM365_LPSC_DAC_CLKRES 45
|
||||
#define DAVINCI_DM365_LPSC_DAC_CLK 46
|
||||
#define DAVINCI_DM365_LPSC_VPSSMSTR 47
|
||||
#define DAVINCI_DM365_LPSC_IMCOP 50
|
||||
#define DAVINCI_DM365_LPSC_KALEIDO 51
|
||||
|
||||
#define PSC_ENABLE 3
|
||||
#define PSC_DISABLE 2
|
||||
#define PSC_SYNCRESET 1
|
||||
#define PSC_RESET 0
|
||||
|
||||
void psc_change_state(int id, int state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
66
bsp/dm365/platform/reset.c
Normal file
66
bsp/dm365/platform/reset.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* File : cpu.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-03-13 Bernard first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include "dm36x.h"
|
||||
|
||||
/**
|
||||
* @addtogroup DM36X
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* reset cpu by dog's time-out
|
||||
*
|
||||
*/
|
||||
void machine_reset()
|
||||
{
|
||||
reset_system();
|
||||
}
|
||||
|
||||
/**
|
||||
* shutdown CPU
|
||||
*
|
||||
*/
|
||||
void machine_shutdown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
|
||||
#include <finsh.h>
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, reset, restart the system);
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
int cmd_reset(int argc, char** argv)
|
||||
{
|
||||
rt_hw_cpu_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_shutdown(int argc, char** argv)
|
||||
{
|
||||
rt_hw_cpu_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(cmd_reset, __cmd_reset, restart the system.);
|
||||
FINSH_FUNCTION_EXPORT_ALIAS(cmd_shutdown, __cmd_shutdown, shutdown the system.);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
367
bsp/dm365/platform/start_gcc.S
Normal file
367
bsp/dm365/platform/start_gcc.S
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* File : start.S
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2010-11-13 weety first version
|
||||
*/
|
||||
|
||||
#define CONFIG_STACKSIZE 512
|
||||
#define S_FRAME_SIZE 68
|
||||
|
||||
#define S_PC 64
|
||||
#define S_LR 60
|
||||
#define S_SP 56
|
||||
#define S_IP 52
|
||||
#define S_FP 48
|
||||
#define S_R10 44
|
||||
#define S_R9 40
|
||||
#define S_R8 36
|
||||
#define S_R7 32
|
||||
#define S_R6 28
|
||||
#define S_R5 24
|
||||
#define S_R4 20
|
||||
#define S_R3 16
|
||||
#define S_R2 12
|
||||
#define S_R1 8
|
||||
#define S_R0 4
|
||||
#define S_CPSR 0
|
||||
|
||||
.equ I_BIT, 0x80 @ when I bit is set, IRQ is disabled
|
||||
.equ F_BIT, 0x40 @ when F bit is set, FIQ is disabled
|
||||
|
||||
.equ USERMODE, 0x10
|
||||
.equ FIQMODE, 0x11
|
||||
.equ IRQMODE, 0x12
|
||||
.equ SVCMODE, 0x13
|
||||
.equ ABORTMODE, 0x17
|
||||
.equ UNDEFMODE, 0x1b
|
||||
.equ MODEMASK, 0x1f
|
||||
.equ NOINT, 0xc0
|
||||
|
||||
.equ RAM_BASE, 0x00000000 /*Start address of RAM */
|
||||
.equ ROM_BASE, 0x80000000 /*Start address of Flash */
|
||||
|
||||
|
||||
.equ EINT_ENABLE0, 0x01c48018
|
||||
.equ EINT_ENABLE1, 0x01c4801c
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Jump vector table
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
b reset
|
||||
ldr pc, _vector_undef
|
||||
ldr pc, _vector_swi
|
||||
ldr pc, _vector_pabt
|
||||
ldr pc, _vector_dabt
|
||||
ldr pc, _vector_resv
|
||||
ldr pc, _vector_irq
|
||||
ldr pc, _vector_fiq
|
||||
|
||||
_vector_undef: .word vector_undef
|
||||
_vector_swi: .word vector_swi
|
||||
_vector_pabt: .word vector_pabt
|
||||
_vector_dabt: .word vector_dabt
|
||||
_vector_resv: .word vector_resv
|
||||
_vector_irq: .word vector_irq
|
||||
_vector_fiq: .word vector_fiq
|
||||
|
||||
.balignl 16,0xdeadbeef
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Startup Code (reset vector)
|
||||
* relocate armboot to ram
|
||||
* setup stack
|
||||
* jump to second stage
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
_TEXT_BASE:
|
||||
.word TEXT_BASE
|
||||
|
||||
/*
|
||||
* rtthread kernel start and end
|
||||
* which are defined in linker script
|
||||
*/
|
||||
.globl _rtthread_start
|
||||
_rtthread_start:
|
||||
.word _start
|
||||
|
||||
.globl _rtthread_end
|
||||
_rtthread_end:
|
||||
.word _end
|
||||
|
||||
/*
|
||||
* rtthread bss start and end which are defined in linker script
|
||||
*/
|
||||
.globl _bss_start
|
||||
_bss_start:
|
||||
.word __bss_start
|
||||
|
||||
.globl _bss_end
|
||||
_bss_end:
|
||||
.word __bss_end
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word _irq_stack_start + 1024
|
||||
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word _fiq_stack_start + 1024
|
||||
|
||||
.globl UNDEFINED_STACK_START
|
||||
UNDEFINED_STACK_START:
|
||||
.word _undefined_stack_start + CONFIG_STACKSIZE
|
||||
|
||||
.globl ABORT_STACK_START
|
||||
ABORT_STACK_START:
|
||||
.word _abort_stack_start + CONFIG_STACKSIZE
|
||||
|
||||
.globl _STACK_START
|
||||
_STACK_START:
|
||||
.word _svc_stack_start + 1024
|
||||
|
||||
/* ----------------------------------entry------------------------------*/
|
||||
reset:
|
||||
|
||||
/* set the cpu to SVC32 mode */
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#MODEMASK
|
||||
orr r0,r0,#SVCMODE
|
||||
msr cpsr,r0
|
||||
|
||||
/* mask all IRQs by clearing all bits in the INTMRs */
|
||||
mov r1, $0
|
||||
ldr r0, =EINT_ENABLE0
|
||||
str r1, [r0]
|
||||
ldr r0, =EINT_ENABLE1
|
||||
str r1, [r0]
|
||||
#if 0
|
||||
/* set interrupt vector */
|
||||
ldr r0, _TEXT_BASE
|
||||
mov r1, #0x00
|
||||
add r2, r0, #0x40 /* size, 32bytes */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r3-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end addreee [r2] */
|
||||
ble copy_loop
|
||||
#endif
|
||||
|
||||
/* setup stack */
|
||||
bl stack_setup
|
||||
|
||||
/* clear .bss */
|
||||
mov r0,#0 /* get a zero */
|
||||
ldr r1,=__bss_start /* bss start */
|
||||
ldr r2,=__bss_end /* bss end */
|
||||
|
||||
bss_loop:
|
||||
cmp r1,r2 /* check if data to clear */
|
||||
strlo r0,[r1],#4 /* clear 4 bytes */
|
||||
blo bss_loop /* loop until done */
|
||||
|
||||
/* call C++ constructors of global objects */
|
||||
ldr r0, =__ctors_start__
|
||||
ldr r1, =__ctors_end__
|
||||
|
||||
ctor_loop:
|
||||
cmp r0, r1
|
||||
beq ctor_end
|
||||
ldr r2, [r0], #4
|
||||
stmfd sp!, {r0-r1}
|
||||
mov lr, pc
|
||||
bx r2
|
||||
ldmfd sp!, {r0-r1}
|
||||
b ctor_loop
|
||||
|
||||
ctor_end:
|
||||
|
||||
/* start RT-Thread Kernel */
|
||||
ldr pc, _rtthread_startup
|
||||
|
||||
_rtthread_startup:
|
||||
.word rtthread_startup
|
||||
#if defined (__FLASH_BUILD__)
|
||||
_load_address:
|
||||
.word ROM_BASE + _TEXT_BASE
|
||||
#else
|
||||
_load_address:
|
||||
.word RAM_BASE + _TEXT_BASE
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Interrupt handling
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.macro push_exp_reg
|
||||
sub sp, sp, #S_FRAME_SIZE @/* Sizeof(struct rt_hw_stack) */
|
||||
stmib sp, {r0 - r12} @/* Calling r0-r12 */
|
||||
mov r0, sp
|
||||
mrs r6, spsr @/* Save CPSR */
|
||||
str lr, [r0, #S_PC] @/* Push PC */
|
||||
str r6, [r0, #S_CPSR] @/* Push CPSR */
|
||||
@ switch to SVC mode with no interrupt
|
||||
msr cpsr_c, #I_BIT|F_BIT|SVCMODE
|
||||
str sp, [r0, #S_SP] @/* Save calling SP */
|
||||
str lr, [r0, #S_LR] @/* Save calling PC */
|
||||
.endm
|
||||
/* exception handlers */
|
||||
.align 5
|
||||
vector_undef:
|
||||
push_exp_reg
|
||||
bl rt_hw_trap_udef
|
||||
|
||||
.align 5
|
||||
vector_swi:
|
||||
push_exp_reg
|
||||
bl rt_hw_trap_swi
|
||||
|
||||
.align 5
|
||||
vector_pabt:
|
||||
push_exp_reg
|
||||
bl rt_hw_trap_pabt
|
||||
|
||||
.align 5
|
||||
vector_dabt:
|
||||
push_exp_reg
|
||||
bl rt_hw_trap_dabt
|
||||
|
||||
.align 5
|
||||
vector_resv:
|
||||
push_exp_reg
|
||||
bl rt_hw_trap_resv
|
||||
|
||||
.globl rt_interrupt_enter
|
||||
.globl rt_interrupt_leave
|
||||
.globl rt_thread_switch_interrupt_flag
|
||||
.globl rt_interrupt_from_thread
|
||||
.globl rt_interrupt_to_thread
|
||||
vector_irq:
|
||||
stmfd sp!, {r0-r12,lr}
|
||||
|
||||
bl rt_interrupt_enter
|
||||
bl rt_hw_trap_irq
|
||||
bl rt_interrupt_leave
|
||||
|
||||
|
||||
@ if rt_thread_switch_interrupt_flag set, jump to
|
||||
@ rt_hw_context_switch_interrupt_do and don't return
|
||||
ldr r0, =rt_thread_switch_interrupt_flag
|
||||
ldr r1, [r0]
|
||||
cmp r1, #1
|
||||
beq rt_hw_context_switch_interrupt_do
|
||||
|
||||
ldmfd sp!, {r0-r12,lr}
|
||||
subs pc, lr, #4
|
||||
|
||||
.align 5
|
||||
vector_fiq:
|
||||
stmfd sp!,{r0-r7,lr}
|
||||
bl rt_hw_trap_fiq
|
||||
ldmfd sp!,{r0-r7,lr}
|
||||
subs pc,lr,#4
|
||||
|
||||
rt_hw_context_switch_interrupt_do:
|
||||
mov r1, #0 @ clear flag
|
||||
str r1, [r0]
|
||||
|
||||
ldmfd sp!, {r0-r12,lr}@ reload saved registers
|
||||
stmfd sp, {r0-r2} @ save r0-r2
|
||||
|
||||
mrs r0, spsr @ get cpsr of interrupt thread
|
||||
|
||||
sub r1, sp, #4*3
|
||||
sub r2, lr, #4 @ save old task's pc to r2
|
||||
|
||||
@ switch to SVC mode with no interrupt
|
||||
msr cpsr_c, #I_BIT|F_BIT|SVCMODE
|
||||
|
||||
stmfd sp!, {r2} @ push old task's pc
|
||||
stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4
|
||||
ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread
|
||||
stmfd sp!, {r1-r3} @ push old task's r0-r2
|
||||
stmfd sp!, {r0} @ push old task's cpsr
|
||||
|
||||
ldr r4, =rt_interrupt_from_thread
|
||||
ldr r5, [r4]
|
||||
str sp, [r5] @ store sp in preempted tasks's TCB
|
||||
|
||||
ldr r6, =rt_interrupt_to_thread
|
||||
ldr r6, [r6]
|
||||
ldr sp, [r6] @ get new task's stack pointer
|
||||
|
||||
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
||||
msr spsr_cxsf, r4
|
||||
|
||||
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
||||
|
||||
|
||||
stack_setup:
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #MODEMASK
|
||||
orr r1, r0, #UNDEFMODE|NOINT
|
||||
msr cpsr_cxsf, r1 /* undef mode */
|
||||
ldr sp, UNDEFINED_STACK_START
|
||||
|
||||
orr r1,r0,#ABORTMODE|NOINT
|
||||
msr cpsr_cxsf,r1 /* abort mode */
|
||||
ldr sp, ABORT_STACK_START
|
||||
|
||||
orr r1,r0,#IRQMODE|NOINT
|
||||
msr cpsr_cxsf,r1 /* IRQ mode */
|
||||
ldr sp, IRQ_STACK_START
|
||||
|
||||
orr r1,r0,#FIQMODE|NOINT
|
||||
msr cpsr_cxsf,r1 /* FIQ mode */
|
||||
ldr sp, FIQ_STACK_START
|
||||
|
||||
bic r0,r0,#MODEMASK
|
||||
orr r1,r0,#SVCMODE|NOINT
|
||||
msr cpsr_cxsf,r1 /* SVC mode */
|
||||
|
||||
ldr sp, _STACK_START
|
||||
|
||||
/* USER mode is not initialized. */
|
||||
bx lr /* The LR register may be not valid for the mode changes.*/
|
||||
|
||||
/*/*}*/
|
||||
|
||||
|
||||
29
bsp/dm365/platform/system_clock.c
Normal file
29
bsp/dm365/platform/system_clock.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* File : clock.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-04-25 Yi.qiu first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "dm36x.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
*/
|
||||
void rt_hw_clock_init(void)
|
||||
{
|
||||
//LOCKTIME = 0xFFFFFFFF; //u-boot already init system clock
|
||||
//rt_hw_set_mpll_clock(MPL_SDIV, MPL_PDIV, MPL_MIDV);
|
||||
//rt_hw_set_upll_clock(UPL_SDIV, UPL_PDIV, UPL_MDIV);
|
||||
//rt_hw_set_divider(HDIVN, PDIVN);
|
||||
}
|
||||
|
||||
189
bsp/dm365/platform/trap.c
Normal file
189
bsp/dm365/platform/trap.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2010-11-13 weety first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "dm36x.h"
|
||||
|
||||
/**
|
||||
* @addtogroup DM36X
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
extern struct rt_thread *rt_current_thread;
|
||||
#ifdef RT_USING_FINSH
|
||||
extern long list_thread(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
|
||||
void rt_hw_show_register (struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("Execption:\n");
|
||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
/**
|
||||
* When ARM7TDMI comes across an instruction which it cannot handle,
|
||||
* it takes the undefined instruction trap.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_udef(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("undefined instruction\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* The software interrupt instruction (SWI) is used for entering
|
||||
* Supervisor mode, usually to request a particular supervisor
|
||||
* function.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_swi(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("software interrupt\n");
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during an instruction prefetch.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_pabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("prefetch abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abort indicates that the current memory access cannot be completed,
|
||||
* which occurs during a data access.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_dabt(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_uint32_t fault_addr;
|
||||
rt_uint32_t fault_status;
|
||||
asm volatile ("mrc p15, 0, %0, c6, c0, 0"
|
||||
:
|
||||
:"r"(fault_addr)
|
||||
:"cc");
|
||||
rt_kprintf("unhandler access to 0x%08x\n", fault_addr);
|
||||
|
||||
/* read DFSR */
|
||||
asm volatile ("MRC p15, 0, %0, c5, c0, 0"
|
||||
:
|
||||
:"r"(fault_status)
|
||||
:"cc");
|
||||
rt_kprintf("fault status 0x%08x\n", fault_status);
|
||||
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("data abort\n");
|
||||
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
#endif
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, system will never reach here
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_resv(struct rt_hw_register *regs)
|
||||
{
|
||||
rt_kprintf("not used\n");
|
||||
rt_hw_show_register(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
extern struct rt_irq_desc irq_desc[];
|
||||
|
||||
|
||||
void rt_hw_trap_irq()
|
||||
{
|
||||
rt_isr_handler_t isr_func;
|
||||
rt_uint32_t val, irq, mask;
|
||||
void *param;
|
||||
|
||||
/* get irq number */
|
||||
val = readl(DAVINCI_ARM_INTC_BASE+0x14) - readl(DAVINCI_ARM_INTC_BASE+0x24);
|
||||
irq = (val >> 2) - 1;
|
||||
/* clear pending register */
|
||||
mask = 1 << (irq & 0x1f);
|
||||
if (irq > 31)
|
||||
writel(mask, DAVINCI_ARM_INTC_BASE+0x0c); //IRQ1
|
||||
else
|
||||
writel(mask, DAVINCI_ARM_INTC_BASE+0x08); //IRQ0
|
||||
|
||||
/* get interrupt service routine */
|
||||
isr_func = irq_desc[irq].handler;
|
||||
param = irq_desc[irq].param;
|
||||
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(irq, param);
|
||||
irq_desc[irq].counter++;
|
||||
}
|
||||
|
||||
void rt_hw_trap_fiq()
|
||||
{
|
||||
rt_kprintf("fast interrupt request\n");
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
Reference in New Issue
Block a user