Add dm365 porting.

This commit is contained in:
weety
2015-09-04 12:30:20 +08:00
parent cb51bdb245
commit b71cb4c09d
45 changed files with 13431 additions and 0 deletions

View 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
View 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);
}

View 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
View 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

File diff suppressed because it is too large Load Diff

308
bsp/dm365/platform/edma.h Normal file
View 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

View 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

View 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
View 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
View 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
View 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

View 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
/*@}*/

View 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.*/
/*/*}*/

View 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
View 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");
}
/*@}*/