From 98d282ae0fb7ef126b5773484e6cabe40de74bc1 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 10 Jun 2024 19:51:19 +0200 Subject: [PATCH 1/6] lib: Vendor in am18x-lib. --- lib/am18x-lib/LICENSE.txt | 21 + lib/am18x-lib/inc/am18x_aintc.h | 30 + lib/am18x-lib/inc/am18x_dclk.h | 134 ++ lib/am18x-lib/inc/am18x_ddr.h | 45 + lib/am18x-lib/inc/am18x_ecap.h | 25 + lib/am18x-lib/inc/am18x_edma.h | 99 + lib/am18x-lib/inc/am18x_gpio.h | 87 + lib/am18x-lib/inc/am18x_i2c.h | 63 + lib/am18x-lib/inc/am18x_lcd.h | 73 + lib/am18x-lib/inc/am18x_lib.h | 84 + lib/am18x-lib/inc/am18x_map.h | 3189 +++++++++++++++++++++++++++++ lib/am18x-lib/inc/am18x_map_s.h | 1313 ++++++++++++ lib/am18x-lib/inc/am18x_mmcsd.h | 93 + lib/am18x-lib/inc/am18x_mpu.h | 8 + lib/am18x-lib/inc/am18x_pll.h | 48 + lib/am18x-lib/inc/am18x_pru.h | 19 + lib/am18x-lib/inc/am18x_psc.h | 21 + lib/am18x-lib/inc/am18x_rtc.h | 37 + lib/am18x-lib/inc/am18x_syscfg.h | 20 + lib/am18x-lib/inc/am18x_timer.h | 56 + lib/am18x-lib/inc/am18x_type.h | 142 ++ lib/am18x-lib/inc/am18x_uart.h | 120 ++ lib/am18x-lib/inc/am18x_usb.h | 17 + lib/am18x-lib/lib/_uart.h | 11 + lib/am18x-lib/lib/arm920t.c | 67 + lib/am18x-lib/lib/arm920t.h | 401 ++++ lib/am18x-lib/lib/arm920t_s.S | 47 + lib/am18x-lib/lib/auxlib.c | 214 ++ lib/am18x-lib/lib/auxlib.h | 56 + lib/am18x-lib/lib/ctype.c | 34 + lib/am18x-lib/lib/ctype.h | 54 + lib/am18x-lib/lib/div64.S | 183 ++ lib/am18x-lib/lib/div64.h | 73 + lib/am18x-lib/lib/dvfs.c | 112 + lib/am18x-lib/lib/dvfs.h | 19 + lib/am18x-lib/lib/i2c_inf.c | 101 + lib/am18x-lib/lib/i2c_inf.h | 9 + lib/am18x-lib/lib/lib1funcs.S | 346 ++++ lib/am18x-lib/lib/linkage.h | 19 + lib/am18x-lib/lib/lshrdi3.S | 51 + lib/am18x-lib/lib/systick.c | 103 + lib/am18x-lib/lib/systick.h | 18 + lib/am18x-lib/lib/uart.c | 79 + lib/am18x-lib/lib/vsprintf.c | 1786 ++++++++++++++++ lib/am18x-lib/prj/abt_handler.S | 133 ++ lib/am18x-lib/prj/am1808exp.c | 95 + lib/am18x-lib/prj/am1808exp.h | 85 + lib/am18x-lib/prj/am18x.ld | 78 + lib/am18x-lib/prj/am18x_conf.c | 167 ++ lib/am18x-lib/prj/am18x_conf.h | 87 + lib/am18x-lib/prj/start.S | 220 ++ lib/am18x-lib/prj/tca6416.c | 91 + lib/am18x-lib/prj/tca6416.h | 19 + lib/am18x-lib/prj/tps6507x.c | 297 +++ lib/am18x-lib/prj/tps6507x.h | 35 + lib/am18x-lib/prj/uart_dbg.S | 113 + lib/am18x-lib/prj/undef_handler.S | 75 + lib/am18x-lib/src/am18x_aintc.c | 137 ++ lib/am18x-lib/src/am18x_dclk.c | 540 +++++ lib/am18x-lib/src/am18x_ddr.c | 264 +++ lib/am18x-lib/src/am18x_ecap.c | 97 + lib/am18x-lib/src/am18x_edma.c | 303 +++ lib/am18x-lib/src/am18x_gpio.c | 242 +++ lib/am18x-lib/src/am18x_i2c.c | 272 +++ lib/am18x-lib/src/am18x_lcd.c | 328 +++ lib/am18x-lib/src/am18x_mmcsd.c | 400 ++++ lib/am18x-lib/src/am18x_pll.c | 254 +++ lib/am18x-lib/src/am18x_pru.c | 93 + lib/am18x-lib/src/am18x_psc.c | 151 ++ lib/am18x-lib/src/am18x_rtc.c | 100 + lib/am18x-lib/src/am18x_syscfg.c | 217 ++ lib/am18x-lib/src/am18x_timer.c | 147 ++ lib/am18x-lib/src/am18x_uart.c | 166 ++ lib/am18x-lib/src/am18x_usb0.c | 165 ++ 74 files changed, 14898 insertions(+) create mode 100644 lib/am18x-lib/LICENSE.txt create mode 100644 lib/am18x-lib/inc/am18x_aintc.h create mode 100644 lib/am18x-lib/inc/am18x_dclk.h create mode 100644 lib/am18x-lib/inc/am18x_ddr.h create mode 100644 lib/am18x-lib/inc/am18x_ecap.h create mode 100644 lib/am18x-lib/inc/am18x_edma.h create mode 100644 lib/am18x-lib/inc/am18x_gpio.h create mode 100644 lib/am18x-lib/inc/am18x_i2c.h create mode 100644 lib/am18x-lib/inc/am18x_lcd.h create mode 100644 lib/am18x-lib/inc/am18x_lib.h create mode 100644 lib/am18x-lib/inc/am18x_map.h create mode 100644 lib/am18x-lib/inc/am18x_map_s.h create mode 100644 lib/am18x-lib/inc/am18x_mmcsd.h create mode 100644 lib/am18x-lib/inc/am18x_mpu.h create mode 100644 lib/am18x-lib/inc/am18x_pll.h create mode 100644 lib/am18x-lib/inc/am18x_pru.h create mode 100644 lib/am18x-lib/inc/am18x_psc.h create mode 100644 lib/am18x-lib/inc/am18x_rtc.h create mode 100644 lib/am18x-lib/inc/am18x_syscfg.h create mode 100644 lib/am18x-lib/inc/am18x_timer.h create mode 100644 lib/am18x-lib/inc/am18x_type.h create mode 100644 lib/am18x-lib/inc/am18x_uart.h create mode 100644 lib/am18x-lib/inc/am18x_usb.h create mode 100644 lib/am18x-lib/lib/_uart.h create mode 100644 lib/am18x-lib/lib/arm920t.c create mode 100644 lib/am18x-lib/lib/arm920t.h create mode 100644 lib/am18x-lib/lib/arm920t_s.S create mode 100644 lib/am18x-lib/lib/auxlib.c create mode 100644 lib/am18x-lib/lib/auxlib.h create mode 100644 lib/am18x-lib/lib/ctype.c create mode 100644 lib/am18x-lib/lib/ctype.h create mode 100644 lib/am18x-lib/lib/div64.S create mode 100644 lib/am18x-lib/lib/div64.h create mode 100644 lib/am18x-lib/lib/dvfs.c create mode 100644 lib/am18x-lib/lib/dvfs.h create mode 100644 lib/am18x-lib/lib/i2c_inf.c create mode 100644 lib/am18x-lib/lib/i2c_inf.h create mode 100644 lib/am18x-lib/lib/lib1funcs.S create mode 100644 lib/am18x-lib/lib/linkage.h create mode 100644 lib/am18x-lib/lib/lshrdi3.S create mode 100644 lib/am18x-lib/lib/systick.c create mode 100644 lib/am18x-lib/lib/systick.h create mode 100644 lib/am18x-lib/lib/uart.c create mode 100644 lib/am18x-lib/lib/vsprintf.c create mode 100644 lib/am18x-lib/prj/abt_handler.S create mode 100644 lib/am18x-lib/prj/am1808exp.c create mode 100644 lib/am18x-lib/prj/am1808exp.h create mode 100644 lib/am18x-lib/prj/am18x.ld create mode 100644 lib/am18x-lib/prj/am18x_conf.c create mode 100644 lib/am18x-lib/prj/am18x_conf.h create mode 100644 lib/am18x-lib/prj/start.S create mode 100644 lib/am18x-lib/prj/tca6416.c create mode 100644 lib/am18x-lib/prj/tca6416.h create mode 100644 lib/am18x-lib/prj/tps6507x.c create mode 100644 lib/am18x-lib/prj/tps6507x.h create mode 100644 lib/am18x-lib/prj/uart_dbg.S create mode 100644 lib/am18x-lib/prj/undef_handler.S create mode 100644 lib/am18x-lib/src/am18x_aintc.c create mode 100644 lib/am18x-lib/src/am18x_dclk.c create mode 100644 lib/am18x-lib/src/am18x_ddr.c create mode 100644 lib/am18x-lib/src/am18x_ecap.c create mode 100644 lib/am18x-lib/src/am18x_edma.c create mode 100644 lib/am18x-lib/src/am18x_gpio.c create mode 100644 lib/am18x-lib/src/am18x_i2c.c create mode 100644 lib/am18x-lib/src/am18x_lcd.c create mode 100644 lib/am18x-lib/src/am18x_mmcsd.c create mode 100644 lib/am18x-lib/src/am18x_pll.c create mode 100644 lib/am18x-lib/src/am18x_pru.c create mode 100644 lib/am18x-lib/src/am18x_psc.c create mode 100644 lib/am18x-lib/src/am18x_rtc.c create mode 100644 lib/am18x-lib/src/am18x_syscfg.c create mode 100644 lib/am18x-lib/src/am18x_timer.c create mode 100644 lib/am18x-lib/src/am18x_uart.c create mode 100644 lib/am18x-lib/src/am18x_usb0.c diff --git a/lib/am18x-lib/LICENSE.txt b/lib/am18x-lib/LICENSE.txt new file mode 100644 index 000000000..2af3fd2a2 --- /dev/null +++ b/lib/am18x-lib/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 - turmary@126.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/am18x-lib/inc/am18x_aintc.h b/lib/am18x-lib/inc/am18x_aintc.h new file mode 100644 index 000000000..d3a47ab92 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_aintc.h @@ -0,0 +1,30 @@ +// tary, 0:01 2013/3/9 + +#ifndef __AM18X_AINTC_H__ +#define __AM18X_AINTC_H__ + +#include "am18x_map.h" + +typedef enum { + AINTC_GLOBAL, + AINTC_HOST_FIQ, + AINTC_HOST_IRQ, +} aintc_host_t; + +typedef struct { + uint32_t isr_addr; + uint32_t isr_size; +} aintc_conf_t; + +#define AINTC_INVALID_ACTIVE (-1) + +am18x_rt aintc_conf(const aintc_conf_t* conf); +am18x_rt aintc_enable(aintc_host_t host); +am18x_rt aintc_disable(aintc_host_t host); +am18x_rt aintc_sys_enable(AINTC_assign_t assign); +am18x_rt aintc_sys_disable(AINTC_assign_t assign); +am18x_rt aintc_trigger(AINTC_assign_t assign); +am18x_rt aintc_clear(AINTC_assign_t assign); +int32_t aintc_get_active(void); + +#endif//__AM18X_AINTC_H__ diff --git a/lib/am18x-lib/inc/am18x_dclk.h b/lib/am18x-lib/inc/am18x_dclk.h new file mode 100644 index 000000000..4e909736e --- /dev/null +++ b/lib/am18x-lib/inc/am18x_dclk.h @@ -0,0 +1,134 @@ +// tary, 19:03 2013/4/20 + +#ifndef __AM18X_DCLK_H__ +#define __AM18X_DCLK_H__ + +#include "am18x_map.h" + +typedef enum { + CLK_NODE_INVALID, + + CLK_NODE_PLL0_SYSCLK1, + CLK_NODE_PLL0_SYSCLK2, + CLK_NODE_PLL0_SYSCLK3, + CLK_NODE_PLL0_SYSCLK4, + CLK_NODE_PLL0_SYSCLK5, + CLK_NODE_PLL0_SYSCLK6, + CLK_NODE_PLL0_SYSCLK7, + CLK_NODE_EMA_CLKSRC, + CLK_NODE_PLL0_AUXCLK, + CLK_NODE_PLL0_OBSCLK, + CLK_NODE_PLL1_SYSCLK1, + CLK_NODE_PLL1_SYSCLK2, + CLK_NODE_PLL1_SYSCLK3, + CLK_NODE_PLL1_OBSCLK, + + CLK_NODE_ASYNC3, + + CLK_NODE_PLL0_PLLEN, + CLK_NODE_PLL_EXTSRC, + CLK_NODE_POSTDIV0, + CLK_NODE_PLLM0, + CLK_NODE_PREDIV0, + CLK_NODE_PLL_CLKMODE, + + CLK_NODE_DIV4_5X, + CLK_NODE_DIV4_5, + + CLK_NODE_OSCDIV0, + CLK_NODE_OCSEL0_OCSRC, + + CLK_NODE_PLL1_PLLEN, + CLK_NODE_POSTDIV1, + CLK_NODE_PLLM1, + + CLK_NODE_OSCDIV1, + CLK_NODE_OCSEL1_OCSRC, + + CLK_NODE_OSCIN, + CLK_NODE_CNT, +} clk_node_id_t; + +typedef uint32_t (*pll_calc_freq_t) (uint32_t parent); + +typedef struct { + cuint32_t id; + const char* name; + uint32_t parent; +#define CN_FLAG_DIV 0x00000001UL +#define CN_FLAG_MULT 0x00000002UL +#define CN_FLAG_MULTI_DIV 0x00000003UL +#define CN_FLAG_MUX 0x00000004UL +#define CN_FLAG_REREAD 0x00000008UL +#define CN_FLAG_RECALC 0x00000010UL +#define CN_FLAG_VISITED 0x00000020UL + uint32_t flag; + uint32_t multiplier; + uint32_t divider; + pll_calc_freq_t calc_freq; + pll_calc_freq_t do_change; + uint32_t* parent_list; + uint32_t freq; +} clk_node_t; + +#define DCLK_ID_GRP_SZ 0x100 +typedef enum { + DCLK_ID_ARM_RAM_ROM = CLK_NODE_PLL0_SYSCLK2 * DCLK_ID_GRP_SZ, + DCLK_ID_ON_CHIP_RAM, + DCLK_ID_UART0, + DCLK_ID_EDMA, + DCLK_ID_SPI0, + DCLK_ID_MMC_SDS, + DCLK_ID_VPIF, + DCLK_ID_LCDC, + DCLK_ID_SATA, + DCLK_ID_UPP, + DCLK_ID_DDR2_MDDR, + DCLK_ID_USB2_0, + DCLK_ID_HPI, + DCLK_ID_PRUSS, + + DCLK_ID_EMIFA = CLK_NODE_EMA_CLKSRC * DCLK_ID_GRP_SZ, + + DCLK_ID_SYSCFG = CLK_NODE_PLL0_SYSCLK4 * DCLK_ID_GRP_SZ, + DCLK_ID_GPIO, + DCLK_ID_PLLCS, + DCLK_ID_PSCS, + DCLK_ID_I2C1, + DCLK_ID_EMAC_MDIO, + DCLK_ID_USB1_1, + DCLK_ID_ARM_INTC, + + DCLK_ID_ARM = CLK_NODE_PLL0_SYSCLK6 * DCLK_ID_GRP_SZ, + + DCLK_ID_EMAC_RMII = CLK_NODE_PLL0_SYSCLK7 * DCLK_ID_GRP_SZ, + + DCLK_ID_I2C0 = CLK_NODE_PLL0_AUXCLK * DCLK_ID_GRP_SZ, + DCLK_ID_TIMER64P0, + DCLK_ID_TIMER64P1, + DCLK_ID_RTC, + DCLK_ID_USB2_0_PHY, + DCLK_ID_MCASP0_SCLK, + + DCLK_ID_DDR2_MDDR_PHY = CLK_NODE_PLL1_SYSCLK1 * DCLK_ID_GRP_SZ, + + DCLK_ID_ECAPS = CLK_NODE_ASYNC3 * DCLK_ID_GRP_SZ, + DCLK_ID_UART1, + DCLK_ID_UART2, + DCLK_ID_TIMER64P2, + DCLK_ID_TIMER64P3, + DCLK_ID_EHRPWMS, + DCLK_ID_MCBSPS, + DCLK_ID_MCASP0, + DCLK_ID_SPI1, +} dev_clk_id_t; + +am18x_rt clk_node_init(void); +am18x_rt clk_node_output(void); +am18x_rt clk_node_tree(void); +am18x_rt clk_node_recalc(void); +uint32_t clk_node_get_freq(uint32_t id); +am18x_rt clk_node_set_parent(uint32_t id, uint32_t parent); +uint32_t dev_get_freq(uint32_t dclk_id); + +#endif//__AM18X_DCLK_H__ diff --git a/lib/am18x-lib/inc/am18x_ddr.h b/lib/am18x-lib/inc/am18x_ddr.h new file mode 100644 index 000000000..d99913e7a --- /dev/null +++ b/lib/am18x-lib/inc/am18x_ddr.h @@ -0,0 +1,45 @@ +// tary, 23:50 2013/10/27 + +#ifndef __AM18X_DDR_H__ +#define __AM18X_DDR_H__ + +#include "am18x_map.h" + +typedef struct { + uint8_t ddr2_not_mddr; + uint8_t page_size; // 8..11 + uint8_t row_size; // 9..16 + uint8_t bank_cnt; // 1,2,4,8 + + uint32_t freq_ck; + uint32_t trefi; // ns + + uint8_t cl; // 2..3 + uint8_t trfc; // ns + uint8_t trp; // ... + uint8_t trcd; + + uint8_t twr; + uint8_t tras; + uint8_t trc; + uint8_t trrd; + + uint8_t twtr; + uint8_t todt; + uint8_t txsnr; + uint8_t trtp; + + uint8_t txp; // tck + uint8_t txsrd; // tck + uint8_t tcke; // tck + + uint32_t trasmax; + + uint8_t pasr; +} ddr_conf_t; + +am18x_rt ddr_initialize(DDR_con_t* dcon, const ddr_conf_t* conf); +am18x_rt ddr_clock_off(DDR_con_t* dcon); +am18x_rt ddr_clock_on(DDR_con_t* dcon); + +#endif//__AM18X_DDR_H__ diff --git a/lib/am18x-lib/inc/am18x_ecap.h b/lib/am18x-lib/inc/am18x_ecap.h new file mode 100644 index 000000000..288355eb3 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_ecap.h @@ -0,0 +1,25 @@ +// tary, 20:42 2017/6/20 + +#ifndef __AM18X_ECAP_H__ +#define __AM18X_ECAP_H__ + +#include "am18x_map.h" + +typedef enum { + ECAP_DISABLE = 0, + ECAP_ENABLE = BIT(0), + ECAP_ACTIVE_LOW = 0, + ECAP_ACTIVE_HIGH = BIT(1), +} ecap_cflag_t; + +typedef struct { + uint32_t freq; + uint32_t duty; + uint8_t cflags; +} ecap_conf_t; + +am18x_rt ecap_init(ECAP_con_t* econ); +am18x_rt ecap_get_conf(ECAP_con_t* econ, ecap_conf_t* conf); +am18x_rt ecap_set_conf(ECAP_con_t* econ, const ecap_conf_t* conf); + +#endif//__AM18X_ECAP_H__ diff --git a/lib/am18x-lib/inc/am18x_edma.h b/lib/am18x-lib/inc/am18x_edma.h new file mode 100644 index 000000000..dd5312c53 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_edma.h @@ -0,0 +1,99 @@ +// tary, 0:18 2013/6/6 + +#ifndef __AM18X_EDMA_H__ +#define __AM18X_EDMA_H__ + +#include "am18x_map.h" + +#define CHANNEL_X_MAX (0x1FUL) +#define CHANNEL(x) ((x) & CHANNEL_X_MAX) +#define QCHANNEL_X_MAX (0x7UL) +#define QCHANNEL(x) ((x) & QCHANNEL_X_MAX) +#define TR_WORD(addr) (((addr) & 0x1FUL) >> 2) + +typedef enum { + REGION_0, + REGION_1, + REGION_GLOBAL, +} edma_region_t; + +typedef enum { + EDMA_Q0, + EDMA_Q1, // EDMA1 only +} emda_queue_t; + +typedef enum { + DMA_EVENT_TRIGGERED, + DMA_MANUALLY_TRIGGERED, + // DMA_CHAIN_TRIGGERED, + QDMA_AUTO_TRIGGERED, + // QDMA_LINK_TRIGGERED, +} edma_trigger_t; + +typedef enum { + // each sync event initiates the transfer of + // one array (ACNT bytes) only + FLAG_SYNCTYPE_A = 0, + // each sync event initiates the transfer of + // one frame (BCNT arrays of ACNT bytes) + FLAG_SYNCTYPE_AB = BIT(0), + FLAG_TRANS_EVT = BIT(1), + FLAG_TRANS_INTR = BIT(2), + FLAG_LAST_PAENTRY = BIT(3), + FLAG_TCC_NORMAL = 0, + FLAG_TCC_EARLY = BIT(4), +} conf_flags_t; + +typedef struct { + uint32_t src; // source start address + uint32_t dst; // destination start address + + uint16_t a_cnt; // (one array has a_cnt bytes) + uint16_t b_cnt; // (one frame has b_cnt arrays) + + uint16_t c_cnt; // (one pa entry transfer has c_cnt frames) +#define LINK_NULL 0xFFFFUL +#define LINK_NEXT(idx) (0x4000UL + ((idx) << 5)) + uint16_t link; // linked as pa[n].link = ¶m[pa[n+1].index] + + uint16_t src_b_idx; // distance (arrrys[n+1], array[n]) in a frame + uint16_t dst_b_idx; // + + uint16_t src_c_idx; // A-sync for distance (frames[n + 1].0, frames[n].last) + uint16_t dst_c_idx; // AB-sync for distance (frames[n + 1].0, frames[n].0) + + uint8_t priv_id; // 0 --- EDMA3 master's privilege identification value + uint8_t tcc; // chain channel or interrupt bit index # + uint8_t index; // index of PaRAM set + uint8_t reserved0[1]; // QCHANNEL --- customized by user + // CHANNEL --- first one identical with edma_conf_t.channel + // other ones can be chained as pa[n].tcc = pa[n + 1].index + uint32_t flags; +} pa_conf_t; + +typedef struct { + pa_conf_t* pa_conf; // param sets as chained or linked + uint16_t pa_cnt; // elements count of pa_conf + uint8_t tr_word; // QCHANNEL only + uint8_t reserved0[1]; + + uint8_t channel; // CHANNEL(n) or QCHANNEL(n) + uint8_t region; // edma_region_t + uint8_t queue; // emda_queue_t + uint8_t trigger; // edma_trigger_t +} edma_conf_t; + +typedef struct { + char* status[8]; + uint32_t comp_actv; + uint16_t queue_evts[2]; +} edma_stat_t; + +am18x_rt edma_init(EDMA_con_t* econ, const edma_conf_t* conf); +am18x_rt edma_param(EDMA_con_t* econ, const edma_conf_t* conf); +am18x_rt edma_interrupt(EDMA_con_t* econ, const edma_conf_t* conf); +am18x_rt edma_transfer(EDMA_con_t* econ, const edma_conf_t* conf); +am18x_rt edma_completed(EDMA_con_t* econ, const edma_conf_t* conf); +am18x_rt edma_status(const EDMA_con_t* econ, edma_stat_t* stat); + +#endif//__AM18X_EDMA_H__ diff --git a/lib/am18x-lib/inc/am18x_gpio.h b/lib/am18x-lib/inc/am18x_gpio.h new file mode 100644 index 000000000..5f0c78be5 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_gpio.h @@ -0,0 +1,87 @@ +// tary, 0:31 2013/4/26 + +#ifndef __AM18X_GPIO_H__ +#define __AM18X_GPIO_H__ + +#include "am18x_map.h" + +typedef enum { + GPIO_LOW = 0, + GPIO_HIGH = 1, +} gpio_level_t; + +typedef enum { + GPIO_BANK0, + GPIO_BANK1, + GPIO_BANK2, + GPIO_BANK3, + GPIO_BANK4, + GPIO_BANK5, + GPIO_BANK6, + GPIO_BANK7, + GPIO_BANK8, +} gpio_bank_t; + +typedef enum { + GPIO_PIN_0, + GPIO_PIN_1, + GPIO_PIN_2, + GPIO_PIN_3, + GPIO_PIN_4, + GPIO_PIN_5, + GPIO_PIN_6, + GPIO_PIN_7, + GPIO_PIN_8, + GPIO_PIN_9, + GPIO_PIN_10, + GPIO_PIN_11, + GPIO_PIN_12, + GPIO_PIN_13, + GPIO_PIN_14, + GPIO_PIN_15, +} gpio_pin_t; + +typedef enum { + GPIO_PINS_0 = BIT(0), + GPIO_PINS_1 = BIT(1), + GPIO_PINS_2 = BIT(2), + GPIO_PINS_3 = BIT(3), + GPIO_PINS_4 = BIT(4), + GPIO_PINS_5 = BIT(5), + GPIO_PINS_6 = BIT(6), + GPIO_PINS_7 = BIT(7), + GPIO_PINS_8 = BIT(8), + GPIO_PINS_9 = BIT(9), + GPIO_PINS_10 = BIT(10), + GPIO_PINS_11 = BIT(11), + GPIO_PINS_12 = BIT(12), + GPIO_PINS_13 = BIT(13), + GPIO_PINS_14 = BIT(14), + GPIO_PINS_15 = BIT(15), + GPIO_PINS_ALL = BIT(16) - 1, +} gpio_pins_cell_t; + +typedef enum { + GPIO_DIR_INPUT, + GPIO_DIR_OUTPUT, +} gpio_dir_t; + +typedef uint32_t gpio_pins_t; + +am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir); + +gpio_level_t gpio_get_input1(gpio_bank_t bank, gpio_pin_t pin); +am18x_rt gpio_set_output1(gpio_bank_t bank, gpio_pin_t pin, gpio_level_t level); +/* get the level last output */ +gpio_level_t gpio_get_output1(gpio_bank_t bank, gpio_pin_t pin); + +/* + bit set == level high + bit reset == level low +*/ +gpio_pins_t gpio_get_inputs(gpio_bank_t bank, gpio_pins_t pins); +am18x_rt gpio_set_outputs(gpio_bank_t bank, gpio_pins_t pins, gpio_pins_t levels); +/* get levels last output */ +gpio_pins_t gpio_get_outputs(gpio_bank_t bank, gpio_pins_t pins); + +#endif//__AM18X_GPIO_H__ diff --git a/lib/am18x-lib/inc/am18x_i2c.h b/lib/am18x-lib/inc/am18x_i2c.h new file mode 100644 index 000000000..394465c27 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_i2c.h @@ -0,0 +1,63 @@ +// tary, 22:00 2013/3/13 + +#ifndef __AM18X_I2C_H__ +#define __AM18X_I2C_H__ + +#include "am18x_map.h" + +typedef enum { + I2C_BITMODE_7BIT, + I2C_BITMODE_10BIT, + I2C_BITMODE_FreeDataFormat, +} i2c_bitmode_t; + +// 22.2.7 Operating Modes +typedef enum { + I2C_OPERMODE_Slave_receiver, + I2C_OPERMODE_Slave_transmitter, + I2C_OPERMODE_Master_receiver, + I2C_OPERMODE_Master_transmitter, +} i2c_opermode_t; + +typedef enum { + I2C_CMD_WAIT_FREE, + I2C_CMD_WAIT_BUSY, + I2C_CMD_WAIT_SLAVE, + I2C_CMD_WAIT_ARDY, + I2C_CMD_WAIT_RX, + I2C_CMD_WAIT_TX, + I2C_CMD_CLR_RX, + I2C_CMD_CLR_TX, + // auto clear + I2C_CMD_BUS_START, + // auto clear + I2C_CMD_BUS_STOP, + // auto clear + I2C_CMD_BUS_NACK, + I2C_CMD_SET_CNT, + I2C_CMD_SET_REPEAT, + I2C_CMD_CLR_REPEAT, + I2C_CMD_TRANSMITTER, + I2C_CMD_RECEIVER, +} i2c_cmd_t; + +typedef struct { + uint32_t freq; + uint16_t addr; + uint8_t bitmode; + uint8_t opermode; +} i2c_conf_t; + +uint32_t i2c_get_serial_clock(I2C_con_t* icon); +am18x_rt i2c_set_serial_clock(I2C_con_t* icon, uint32_t freq); +am18x_rt i2c_conf(I2C_con_t* icon, i2c_conf_t* conf); +static inline int32_t i2c_get_rx(I2C_con_t* icon) { + return icon->ICDRR; +} +static inline am18x_rt i2c_set_tx(I2C_con_t* icon, uint8_t data) { + icon->ICDXR = data; + return AM18X_TRUE; +} +am18x_rt i2c_cmd(I2C_con_t* icon, uint32_t cmd, uint32_t arg); + +#endif//__AM18X_I2C_H__ diff --git a/lib/am18x-lib/inc/am18x_lcd.h b/lib/am18x-lib/inc/am18x_lcd.h new file mode 100644 index 000000000..0b26657c3 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_lcd.h @@ -0,0 +1,73 @@ +// tary, 17:57 2013/12/8 + +#ifndef __AM18X_LCD_H__ +#define __AM18X_LCD_H__ + +#include "am18x_map.h" + +typedef enum { + LCD_BPP_1 = 1, + LCD_BPP_2 = 2, + LCD_BPP_4 = 4, + LCD_BPP_8 = 8, + LCD_BPP_16 = 16, +} lcd_bpp_t; + +typedef enum { + LCD_CFLAG_BIAS_HIGH = 0, + LCD_CFLAG_BIAS_LOW = BIT(0), + LCD_CFLAG_PIXEL_RISING = 0, + LCD_CFLAG_PIXEL_FALLING = BIT(1), + LCD_CFLAG_HSYNC_HIGH = 0, + LCD_CFLAG_HSYNC_LOW = BIT(2), + LCD_CFLAG_VSYNC_HIGH = 0, + LCD_CFLAG_VSYNC_LOW = BIT(3), +} lcd_cflag_t; + +typedef enum { + LCD_HVSYNC_PCLK, + LCD_HVSYNC_RISING, + LCD_HVSYNC_FALLING, +} lcd_hvsync_t; + +typedef struct { + uint32_t pclk; + uint32_t width, height; + uint16_t hfp, hsw, hbp; + uint16_t vfp, vsw, vbp; + uint8_t bpp; + uint8_t hvsync; + uint16_t cflag; + uint32_t fb0_base; + uint32_t fb1_base; +} lcd_conf_t; + +typedef enum { + LCD_CMD_RASTER_EN, + LCD_CMD_RASTER_DIS, + LCD_CMD_PALETTE, + LCD_CMD_DATA, + LCD_CMD_FB_SET, +} lcd_cmd_t; + +typedef enum { + LCD_INTR_AC, + LCD_INTR_DONE, + LCD_INTR_PL, + LCD_INTR_SL, + LCD_INTR_FUF, + LCD_INTR_EOF, + // only for lcd_intr_state(), lcd_intr_clear() + LCD_INTR_EOF1, + // only for lcd_intr_clear() + LCD_INTR_ALL, +} lcd_intr_t; + +am18x_rt lcd_conf(LCD_con_t* lcon, const lcd_conf_t* conf); +am18x_rt lcd_cmd(LCD_con_t* lcon, uint32_t cmd, uint32_t arg); +am18x_rt lcd_intr_enable(LCD_con_t* lcon, uint32_t intr); +am18x_rt lcd_intr_disable(LCD_con_t* lcon, uint32_t intr); +am18x_rt lcd_intr_clear(LCD_con_t* lcon, uint32_t intr); +am18x_bool lcd_intr_state(const LCD_con_t* lcon, uint32_t intr); + +#endif//__AM18X_LCD_H__ diff --git a/lib/am18x-lib/inc/am18x_lib.h b/lib/am18x-lib/inc/am18x_lib.h new file mode 100644 index 000000000..c4da65078 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_lib.h @@ -0,0 +1,84 @@ +// tary, 0:39 2012/12/23 + +#ifndef __AM18X_LIB_H__ +#define __AM18X_LIB_H__ + +#include "am18x_map.h" + +#ifdef _SYSCFG +#include "am18x_syscfg.h" +#endif + +#ifdef _PSC +#include "am18x_psc.h" +#endif + +#ifdef _I2C +#include "am18x_i2c.h" +#endif + +#ifdef _TIMER +#include "am18x_timer.h" +#endif + +#ifdef _UART +#include "am18x_uart.h" +#endif + +#ifdef _AINTC +#include "am18x_aintc.h" +#endif + +#ifdef _PLL +#include "am18x_pll.h" +#endif + +#ifdef _DCLK +#include "am18x_dclk.h" +#endif + +#ifdef _MPU +#include "am18x_mpu.h" +#endif + +#ifdef _GPIO +#include "am18x_gpio.h" +#endif + +#ifdef _PRU +#include "am18x_pru.h" +#endif + +#ifdef _EDMA +#include "am18x_edma.h" +#endif + +#ifdef _MMCSD +#include "am18x_mmcsd.h" +#endif + +#ifdef _RTC +#include "am18x_rtc.h" +#endif + +#ifdef _DDR +#include "am18x_ddr.h" +#endif + +#ifdef _LCD +#include "am18x_lcd.h" +#endif + +#ifdef _USB +#include "am18x_usb.h" +#endif + +#ifdef _ECAP +#include "am18x_ecap.h" +#endif + +#ifdef _EMAC +#include "am18x_emac.h" +#endif + +#endif//__AM18X_LIB_H__ diff --git a/lib/am18x-lib/inc/am18x_map.h b/lib/am18x-lib/inc/am18x_map.h new file mode 100644 index 000000000..aec8ae425 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_map.h @@ -0,0 +1,3189 @@ +// tary, 23:18 2012/12/16 + +#ifndef __AM18X_MAP_H__ +#define __AM18X_MAP_H__ + +#ifndef _EXTERN +#define _EXTERN extern +#endif + +#include "am18x_type.h" +#include "am18x_conf.h" + +/*----------------------------------------------------------------------------*/ +// Peripheral register structures +/*----------------------------------------------------------------------------*/ + +#define _RS(b,a) (((b) - (a) - 0x4UL) >> 2) + + +/*----------------------------------------------------------------------------*/ +// Memory Protection Unit(MPU) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define MPU1_PROGxMPxAR_MASK 0xFFFFFC00UL +#define MPU2_PROGxMPxAR_MASK 0xFFFF0000UL + vuint32_t MPSAR; + vuint32_t MPEAR; +// n = 0..11 +#define PROGxMPPA_AIDn_MASK(n) (0x1UL << (10 + (n))) +#define PROGxMPPA_AIDn_denied(n) (0x0UL << (10 + (n))) +#define PROGxMPPA_AIDn_granted(n) (0x1UL << (10 + (n))) + vuint32_t MPPA; + uint32_t RESERVED0; +} MPU_range_t; + +typedef struct { +#define MPU_REVID 0x4E810101UL + vcuint32_t REVID; +#define CONFIG_ADDR_WIDTH_MASK (0xFFUL << 24) +#define CONFIG_NUM_FIXED_MASK (0xFUL << 20) +#define CONFIG_NUM_PROG_MASK (0xFUL << 16) +#define CONFIG_NUM_AIDS_MASK (0xFUL << 12) +#define CONFIG_ASSUME_ALLOWED_MASK (0x1UL << 0) +#define CONFIG_ASSUME_ALLOWED_no (0x0UL << 0) +#define CONFIG_ASSUME_ALLOWED_yes (0x1UL << 0) + vcuint32_t CONFIG; + uint32_t RESERVED0[_RS(0x010,0x004)]; + vuint32_t IRAWSTAT; + vuint32_t IENSTAT; + vuint32_t IENSET; + vuint32_t IENCLR; + uint32_t RESERVED1[_RS(0x100,0x01C)]; + // only valid in MPU2 +#define FXD_MPSAR_VAL 0xB0000000UL +#define FXD_MPEAR_VAL 0xB0007FFFUL + MPU_range_t FXD; + uint32_t RESERVED2[_RS(0x200,0x10C)]; + MPU_range_t PROGx[1]; + uint32_t RESERVED3[_RS(0x300,0x20C)]; + vcuint32_t FLTADDRR; +#define FLTSTAT_MSTID_MASK (0xFFUL << 16) +#define FLTSTAT_PRIVID_MASK (0xFUL << 9) +#define FLTSTAT_TYPE_MASK (0x3FUL << 0) +#define FLTSTAT_TYPE_NoFault (0x0UL << 0) +#define FLTSTAT_TYPE_UserExecute (0x1UL << 0) +#define FLTSTAT_TYPE_UserWrite (0x2UL << 0) +#define FLTSTAT_TYPE_UserRead (0x4UL << 0) +#define FLTSTAT_TYPE_SupervisorExecute (0x8UL << 0) +#define FLTSTAT_TYPE_SupervisorWrite (0x10UL << 0) +#define FLTSTAT_TYPE_CacheWriteBack (0x12UL << 0) +#define FLTSTAT_TYPE_SupervisorRead (0x20UL << 0) +#define FLTSTAT_TYPE_CacheLineFill (0x3FUL << 0) + vcuint32_t FLTSTAT; + vcuint32_t FLTCLR; +} MPU_con_t; + +enum { + BIT_DEF(PROGxMPPA,9,AIDX,denied,granted), + BIT_DEF(PROGxMPPA,5,SR,denied,allowed), + BIT_DEF(PROGxMPPA,4,SW,denied,allowed), + BIT_DEF(PROGxMPPA,3,SX,denied,allowed), + BIT_DEF(PROGxMPPA,2,UR,denied,allowed), + BIT_DEF(PROGxMPPA,1,UW,denied,allowed), + BIT_DEF(PROGxMPPA,0,UX,denied,allowed), + BIT_DEF(FLTCLR,0,CLEAR,none,fault), +}; + + +/*----------------------------------------------------------------------------*/ +// Phase-Locked Loop(PLL) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define PLL0_REVID 0x44813C00UL +#define PLL1_REVID 0x44814400UL + vcuint32_t REVID; + uint32_t RESERVED0[_RS(0xE4,0x0)]; +#define RSTYPE_PLLSWRST_MASK (0x1UL << 2) +#define RSTYPE_PLLSWRST_no (0x0UL << 2) +#define RSTYPE_PLLSWRST_yes (0x1UL << 2) +#define RSTYPE_XWRST_MASK (0x1UL << 1) +#define RSTYPE_XWRST_no (0x0UL << 1) +#define RSTYPE_XWRST_yes (0x1UL << 1) +#define RSTYPE_POR_MASK (0x1UL << 0) +#define RSTYPE_POR_no (0x0UL << 0) +#define RSTYPE_POR_yes (0x1UL << 0) + vcuint32_t RSTYPE; +#define RSCTRL_SWRST_MASK (0x1UL << 16) +#define RSCTRL_SWRST_yes (0x0UL << 16) +#define RSCTRL_SWRST_no (0x1UL << 16) +#define RSCTRL_KEY_MASK (0xFFFFUL << 0) +#define RSCTRL_KEY_locked (0x3UL << 0) +#define RSCTRL_KEY_unlocked (0xCUL << 0) +#define RSCTRL_KEY_unlock (0x5A69UL << 0) + vuint32_t RSCTRL; + uint32_t RESERVED1[_RS(0x100,0xE8)]; +#define PLLCTL_EXTCLKSRC_MASK (0x1UL << 9) +#define PLLCTL_EXTCLKSRC_oscin (0x0UL << 9) +#define PLLCTL_EXTCLKSRC_PLL1sysclk3 (0x1UL << 9) +#define PLLCTL_CLKMODE_MASK (0x1UL << 8) +#define PLLCTL_CLKMODE_crystal (0x0UL << 8) +#define PLLCTL_CLKMODE_wave (0x1UL << 8) +#define PLLCTL_PLLENSRC_MASK (0x1UL << 5) +#define PLLCTL_PLLENSRC_cleared (0x0UL << 5) +#define PLLCTL_PLLENSRC_none (0x1UL << 5) +#define PLLCTL_PLLRST_MASK (0x1UL << 3) +#define PLLCTL_PLLRST_asserted (0x0UL << 3) +#define PLLCTL_PLLRST_deasserted (0x1UL << 3) +#define PLLCTL_PLLPWRDN_MASK (0x1UL << 1) +#define PLLCTL_PLLPWRDN_no (0x0UL << 1) +#define PLLCTL_PLLPWRDN_yes (0x1UL << 1) +#define PLLCTL_PLLEN_MASK (0x1UL << 0) +#define PLLCTL_PLLEN_no (0x0UL << 0) +#define PLLCTL_PLLEN_yes (0x1UL << 0) + vuint32_t PLLCTL; +#define OCSEL_OCSRC_MASK (0x1FUL << 0) +#define OCSEL_OCSRC_oscin (0x14UL << 0) +// PLL0 x = 1..7 +// PLL1 x = 1..3 +#define OCSEL_OCSRC_PLLsysclkx(x) ((0x16UL + (x)) << 0) +#define OCSEL_OCSRC_PLL1obsclk (0x1EUL << 0) +#define OCSEL_OCSRC_Disabled (0x1FUL << 0) + vuint32_t OCSEL; + uint32_t RESERVED2[_RS(0x110,0x104)]; +#define PLLM_MASK (0x1FUL << 0) +#define PLLM_WR(m) (((m) - 0x1UL) << 0) + vuint32_t PLLM; +// XXXDIVx include PREDIV, PLLDIV1, PLLDIV2, PLLDIV3, +// PLLDIV4, PLLDIV5, PLLDIV6, PLLDIV7, +// OSCDIV, POSTDIV +#define XXXDIVx_DxEN_MASK (0x1UL << 15) +#define XXXDIVx_DxEN_disable (0x0UL << 15) +#define XXXDIVx_DxEN_enable (0x1UL << 15) +#define XXXDIVx_RATIO_MASK (0x1FUL << 0) +#define XXXDIVx_RATIO_WR(r) (((r) - 0x1UL) << 0) + vuint32_t PREDIV; +// PLLDIVxA_IDX include PLLDIV1, PLLDIV2, PLLDIV3 +#define PLLDIVxA_IDX_1 0x0 +#define PLLDIVxA_IDX_2 0x1 +#define PLLDIVxA_IDX_3 0x2 + vuint32_t PLLDIVxA[3]; + vuint32_t OSCDIV; + vuint32_t POSTDIV; + uint32_t RESERVED3[_RS(0x138,0x128)]; +#define PLLCMD_GOSET_MASK (0x1UL << 0) +#define PLLCMD_GOSET_clear (0x0UL << 0) +#define PLLCMD_GOSET_initiate (0x1UL << 0) + vuint32_t PLLCMD; +#define PLLSTAT_STABLE_MASK (0x1UL << 2) +#define PLLSTAT_STABLE_no (0x0UL << 2) +#define PLLSTAT_STABLE_yes (0x1UL << 2) +#define PLLSTAT_GOSTAT_MASK (0x1UL << 0) +#define PLLSTAT_GOSTAT_done (0x0UL << 0) +#define PLLSTAT_GOSTAT_in_progress (0x1UL << 0) + vcuint32_t PLLSTAT; +// PLL0 x = 1..7 +// PLL1 x = 1..3 +#define ALNCTL_ALNx_MASK(x) (0x1UL << ((x) - 1)) +#define ALNCTL_ALNx_no(x) (0x0UL << ((x) - 1)) +#define ALNCTL_ALNx_yes(x) (0x1UL << ((x) - 1)) + vuint32_t ALNCTL; +// PLL0 x = 1..7 +// PLL1 x = 1..3 +#define DCHANGE_SYSx_MASK(x) (0x1UL << ((x) - 1)) +#define DCHANGE_SYSx_none(x) (0x0UL << ((x) - 1)) +#define DCHANGE_SYSx_modified(x) (0x1UL << ((x) - 1)) + vcuint32_t DCHANGE; +#define CKEN_OBSEN_MASK (0x1UL << 1) +#define CKEN_OBSEN_disable (0x0UL << 1) +#define CKEN_OBSEN_enable (0x1UL << 1) +#define CKEN_AUXEN_MASK (0x1UL << 0) +#define CKEN_AUXEN_disable (0x0UL << 0) +#define CKEN_AUXEN_enable (0x1UL << 0) + vuint32_t CKEN; +#define CKSTAT_OBSEN_MASK (0x1UL << 1) +#define CKSTAT_OBSEN_off (0x0UL << 1) +#define CKSTAT_OBSEN_on (0x1UL << 1) +#define CKSTAT_AUXEN_MASK (0x1UL << 0) +#define CKSTAT_AUXEN_off (0x0UL << 0) +#define CKSTAT_AUXEN_on (0x1UL << 0) + vcuint32_t CKSTAT; +// PLL0 x = 1..7 +// PLL1 x = 1..3 +#define SYSTAT_SYSxON_MASK(X) (0x1UL << ((x) - 1)) +#define SYSTAT_SYSxON_off(x) (0x0UL << ((x) - 1)) +#define SYSTAT_SYSxON_on(x) (0x1UL << ((x) - 1)) + vcuint32_t SYSTAT; + uint32_t RESERVED4[_RS(0x160,0x150)]; +// PLLDIVxB_IDX include PLLDIV4, PLLDIV5, PLLDIV6, PLLDIV7 +#define PLLDIVxB_IDX_4 0x0 +#define PLLDIVxB_IDX_5 0x1 +#define PLLDIVxB_IDX_6 0x2 +#define PLLDIVxB_IDX_7 0x3 + vuint32_t PLLDIVxB[4]; + uint32_t RESERVED5[_RS(0x1F0,0x16C)]; + vuint32_t EMUCNTx[2]; +} PLL_con_t; + + +/*----------------------------------------------------------------------------*/ +// Power and Sleep Controller(PSC) +/*----------------------------------------------------------------------------*/ +#define MODULE_NR_PER_PSC 32 +typedef enum { + PSC_EDMA3_0_C0 = MODULE_NR_PER_PSC * 0, + PSC_EDMA3_0_T0, + PSC_EDMA3_0_T1, + PSC_EMIFA, + PSC_SPI0, + PSC_MMC_SD0, + PSC_ARM_INTC, + PSC_ARM_RAM_ROM, + PSC_RESERVED0, + PSC_UART0, + PSC_SCR0, + PSC_SCR1, + PSC_SCR2, + PSC_PRU, + PSC_ARM, + PSC_RESERVED1, + PSC_EDMA3_1_C0 = MODULE_NR_PER_PSC * 1, + PSC_USB0, + PSC_USB1, + PSC_GPIO, + PSC_HPI, + PSC_EMAC, + PSC_DDR2, + PSC_MCASP0, + PSC_SATA, + PSC_VPIF, + PSC_SPI1, + PSC_I2C1, + PSC_UART1, + PSC_UART2, + PSC_MCBSP0, + PSC_MCBSP1, + PSC_LCDC, + PSC_EHRPWM, + PSC_MMC_SD1, + PSC_UPP, + PSC_ECAP, + PSC_EDMA3_1_T0, + PSC_RESERVED2, + PSC_RESERVED3, + PSC_SCR_F0, + PSC_SCR_F1, + PSC_SCR_F2, + PSC_SCR_F6, + PSC_SCR_F7, + PSC_SCR_F8, + PSC_BR_F7, + PSC_ON_CHIP_RAM, +} psc_module_t; + + +typedef struct { +#define PSC_REVID 0x44825A00UL + vcuint32_t REVID; + uint32_t RESERVED0[5]; + vuint32_t INTEVAL; + uint32_t RESERVED1[9]; + vcuint32_t MERRPR0; + uint32_t RESERVED2[3]; + vuint32_t MERRCR0; + uint32_t RESERVED3[3]; + vcuint32_t PERRPR; + uint32_t RESERVED4; + vuint32_t PERRCR; + uint32_t RESERVED5[45]; +#define PTCMD_GO1 (0x1UL << 1) +#define PTCMD_GO0 (0x1UL << 0) + vuint32_t PTCMD; + uint32_t RESERVED6; +#define PTSTAT_GO1_MASK (0x1UL << 1) +#define PTSTAT_GO1_no (0x0UL << 1) +#define PTSTAT_GO1_yes (0x1UL << 1) +#define PTSTAT_GO0_MASK (0x1UL << 0) +#define PTSTAT_GO0_no (0x0UL << 0) +#define PTSTAT_GO0_yes (0x1UL << 0) + vcuint32_t PTSTAT; + uint32_t RESERVED7[53]; +#define PDSTATx_EMUIHB_MASK (0x1UL << 11) +#define PDSTATx_EMUIHB_unactive (0x0UL << 11) +#define PDSTATx_EMUIHB_active (0x1UL << 11) +#define PDSTATx_PORDONE_MASK (0x1UL << 9) +#define PDSTATx_PORDONE_no (0x0UL << 9) +#define PDSTATx_PORDONE_yes (0x1UL << 9) +#define PDSTATx_POR_MASK (0x1UL << 8) +#define PDSTATx_POR_asserted (0x0UL << 8) +#define PDSTATx_POR_deasserted (0x1UL << 8) +#define PDSTATx_STATE_MASK (0x1FUL << 0) +#define PDSTATx_STATE_off (0x0UL << 0) +#define PDSTATx_STATE_on (0x1UL << 0) +#define PDSTATx_STATE_in_transition(x) (0x10UL <= (x) && (x) <= 0x1AUL) + vcuint32_t PDSTAT0; + vcuint32_t PDSTAT1; + uint32_t RESERVED8[62]; +#define PDCTLx_WAKECNT_MASK (0xFFUL << 16) +#define PDCTLx_GOOD2ACCESS_MASK (0xFUL << 20) +#define PDCTLx_ON2GOOD_MASK (0xFUL << 16) +#define PDCTLx_PDMODE_MASK (0xFUL << 12) +#define PDCTLx_PDMODE_on (0xFUL << 12) +#define PDCTLx_EMUIHBIE_MASK (0x1UL << 9) +#define PDCTLx_EMUIHBIE_disable (0x0UL << 9) +#define PDCTLx_EMUIHBIE_enable (0x1UL << 9) +#define PDCTLx_NEXT_MASK (0x1UL << 0) +#define PDCTLx_NEXT_off (0x0UL << 0) +#define PDCTLx_NEXT_on (0x1UL << 0) + vuint32_t PDCTL0; + vuint32_t PDCTL1; + uint32_t RESERVED9[62]; +#define PDCFGx_PD_LOCK_MASK (0x1UL << 3) +#define PDCFGx_PD_LOCK_locked (0x0UL << 3) +#define PDCFGx_PD_LOCK_unlocked (0x1UL << 3) +#define PDCFGx_ICEPICK_MASK (0x1UL << 2) +#define PDCFGx_ICEPICK_unpresent (0x0UL << 2) +#define PDCFGx_ICEPICK_present (0x1UL << 2) +#define PDCFGx_RAM_PSM_MASK (0x1UL << 1) +#define PDCFGx_RAM_PSM_no (0x0UL << 1) +#define PDCFGx_RAM_PSM_yes (0x1UL << 1) +#define PDCFGx_ALWAYSON_MASK (0x1UL << 0) +#define PDCFGx_ALWAYSON_no (0x0UL << 0) +#define PDCFGx_ALWAYSON_yes (0x1UL << 0) + vcuint32_t PDCFG0; + vcuint32_t PDCFG1; + uint32_t RESERVED10[254]; +#define MDSTATx_EMUIHB_MASK (0x1UL << 17) +#define MDSTATx_EMUIHB_no (0x0UL << 17) +#define MDSTATx_EMUIHB_yes (0x1UL << 17) +#define MDSTATx_EMURST_MASK (0x1UL << 16) +#define MDSTATx_EMURST_no (0x0UL << 16) +#define MDSTATx_EMURST_yes (0x1UL << 16) +#define MDSTATx_MCKOUT_MASK (0x1UL << 12) +#define MDSTATx_MCKOUT_off (0x0UL << 12) +#define MDSTATx_MCKOUT_on (0x1UL << 12) +#define MDSTATx_MRST_MASK (0x1UL << 10) +#define MDSTATx_MRST_asserted (0x0UL << 10) +#define MDSTATx_MRST_deasserted (0x1UL << 10) +#define MDSTATx_LRSTDONE_MASK (0x1UL << 9) +#define MDSTATx_LRSTDONE_yes (0x0UL << 9) +#define MDSTATx_LRSTDONE_no (0x1UL << 9) +#define MDSTATx_LRST_MASK (0x1UL << 8) +#define MDSTATx_LRST_asserted (0x0UL << 8) +#define MDSTATx_LRST_deasserted (0x1UL << 8) +#define MDSTATx_STATE_MASK (0x3FUL << 0) +#define MDSTATx_STATE_SwRstDisable (0x0UL) +#define MDSTATx_STATE_SyncReset (0x1UL) +#define MDSTATx_STATE_Disable (0x2UL) +#define MDSTATx_STATE_Enable (0x3UL) +#define MDSTATx_STATE_in_transition(x) (0x4UL <= (x) && (x) <= 0x3FUL) + vcuint32_t MDSTATx[MODULE_NR_PER_PSC]; + uint32_t RESERVED11[96]; +#define MDCTLx_FORCE_MASK (0x1UL << 31) +#define MDCTLx_FORCE_disabled (0x0UL << 31) +#define MDCTLx_FORCE_enabled (0x1UL << 31) +#define MDCTLx_EMUIHBIE_MASK (0x1UL << 10) +#define MDCTLx_EMUIHBIE_disable (0x0UL << 10) +#define MDCTLx_EMUIHBIE_enable (0x1UL << 10) +#define MDCTLx_EMURSTIE_MASK (0x1UL << 9) +#define MDCTLx_EMURSTIE_disable (0x0UL << 9) +#define MDCTLx_EMURSTIE_enable (0x1UL << 9) +#define MDCTLx_LRST_MASK (0x1UL << 8) +#define MDCTLx_LRST_assert (0x0UL << 8) +#define MDCTLx_LRST_deassert (0x1UL << 8) +#define MDCTLx_STATE_MASK (0x7UL << 0) +#define MDCTLx_STATE_SwRstDisable (0x0UL << 0) +#define MDCTLx_STATE_SyncReset (0x1UL << 0) +#define MDCTLx_STATE_Disable (0x2UL << 0) +#define MDCTLx_STATE_Enable (0x3UL << 0) + vuint32_t MDCTLx[MODULE_NR_PER_PSC]; +} PSC_con_t; + + +/*----------------------------------------------------------------------------*/ +// System Configuration(SYSCFG) +/*----------------------------------------------------------------------------*/ +enum { + MSTPRI_ARM_I, + MSTPRI_ARM_D, + MSTPRI_Reserved0, + MSTPRI_Reserved1, + + MSTPRI_UPP, + MSTPRI_STAT, + MSTPRI_Reserved2, + MSTPRI_Reserved3, + + MSTPRI_PRU0, + MSTPRI_PRU1, + MSTPRI_EDMA30TC0, + MSTPRI_EDMA30TC1, + + MSTPRI_EDMA31TC0, + MSTPRI_Reserved4, + MSTPRI_VPIF_DMA_0, + MSTPRI_VPIF_DMA_1, + + MSTPRI_EMAC, + MSTPRI_Reserved5, + MSTPRI_USB0CFG, + MSTPRI_USB0CDMA, + + MSTPRI_Reserved6, + MSTPRI_UHPI, + MSTPRI_USB1, + MSTPRI_LCDC, +}; + +typedef struct { +#define SYSCFG0_REVID 0x4E840102UL + vcuint32_t REVID; + uint32_t RESERVED0; + vcuint32_t DIEIDRx[4]; + vcuint32_t REVIDR0; + uint32_t RESERVED1; +#define BOOTCFG_BOOTMODE_MASK 0x001FUL +#define BOOTCFG_BOOTMODE_I2C0EEPROM 0x00UL +#define BOOTCFG_BOOTMODE_I2C0SLAVE 0x01UL +#define BOOTCFG_BOOTMODE_NOR 0x02UL +#define BOOTCFG_BOOTMODE_HPI 0x04UL +#define BOOTCFG_BOOTMODE_I2C1EEPROM 0x06UL +#define BOOTCFG_BOOTMODE_I2C1SLAVE 0x07UL +#define BOOTCFG_BOOTMODE_SPI0EEPROM 0x08UL +#define BOOTCFG_BOOTMODE_SPI1EEPROM 0x09UL +#define BOOTCFG_BOOTMODE_SPI0FLASH 0x0AUL +#define BOOTCFG_BOOTMODE_SPI1FLASH 0x0CUL +#define BOOTCFG_BOOTMODE_NAND8 0x0EUL +#define BOOTCFG_BOOTMODE_NAND16 0x10UL +#define BOOTCFG_BOOTMODE_SPI0SLAVE 0x12UL +#define BOOTCFG_BOOTMODE_SPI1SLAVE 0x13UL +#define BOOTCFG_BOOTMODE_UART2 0x14UL +#define BOOTCFG_BOOTMODE_UART0 0x16UL +#define BOOTCFG_BOOTMODE_UART1 0x17UL +#define BOOTCFG_BOOTMODE_MMCSD0 0x1CUL +#define BOOTCFG_BOOTMODE_EMU 0x1EUL + vcuint32_t BOOTCFG; + uint32_t RESERVED2[5]; +#define KICK0R_UNLOCK 0x83E70B13UL +#define KICK0R_LOCK 0x00000000UL +#define KICK1R_UNLOCK 0x95A4F1E0UL +#define KICK1R_LOCK 0x00000000UL + vuint32_t KICKxR[2]; +#define HOST0CFG_BOOTRDY_MASK (0x1UL << 0) +#define HOST0CFG_BOOTRDY_reset (0x0UL << 0) +#define HOST0CFG_BOOTRDY_released (0x1UL << 0) + vuint32_t HOST0CFG; + uint32_t RESERVED3[39]; +#define IRAWSTAT_ADDRERR_MASK (0x1UL << 1) +#define IRAWSTAT_ADDRERR_unset (0x0UL << 1) +#define IRAWSTAT_ADDRERR_set (0x1UL << 1) +#define IRAWSTAT_PROTERR_MASK (0x1UL << 0) +#define IRAWSTAT_PROTERR_unset (0x0UL << 0) +#define IRAWSTAT_PROTERR_set (0x1UL << 0) + vuint32_t IRAWSTAT; +#define IENSTAT_ADDRERR_MASK (0x1UL << 1) +#define IENSTAT_ADDRERR_unset (0x0UL << 1) +#define IENSTAT_ADDRERR_set (0x1UL << 1) +#define IENSTAT_PROTERR_MASK (0x1UL << 0) +#define IENSTAT_PROTERR_unset (0x0UL << 0) +#define IENSTAT_PROTERR_set (0x1UL << 0) + vcuint32_t IENSTAT; +#define IENSET_ADDRERR_EN_enable (0x1UL << 1) +#define IENSET_PROTERR_EN_enable (0x1UL << 0) + vuint32_t IENSET; +#define IENCLR_ADDRERR_EN_enable (0x1UL << 1) +#define IENCLR_PROTERR_EN_enable (0x1UL << 0) + vuint32_t IENCLR; +#define EOI_EOIVECT_MASK (0xFFUL << 0) + vuint32_t EOI; + vcuint32_t FLTADDRR; +#define FLTSTAT_ID_MASK (0xFFUL << 24) + vcuint32_t FLTSTAT; + uint32_t RESERVED4[5]; +// Master Priority X +// x = 0..23 +#define MSTPRIx_IDX(x) ((x) >> 3) +#define MSTPRIx_MASK(x) (0x7UL << (((x) & 0x7UL) << 2)) + vuint32_t MSTPRIx[3]; + uint32_t RESERVED5; + vuint32_t PINMUXx[20]; + vuint32_t SUSPSRC; +#define CHIPSIG_X_MASK(i) (0x1UL << (i)) +#define CHIPSIG_X_assert(i) (0x1UL << (i)) +#define CHIPSIG_X_clear(i) (0x1UL << (i)) + vuint32_t CHIPSIG; + vuint32_t CHIPSIG_CLR; +#define CFGCHIP0_PLL_MASTER_LOCK_MASK (0x1UL << 4) +#define CFGCHIP0_PLL_MASTER_LOCK_no (0x0UL << 4) +#define CFGCHIP0_PLL_MASTER_LOCK_yes (0x1UL << 4) +// x = 0..1 +#define CFGCHIP0_EDMA30TCxDBS_MASK(x) (0x3UL << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_16B(x) (0x0UL << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_32B(x) (0x1UL << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_64B(x) (0x2UL << (2*(x))) + vuint32_t CFGCHIP0; +#define CFGCHIP1_EDMA31TC0DBS_MASK (0x3UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_16B (0x0UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_32B (0x1UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_64B (0x2UL << 13) + vuint32_t CFGCHIP1; +#define CFGCHIP2_USB0OTGMODE_MASK (0x3UL << 13) +#define CFGCHIP2_USB0OTGMODE_none (0x0UL << 13) +#define CFGCHIP2_USB0OTGMODE_host (0x1UL << 13) +#define CFGCHIP2_USB0OTGMODE_device (0x2UL << 13) +#define CFGCHIP2_USB0OTGMODE_VBUSlow (0x3UL << 13) +#define CFGCHIP2_USB0REFFREQ_MASK (0xFUL << 0) +#define CFGCHIP2_USB0REFFREQ_12MHz (0x1UL << 0) +#define CFGCHIP2_USB0REFFREQ_24MHz (0x2UL << 0) +#define CFGCHIP2_USB0REFFREQ_48MHz (0x3UL << 0) +#define CFGCHIP2_USB0REFFREQ_19_2MHz (0x4UL << 0) +#define CFGCHIP2_USB0REFFREQ_38_4MHz (0x5UL << 0) +#define CFGCHIP2_USB0REFFREQ_13MHz (0x6UL << 0) +#define CFGCHIP2_USB0REFFREQ_26MHz (0x7UL << 0) +#define CFGCHIP2_USB0REFFREQ_20MHz (0x8UL << 0) +#define CFGCHIP2_USB0REFFREQ_40MHz (0x9UL << 0) + vuint32_t CFGCHIP2; +#define CFGCHIP3_RMII_SEL_MASK (0x1UL << 8) +#define CFGCHIP3_RMII_SEL_mii (0x0UL << 8) +#define CFGCHIP3_RMII_SEL_rmii (0x1UL << 8) +#define CFGCHIP3_UPP_TX_CLKSRC_MASK (0x1UL << 6) +#define CFGCHIP3_UPP_TX_CLKSRC_asyn3 (0x0UL << 6) +#define CFGCHIP3_UPP_TX_CLKSRC_2xTXCLK (0x1UL << 6) +#define CFGCHIP3_PLL1_MASTER_LOCK_MASK (0x1UL << 5) +#define CFGCHIP3_PLL1_MASTER_LOCK_no (0x0UL << 5) +#define CFGCHIP3_PLL1_MASTER_LOCK_yes (0x1UL << 5) +#define CFGCHIP3_ASYNC3_CLKSRC_MASK (0x1UL << 4) +#define CFGCHIP3_ASYNC3_CLKSRC_pll0 (0x0UL << 4) +#define CFGCHIP3_ASYNC3_CLKSRC_pll1 (0x1UL << 4) +#define CFGCHIP3_PRUEVTSEL_MASK (0x1UL << 3) +#define CFGCHIP3_PRUEVTSEL_normal (0x0UL << 3) +#define CFGCHIP3_PRUEVTSEL_alternate (0x1UL << 3) +#define CFGCHIP3_DIV45PENA_MASK (0x1UL << 2) +#define CFGCHIP3_DIV45PENA_no (0x0UL << 2) +#define CFGCHIP3_DIV45PENA_yes (0x1UL << 2) +#define CFGCHIP3_EMA_CLKSRC_MASK (0x1UL << 1) +#define CFGCHIP3_EMA_CLKSRC_sysclk3 (0x0UL << 1) +#define CFGCHIP3_EMA_CLKSRC_pll_out (0x1UL << 1) + vuint32_t CFGCHIP3; +#define CFGCHIP4_AMUTECLR0_MASK (0x1UL << 0) +#define CFGCHIP4_AMUTECLR0_none (0x0UL << 0) +#define CFGCHIP4_AMUTECLR0_clr_int (0x1UL << 0) + vuint32_t CFGCHIP4; +} SYSCFG0_con_t; + +enum { + BIT_DEF(CFGCHIP2,17,USB0PHYCLKGD,no,yes), // Readonly + BIT_DEF(CFGCHIP2,16,USB0VBUSSENSE,no,yes), // Readonly + BIT_DEF(CFGCHIP2,15,RESET,no,yes), + BIT_DEF(CFGCHIP2,12,USB1PHYCLKMUX,USB0PHY,REFCLKIN), + BIT_DEF(CFGCHIP2,11,USB0PHYCLKMUX,REFCLKIN,AUXCLK), + BIT_DEF(CFGCHIP2,10,USB0PHYPWDN,none,down), + BIT_DEF(CFGCHIP2,9,USB0OTGPWRDN,none,down), + BIT_DEF(CFGCHIP2,8,USB0DATPOL,interted,none), + BIT_DEF(CFGCHIP2,7,USB1SUSPENDM,yes,no), + BIT_DEF(CFGCHIP2,6,USB0PHY_PLLON,no,yes), + BIT_DEF(CFGCHIP2,5,USB0SESNDEN,disabled,enabled), + BIT_DEF(CFGCHIP2,4,USB0VBDTCTEN,disabled,enabled), +}; + +typedef struct { +#define CFGCHIP1_EDMA31TC0DBS_MASK (0x3UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_16B (0x0UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_32B (0x1UL << 13) +#define CFGCHIP1_EDMA31TC0DBS_64B (0x2UL << 13) + +#define VTPIO_CTL_F_MASK (0x7UL << 0) +#define VTPIO_CTL_F_Enable (0x7UL << 0) +#define VTPIO_CTL_D_MASK (0x7UL << 3) +#define VTPIO_CTL_D_100PS (0x6UL << 3) +#define VTPIO_CTL_VREFTAP_MASK (0x3UL << 16) +#define VTPIO_CTL_VREFTAP_50PS (0x0UL << 16) + vuint32_t VTPIO_CTL; + vuint32_t DDR_SLEW; +#define DEEPSLEEP_SLEEPCOUNT_MASK (0xFFFFUL << 0) +#define DEEPSLEEP_SLEEPCOUNT_VAL(x) (((x) & 0xFFFFUL) << 0) + vuint32_t DEEPSLEEP; + vuint32_t PUPD_ENA; + vuint32_t PUPD_SEL; + vuint32_t RXACTIVE; + vuint32_t PWRDN; +} SYSCFG1_con_t; + +enum { + BIT_DEF(VTPIO_CTL,18,VREFEN,pad,none), + BIT_DEF(VTPIO_CTL,15,READY,no,yes), + BIT_DEF(VTPIO_CTL,14,IOPWRDN,no,yes), + BIT_DEF(VTPIO_CTL,13,CLKRZ,clear,none), + BIT_DEF(VTPIO_CTL,8,PWRSAVE,no,yes), + BIT_DEF(VTPIO_CTL,7,LOCK,no,yes), + BIT_DEF(VTPIO_CTL,6,POWERDN,no,yes), + BIT_DEF(DDR_SLEW,5,PDENA,no,yes), + BIT_DEF(DDR_SLEW,4,CMOSEN,SSTL,LVCMOS), + BIT_DEF(DEEPSLEEP,31,ENABLE,no,yes), + BIT_DEF(DEEPSLEEP,30,COMPLETE,no,yes), +}; + + +/*----------------------------------------------------------------------------*/ +// ARM Interrupt Controller(AINTC) +/*----------------------------------------------------------------------------*/ +typedef enum { + AINTC_COMMTX = 0, // 0 + AINTC_COMMRX, + AINTC_NINT, + AINTC_PRU_EVTOUT0, + AINTC_PRU_EVTOUT1, + + AINTC_PRU_EVTOUT2, + AINTC_PRU_EVTOUT3, + AINTC_PRU_EVTOUT4, + AINTC_PRU_EVTOUT5, + AINTC_PRU_EVTOUT6, + + AINTC_PRU_EVTOUT7, // 10 + AINTC_EDMA3_0_CC0_INT0, + AINTC_EDMA3_0_CC0_ERRINT, + AINTC_EDMA3_0_TC0_ERRINT, + AINTC_EMIFA_INT, + + AINTC_IIC0_INT, + AINTC_MMCSD0_INT0, + AINTC_MMCSD0_INT1, + AINTC_PSC0_ALLINT, + AINTC_RTC_IRQS_1_0, + + AINTC_SPI0_INT, // 20 + AINTC_T64P0_TINT12, + AINTC_T64P0_TINT32, + AINTC_T64P1_TINT12, + AINTC_T64P1_TINT34, + + AINTC_UART0_INT, + AINTC_RESERVED0, + AINTC_PROTERR, + AINTC_SYSCFG_CHIPINT0, + AINTC_SYSCFG_CHIPINT1, + + AINTC_SYSCFG_CHIPINT2, // 30 + AINTC_SYSCFG_CHIPINT3, + AINTC_EDMA3_0_TC1_ERRINT, + AINTC_EMAC_C0RXTHRESH, + AINTC_EMAC_C0RX, + + AINTC_EMAC_C0TX, + AINTC_EMAC_C0MISC, + AINTC_EMAC_C1RXTHRESH, + AINTC_EMAC_C1RX, + AINTC_EMAC_C1TX, + + AINTC_EMAC_C1MISC, // 40 + AINTC_DDR2_MEMERR, + AINTC_GPIO_B0INT, + AINTC_GPIO_B1INT, + AINTC_GPIO_B2INT, + + AINTC_GPIO_B3INT, + AINTC_GPIO_B4INT, + AINTC_GPIO_B5INT, + AINTC_GPIO_B6INT, + AINTC_GPIO_B7INT, + + AINTC_GPIO_B8INT, // 50 + AINTC_IIC1_INT, + AINTC_LCDC_INT, + AINTC_UART_INT1, + AINTC_MCASP_INT, + + AINTC_PSC1_ALLINT, + AINTC_SPI1_INT, + AINTC_UHPI_ARMINT, + AINTC_USB0_INT, + AINTC_USB1_HCINT, + + AINTC_USB1_R_WAKEUP, // 60 + AINTC_UART2_INT, + AINTC_RESERVED1, + AINTC_EHRPWM0, + AINTC_EHRPWM0TZ, + + AINTC_EHRPWM1, + AINTC_EHRPWM1TZ, + AINTC_SATA_INT, + AINTC_T64P2_ALL, + AINTC_ECAP0, + + AINTC_ECAP1, // 70 + AINTC_ECAP2, + AINTC_MMCSD1_INT0, + AINTC_MMCSD1_INT1, + AINTC_T64P2_CMPINT0, + + AINTC_T64P2_CMPINT1, + AINTC_T64P2_CMPINT2, + AINTC_T64P2_CMPINT3, + AINTC_T64P2_CMPINT4, + AINTC_T64P2_CMPINT5, + + AINTC_T64P2_CMPINT6, // 80 + AINTC_T64P2_CMPINT7, + AINTC_T64P3_CMPINT0, + AINTC_T64P3_CMPINT1, + AINTC_T64P3_CMPINT2, + + AINTC_T64P3_CMPINT3, + AINTC_T64P3_CMPINT4, + AINTC_T64P3_CMPINT5, + AINTC_T64P3_CMPINT6, + AINTC_T64P3_CMPINT7, + + AINTC_ARMCLKSTOPREQ, // 90 + AINTC_uPP_AlLINT, + AINTC_VPIF_ALLINT, + AINTC_EDMA3_1_CC0_INT0, + AINTC_EDMA3_1_CC0_ERRINT, + + AINTC_EDMA3_1_TC0_ERRINT, + AINTC_T64P3_ALL, + AINTC_MCBSP0_RINT, + AINTC_MCBSP0_XINT, + AINTC_MCBSP1_RINT, + + AINTC_MCBSP1_XINT, // 100 + AINTC_ASSIGN_CNT, +} AINTC_assign_t; + +typedef struct { + vcuint32_t REVID; +#define CR_PRHOLDMODE_MASK (0x1UL << 4) +#define CR_PRHOLDMODE_disable (0x0UL << 4) +#define CR_PRHOLDMODE_enable (0x1UL << 4) +#define CR_NESTMODE_MASK (0x3UL << 2) +#define CR_NESTMODE_None (0x0UL << 2) +#define CR_NESTMODE_Individual (0x1UL << 2) +#define CR_NESTMODE_Global (0x2UL << 2) +#define CR_NESTMODE_Manual (0x3UL << 2) + vuint32_t CR; + uint32_t RESERVED0[2]; +#define GER_ENABLE_MASK (0x1UL << 0) +#define GER_ENABLE_no (0x0UL << 0) +#define GER_ENABLE_yes (0x1UL << 0) + vuint32_t GER; + uint32_t RESERVED1[2]; +#define GNLR_OVERRIDE_SET (0x1UL << 31) +#define GNLR_NESTLVL_MASK (0xFFUL << 0) +#define GNLR_NESTLVL_VAL(x) ((x) << 0) + vuint32_t GNLR; +// AINTC_IDX_XX include SIxR, EIxR, HIEIxR +#define AINTC_IDX_SET 0x00 +#define AINTC_IDX_CLR 0x01 +#define XIxR_INDEX_MASK (0x7FUL << 0) +#define XIxR_INDEX_VAL(x) ((x) << 0) + vuint32_t SIxR[2]; + vuint32_t EIxR[2]; + uint32_t RESERVED2; +#define HIEIxR_INDEX_MASK (0x1UL << 0) +#define HIEIxR_INDEX_FIQ (0x0UL << 0) +#define HIEIxR_INDEX_IRQ (0x1UL << 0) + vuint32_t HIEIxR[2]; + uint32_t RESERVED3[5]; + vuint32_t VBR; +#define VSR_SIZE_MASK (0xFFUL << 0) +#define VSR_SIZE_VAL(x) (((x) >> 2) - 1) + vuint32_t VSR; + vuint32_t VNR; + uint32_t RESERVED4[9]; +#define GPIR_NONE_MASK (0x1UL << 31) +#define GPIR_NONE_no (0x0UL << 31) +#define GPIR_NONE_yes (0x1UL << 31) +#define GPIR_PRI_INDX_MASK (0x3FFUL << 0) + vcint32_t GPIR; + vuint32_t GPVR; + uint32_t RESERVED5[94]; +#define SXXRx_WR_X(x) ((x) >> 5) +#define SXXRx_WR_VAL(x) (0x1UL << ((x) & 0x1F)) + vuint32_t SRSRx[4]; + uint32_t RESERVED6[28]; + vuint32_t SECRx[4]; + uint32_t RESERVED7[28]; +#define EXRx_WR_X(x) ((x) >> 5) +#define EXRx_WR_VAL(x) (0x1UL << ((x) & 0x1F)) + vuint32_t ESRx[4]; + uint32_t RESERVED8[28]; + vuint32_t ECRx[4]; + uint32_t RESERVED9[28]; +#define CMRx_X(x) ((x) >> 2) +#define CMRx_MASK(x) (0xFFUL << (((x) & 0x3UL) << 3)) +#define CMRx_VAL(x,v) ((0xFFUL & (v)) << (((x) & 0x3UL) << 3)) + vuint32_t CMRx[26]; + uint32_t RESERVED10[294]; +// AINTC_IDX_XXX include HIPIRx, HINLRx, HIPVRx +#define AINTC_IDX_FIQ 0x00 +#define AINTC_IDX_IRQ 0x01 +#define HIPIRx_NONE_MASK (0x1UL << 31) +#define HIPIRx_NONE_no (0x0UL << 31) +#define HIPIRx_NONE_yes (0x1UL << 31) +#define HIPIRx_PRI_INDX_MASK (0x3FFUL << 0) + vuint32_t HIPIRx[2]; + uint32_t RESERVED11[510]; +#define HINLRx_OVERRIDE_SET (0x1UL << 31) +#define HINLRx_NEST_LVL_MASK (0x1FFUL << 0) + vuint32_t HINLRx[2]; + uint32_t RESERVED12[254]; +#define HIER_IRQ_MASK (0x1UL << 1) +#define HIER_IRQ_disabled (0x0UL << 1) +#define HIER_IRQ_enabled (0x1UL << 1) +#define HIER_FIQ_MASK (0x1UL << 0) +#define HIER_FIQ_disabled (0x0UL << 0) +#define HIER_FIQ_enabled (0x1UL << 0) + vuint32_t HIER; + uint32_t RESERVED13[63]; + vcuint32_t HIPVRx[2]; +} AINTC_con_t; + + +/*----------------------------------------------------------------------------*/ +// Programmable Real-Time Unit Subsystem(PRUSS) +/*----------------------------------------------------------------------------*/ +// refer to +// http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit +typedef struct { +#define CONTROL_PCRESETVAL_MASK (0xFFFFUL << 16) + vuint32_t CONTROL; +#define STATUS_PCOUNTER_MASK 0x0000FFFFUL + vcuint32_t STATUS; +#define WAKEUP_ENABLES_MASK(x) (0x1UL << (x)) +#define WAKEUP_ENABLES_no(x) (0x0UL << (x)) +#define WAKEUP_ENABLES_yes(x) (0x1UL << (x)) + vuint32_t WAKEUP; + vuint32_t CYCLECNT; + vcuint32_t STALLCNT; + uint32_t RESERVED0[_RS(0x020, 0x010)]; +// C25[8 - 11] +#define CONTABBLKIDX0_C25_MASK (0xFUL << 16) +// C24[8 - 11] +#define CONTABBLKIDX0_C24_MASK (0xFUL << 0) + vuint32_t CONTABBLKIDX0; + uint32_t RESERVED1; +#define CONTABPROPTR_C29_MASK (0xFFFFUL << 16) +#define CONTABPROPTR_C28_MASK (0xFFFFUL << 0) +#define CONTABPROPTR_C31_MASK (0xFFFFUL << 16) +#define CONTABPROPTR_C30_MASK (0xFFFFUL << 0) + vuint32_t CONTABPROPTR[2]; + uint32_t RESERVED2[_RS(0x400, 0x02C)]; + vuint32_t INTGPR[32]; + vcuint32_t INTCTER[32]; +} PRU_con_t; + +enum { + BIT_DEF(CONTROL,15,RUNSTATE,halted,running), + BIT_DEF(CONTROL,8,SINGLESTEP,no,yes), + BIT_DEF(CONTROL,3,COUNTENABLE,no,yes), + BIT_DEF(CONTROL,2,SLEEPING,no,yes), + BIT_DEF(CONTROL,1,ENABLE,no,yes), + BIT_DEF(CONTROL,0,SOFTRESET,yes,no), +}; + + +/*----------------------------------------------------------------------------*/ +// DDR2/mDDR Memory Controller(DDR) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define DDR0_REVID (0x40311B1FUL) + vcuint32_t REVID; + vcuint32_t SDRSTAT; +#define SDCR_DDR2TERM_MASK ((0x1UL << 27) | (0x1UL << 21)) +#define SDCR_DDR2TERM_disable (0x0UL) +#define SDCR_DDR2TERM_default (0x1UL << 27) +#define SDCR_DDRDRIVE_MASK ((0x1UL << 24) | (0x1UL << 18)) +#define SDCR_DDRDRIVE_full ((0x0UL << 24) | (0x0UL << 18)) +#define SDCR_DDRDRIVE_half ((0x0UL << 24) | (0x1UL << 18)) +#define SDCR_DDRDRIVE_quarter ((0x1UL << 24) | (0x0UL << 18)) +#define SDCR_DDRDRIVE_3quarter ((0x1UL << 24) | (0x1UL << 18)) +#define SDCR_CL_MASK (0x7UL << 9) +// x = 2..5 +#define SDCR_CL_VAL(x) ((x) << 9) +#define SDCR_IBANK_MASK (0x7UL << 4) +#define SDCR_IBANK_1bank (0x0UL << 4) +#define SDCR_IBANK_2banks (0x1UL << 4) +#define SDCR_IBANK_4banks (0x2UL << 4) +#define SDCR_IBANK_8banks (0x3UL << 4) +#define SDCR_PAGESIZE_MASK (0x7UL << 0) +#define SDCR_PAGESIZE_256w8col (0x0UL << 0) +#define SDCR_PAGESIZE_512w9col (0x1UL << 0) +#define SDCR_PAGESIZE_1kw10col (0x2UL << 0) +#define SDCR_PAGESIZE_2kw11col (0x3UL << 0) + vuint32_t SDCR; +#define SDRCR_RR_MASK (0xFFFFUL << 0) +#define SDRCR_RR_VAL(x) ((x) << 0) + vuint32_t SDRCR; +#define SDTIMR1_TRFC_MASK (0x7UL << 25) +#define SDTIMR1_TRFC_VAL(x) ((x) << 25) +#define SDTIMR1_TRP_MASK (0x7UL << 22) +#define SDTIMR1_TRP_VAL(x) ((x) << 22) +#define SDTIMR1_TRCD_MASK (0x7UL << 19) +#define SDTIMR1_TRCD_VAL(x) ((x) << 19) +#define SDTIMR1_TWR_MASK (0x7UL << 16) +#define SDTIMR1_TWR_VAL(x) ((x) << 16) +#define SDTIMR1_TRAS_MASK (0x1FUL << 11) +#define SDTIMR1_TRAS_VAL(x) ((x) << 11) +#define SDTIMR1_TRC_MASK (0x1FUL << 6) +#define SDTIMR1_TRC_VAL(x) ((x) << 6) +#define SDTIMR1_TRRD_MASK (0x7UL << 3) +#define SDTIMR1_TRRD_VAL(x) ((x) << 3) +#define SDTIMR1_TWTR_MASK (0x3UL << 0) +#define SDTIMR1_TWTR_VAL(x) ((x) << 0) + vuint32_t SDTIMR1; +#define SDTIMR2_TRASMAX_MASK (0xFUL << 27) +#define SDTIMR2_TRASMAX_VAL(x) ((x) << 27) +#define SDTIMR2_TXP_MASK (0x3UL << 25) +#define SDTIMR2_TXP_VAL(x) ((x) << 25) +#define SDTIMR2_TODT_MASK (0x3UL << 23) +#define SDTIMR2_TODT_VAL(x) ((x) << 23) +#define SDTIMR2_TXSNR_MASK (0x7FUL << 16) +#define SDTIMR2_TXSNR_VAL(x) ((x) << 16) +#define SDTIMR2_TXSRD_MASK (0xFFUL << 8) +#define SDTIMR2_TXSRD_VAL(x) ((x) << 8) +#define SDTIMR2_TRTP_MASK (0x7UL << 5) +#define SDTIMR2_TRTP_VAL(x) ((x) << 5) +#define SDTIMR2_TCKE_MASK (0x1FUL << 0) +#define SDTIMR2_TCKE_VAL(x) ((x) << 0) + vuint32_t SDTIMR2; + uint32_t RESERVED0[_RS(0x1C, 0x14)]; +#define SDCR2_PASR_MASK (0x7UL << 16) +#define SDCR2_PASR_4banks (0x0UL << 16) +#define SDCR2_PASR_2banks (0x1UL << 16) +#define SDCR2_PASR_1banks (0x2UL << 16) +#define SDCR2_PASR_half_bank (0x5UL << 16) +#define SDCR2_PASR_quarter_bank (0x6UL << 16) +#define SDCR2_ROWSIZE_MASK (0x7UL << 0) +// x = 9..16 +#define SDCR2_ROWSIZE_VAL(x) (((x) - 9) << 0) + vuint32_t SDCR2; +#define PBBPR_PROLDCOUNT_MASK (0xFFUL << 0) +// x = 1..256 +#define PBBPR_PROLDCOUNT_VAL(x) (((x) - 1) << 0) + vuint32_t PBBPR; + uint32_t RESERVED1[_RS(0x40, 0x20)]; + vuint32_t PC1; + vuint32_t PC2; +#define PCC_CNTR2CFG_MASK (0xFUL << 16) +#define PCC_CNTR2CFG_VAL(x) ((x) << 16) +#define PCC_CNTR1CFG_MASK (0xFUL << 0) +#define PCC_CNTR1CFG_VAL(x) ((x) << 0) + vuint32_t PCC; +#define PCMRS_MSTID2_MASK (0xFFUL << 24) +#define PCMRS_MSTID2_VAL(x) ((x) << 24) +#define PCMRS_REGIONSEL2_MASK (0xFUL << 16) +#define PCMRS_REGIONSEL2_access (0x0UL << 16) +#define PCMRS_REGIONSEL2_register (0x7UL << 16) +#define PCMRS_MSTID1_MASK (0xFFUL << 8) +#define PCMRS_MSTID1_VAL(x) ((x) << 8) +#define PCMRS_REGIONSEL1_MASK (0xFUL << 0) +#define PCMRS_REGIONSEL1_access (0x0UL << 0) +#define PCMRS_REGIONSEL1_register (0x7UL << 0) + vuint32_t PCMRS; + vuint32_t PCT; + uint32_t RESERVED2[_RS(0x60, 0x50)]; + vuint32_t DRPYRCR; + uint32_t RESERVED3[_RS(0xC0, 0x60)]; + vuint32_t IRR; + vuint32_t IMR; + vuint32_t IMSR; + vuint32_t IMCR; + uint32_t RESERVED4[_RS(0xE4, 0xCC)]; +#define DRPYC1R_RL_MASK (0x7UL << 0) +#define DRPYC1R_RL_VAL(x) ((x) << 0) + vuint32_t DRPYC1R; +} DDR_con_t; + +enum { + BIT_DEF(SDRSTAT,30,DUALCLK,none,async), + BIT_DEF(SDRSTAT,2,PHYRDY,no,yes), + BIT_DEF(SDCR,26,IBANKPOS,normal,special), + BIT_DEF(SDCR,25,MSDRAMEN,no,yes), + BIT_DEF(SDCR,23,BOOTUNLOCK,none,unlock), + BIT_DEF(SDCR,22,DDR2DDQS,single,none), + BIT_DEF(SDCR,20,DDR2EN,no,yes), + BIT_DEF(SDCR,19,DDRDLLDIS,no,yes), + BIT_DEF(SDCR,17,DDREN,no,yes), + BIT_DEF(SDCR,16,SDRAMEN,no,yes), + BIT_DEF(SDCR,15,TIMUNLOCK,none,unlock), + BIT_DEF(SDCR,14,NM,none,16bit), + BIT_DEF(SDRCR,31,LPMODEN,no,yes), + BIT_DEF(SDRCR,30,MCLKSTOPEN,no,yes), + BIT_DEF(SDRCR,23,SRPD,selfrefresh,powerdown), + BIT_DEF(PCC,31,CNTR2MSTIDEN,no,yes), + BIT_DEF(PCC,30,CNTR2REGIONEN,no,yes), + BIT_DEF(PCC,15,CNTR1MSTIDEN,no,yes), + BIT_DEF(PCC,14,CNTR1REGIONEN,no,yes), + BIT_DEF(DRPYRCR,10,RESETPHY,none,reset), + BIT_DEF(IRR,2,LT,none,illegal), + BIT_DEF(IMR,2,LTM,none,illegal), + BIT_DEF(IMSR,2,LTMSET,none,set), + BIT_DEF(IMCR,2,LTMCLR,none,clear), + BIT_DEF(DRPYC1R,7,EXTSTRBEN,internal,external), + BIT_DEF(DRPYC1R,6,PWRDNEN,powerup,powerdown), +}; + + +/*----------------------------------------------------------------------------*/ +// Enhanced Capture(eCAP) Module +/*----------------------------------------------------------------------------*/ +enum { + CAPx_CAP1 = 0, + CAPx_CAP2 = 1, + CAPx_CAP3 = 2, + CAPx_CAP4 = 3, + CAPx_ECCTL1 = 0, + CAPx_ECCTL2, + CAPx_APRD_active = 0, + CAPx_ACMP_active, + CAPx_APRD, + CAPx_ACMP, + ECEINT_EVT1 = 1, + ECEINT_EVT2, + ECEINT_EVT3, + ECEINT_EVT4, + ECEINT_CTROVF, + ECEINT_CTR_EQU_PRD, + ECEINT_CTR_EQU_CMP, +}; + +typedef struct { + vuint32_t TSCTR; + vuint32_t CTRPHS; + vuint32_t CAPx[4]; + uint32_t RESERVED0[_RS(0x28,0x14)]; +#define ECCTL1_FREESOFT_MASK (0x3UL << 14) +#define ECCTL1_FREESOFT_stop (0x0UL << 14) +#define ECCTL1_FREESOFT_runs (0x1UL << 14) +#define ECCTL1_FREESOFT_none (0x3UL << 14) +#define ECCTL1_PRESCALE_MASK (0x1FUL << 9) +#define ECCTL1_PRESCALE_VAL(x) (((x) & 0x3EUL) << 8) +#define ECCTL1_CTRRSTx_MASK(x) (0x1UL << (((x) << 1) + 1)) +#define ECCTL1_CTRRSTx_none(x) (0x0UL << (((x) << 1) + 1)) +#define ECCTL1_CTRRSTx_reset(x) (0x1UL << (((x) << 1) + 1)) +#define ECCTL1_CTRPOLx_MASK(x) (0x1UL << (((x) << 1) + 0)) +#define ECCTL1_CTRPOLx_rising(x) (0x0UL << (((x) << 1) + 0)) +#define ECCTL1_CTRPOLx_falling(x) (0x1UL << (((x) << 1) + 0)) +#define ECCTL2_SYNCO_SEL_MASK (0x3UL << 6) +#define ECCTL2_SYNCO_SEL_pass (0x0UL << 6) +#define ECCTL2_SYNCO_SEL_ctr_equ_prd (0x1UL << 6) +#define ECCTL2_SYNCO_SEL_disable (0x2UL << 6) +#define ECCTL2_STOP_WARP_MASK (0x3UL << 1) +#define ECCTL2_STOP_WARP_VAL(x) ((x) << 1) + vuint16_t ECCTLx[2]; +#define ECINT_MASK(x) (0x1UL << (x)) +#define ECINT_deassert(x) (0x0UL << (x)) +#define ECINT_assert(x) (0x1UL << (x)) + vuint16_t ECEINT; + vcuint16_t ECFLG; + // writing 0 no effect, include ECCLR,ECFRC + vuint16_t ECCLR; + vuint16_t ECFRC; +#define ECAP_REVID 0x44D22100UL + vcuint32_t REVID; +} ECAP_con_t; + +enum { + BIT_DEF(ECCTL1,8,CAPLDEN,no,yes), + BIT_DEF(ECCTL2,10,APWMPOL,high,low), + BIT_DEF(ECCTL2,9,operating,capture,APWM), + BIT_DEF(ECCTL2,8,SWSYNC,none,load), + BIT_DEF(ECCTL2,5,SYNCI_EN,no,yes), + BIT_DEF(ECCTL2,4,TSCTRSTOP,yes,no), + BIT_DEF(ECCTL2,3,RE_ARM,none,arm), + BIT_DEF(ECCTL2,0,CONT,continuous,one_shot), +}; + + +/*----------------------------------------------------------------------------*/ +// Enhanced Direct Memory Access(EDMA3) +/*----------------------------------------------------------------------------*/ +// am1808.pdf, Page 52 +// 5.9.1 EDMA3 Channel Synchronization Events +typedef enum { + // EDMA Channel Controller 0 + EDMA_McASP0_Receive, + EDMA_McASP0_Transmit, + EDMA_McBSP0_Receive, + EDMA_McBSP0_Transmit, + + EDMA_McBSP1_Receive, + EDMA_McBSP1_Transmit, + EDMA_GPIO_Bank0_Interrupt, + EDMA_GPIO_Bank1_Interrupt, + + EDMA_UART0_Receive, + EDMA_UART0_Transmit, + EDMA_Timer64P0_EventOut12, + EDMA_Timer64P0_EventOut34, + + EDMA_UART1_Receive, + EDMA_UART1_Transmit, + EDMA_SPI0_Receive, + EDMA_SPI0_Transmit, + + EDMA_MMCSD0_Receive, + EDMA_MMCSD0_Transmit, + EDMA_SPI1_Receive, + EDMA_SPI1_Transmit, + + EDMA_PRU_EVTOUT6, + EDMA_PRU_EVTOUT7, + EDMA_GPIO_Bank2_Interrupt, + EDMA_GPIO_Bank3_Interrupt, + + EDMA_I2C0_Receive, + EDMA_I2C0_Transmit, + EDMA_I2C1_Receive, + EDMA_I2C1_Transmit, + + EDMA_GPIO_Bank4_Interrupt, + EDMA_GPIO_Bank5_Interrupt, + EDMA_UART2_Receive, + EDMA_UART2_Transmit, + + // EDMA Channel Controller 1 + EDMA_Timer64P2_CompareEvent0, + EDMA_Timer64P2_CompareEvent1, + EDMA_Timer64P2_CompareEvent2, + EDMA_Timer64P2_CompareEvent3, + + EDMA_Timer64P2_CompareEvent4, + EDMA_Timer64P2_CompareEvent5, + EDMA_Timer64P2_CompareEvent6, + EDMA_Timer64P2_CompareEvent7, + + EDMA_Timer64P3_CompareEvent0, + EDMA_Timer64P3_CompareEvent1, + EDMA_Timer64P3_CompareEvent2, + EDMA_Timer64P3_CompareEvent3, + + EDMA_Timer64P3_CompareEvent4, + EDMA_Timer64P3_CompareEvent5, + EDMA_Timer64P3_CompareEvent6, + EDMA_Timer64P3_CompareEvent7, + + EDMA_GPIO_Bank6_Interrupt, + EDMA_GPIO_Bank7_Interrupt, + EDMA_GPIO_Bank8_Interrupt, + EDMA_Reserved0, + + EDMA_Reserved1, + EDMA_Reserved2, + EDMA_Reserved3, + EDMA_Reserved4, + + EDMA_Timer64P2_EventOut12, + EDMA_Timer64P2_EventOut34, + EDMA_Timer64P3_EventOut12, + EDMA_Timer64P3_EventOut34, + + EDMA_MMCSD1_Receive, + EDMA_MMCSD1_Transmit, + EDMA_Reserved5, + EDMA_Reserved6, +} EDMA_event_t; + +typedef struct { +#define OPT_PRIVID_MASK (0xFUL << 24) +#define OPT_PRIVID_X(x) (((x) & 0xFUL) << 24) +#define OPT_TCC_MASK (0x3FUL << 12) +#define OPT_TCC_X(x) (((x) & 0x3FUL) << 12) +#define OPT_FWID_MASK (0x7UL << 8) +#define OPT_FWID_8b (0x0UL << 8) +#define OPT_FWID_16b (0x1UL << 8) +#define OPT_FWID_32b (0x2UL << 8) +#define OPT_FWID_64b (0x3UL << 8) +#define OPT_FWID_128b (0x4UL << 8) +#define OPT_FWID_256b (0x5UL << 8) +#define OPT_PRI_MASK (0x7UL << 4) + vuint32_t OPT; + vuint32_t SRC; +#define PARAM_BCNT_MASK (0xFFFFUL << 16) +#define PARAM_ACNT_MASK (0xFFFFUL << 0) + vuint32_t A_B_CNT; + vuint32_t DST; +#define PARAM_DSTBIDX_MASK (0xFFFFUL << 16) +#define PARAM_SRCBIDX_MASK (0xFFFFUL << 0) + vuint32_t SRC_DST_BIDX; +#define PARAM_BCNTRLD_MASK (0xFFFFUL << 16) +#define PARAM_LINK_MASK (0xFFFFUL << 0) + vuint32_t LINK_BCNTRLD; +#define PARAM_DSTCIDX_MASK (0xFFFFUL << 16) +#define PARAM_SRCCIDX_MASK (0xFFFFUL << 0) + vuint32_t SRC_DST_CIDX; +#define PARAM_CCNT_MASK (0xFFFFUL << 0) + vuint32_t CCNT; +} PaRAM_entry_t; + +enum { + BIT_DEF(OPT,23,ITCCHEN,no,yes), + BIT_DEF(OPT,22,TCCHEN,no,yes), + BIT_DEF(OPT,21,ITCINTEN,no,yes), + BIT_DEF(OPT,20,TCINTEN,no,yes), + BIT_DEF(OPT,11,TCCMODE,Normal,Early), + BIT_DEF(OPT,3,STATIC,no,yes), + BIT_DEF(OPT,2,SYNCDIM,Async,ABsync), + BIT_DEF(OPT,1,DAM,INCR,CONST), + BIT_DEF(OPT,0,SAM,INCR,CONST), +}; + +typedef struct { +// n = 0..31 +#define ExR_En_MASK(n) (0x1UL << (n)) +#define ExR_En_none(n) (0x0UL << (n)) +#define ExR_En_asserted(n) (0x1UL << (n)) +#define ExR_En_clear(n) (0x1UL << (n)) +#define ExR_En_set(n) (0x1UL << (n)) + vcuint32_t ER; + uint32_t RESERVED0; + vuint32_t ECR; + uint32_t RESERVED1; + vuint32_t ESR; + uint32_t RESERVED2; +// n = 0..31 +#define CER_En_MASK(n) (0x1UL << (n)) +#define CER_En_none(n) (0x0UL << (n)) +#define CER_En_prioritized(n) (0x1UL << (n)) + vcuint32_t CER; + uint32_t RESERVED3; +// n = 0..31 +#define EExR_En_MASK(n) (0x1UL << (n)) +#define EExR_En_no(n) (0x0UL << (n)) +#define EExR_En_yes(n) (0x1UL << (n)) +#define EExR_En_clear(n) (0x1UL << (n)) +#define EExR_En_set(n) (0x1UL << (n)) + vcuint32_t EER; + uint32_t RESERVED4; + vuint32_t EECR; + uint32_t RESERVED5; + vuint32_t EESR; + uint32_t RESERVED6; +// n = 0..31 +#define SExR_En_MASK(n) (0x1UL << (n)) +#define SExR_En_none(n) (0x0UL << (n)) +#define SExR_En_stored(n) (0x1UL << (n)) +#define SExR_En_clear(n) (0x1UL << (n)) + vcuint32_t SER; + uint32_t RESERVED7; + vuint32_t SECR; + uint32_t RESERVED8[_RS(0x50,0x40)]; +// n = 0..31 +#define IExR_En_MASK(n) (0x1UL << (n)) +#define IExR_En_no(n) (0x0UL << (n)) +#define IExR_En_yes(n) (0x1UL << (n)) +#define IExR_En_clear(n) (0x1UL << (n)) +#define IExR_En_set(n) (0x1UL << (n)) + vcuint32_t IER; + uint32_t RESERVED9; + vuint32_t IECR; + uint32_t RESERVED10; + vuint32_t IESR; + uint32_t RESERVED11; +// n = 0..31 +#define IxR_En_MASK(n) (0x1UL << (n)) +#define IxR_En_none(n) (0x0UL << (n)) +#define IxR_En_pending(n) (0x1UL << (n)) +#define IxR_En_clear(n) (0x1UL << (n)) + vcuint32_t IPR; + uint32_t RESERVED12; + vuint32_t ICR; + uint32_t RESERVED13; + vuint32_t IEVAL; + uint32_t RESERVED14; +// n = 0..7 +#define QER_En_MASK(n) (0x1UL << (n)) +#define QER_En_none(n) (0x0UL << (n)) +#define QER_En_prioritized(n) (0x1UL << (n)) + vcuint32_t QER; +// n = 0..7 +#define QEExR_En_MASK(n) (0x1UL << (n)) +#define QEExR_En_no(n) (0x0UL << (n)) +#define QEExR_En_yes(n) (0x1UL << (n)) +#define QEExR_En_clear(n) (0x1UL << (n)) +#define QEExR_En_set(n) (0x1UL << (n)) + vcuint32_t QEER; + vuint32_t QEECR; + vuint32_t QEESR; +// n = 0..7 +#define QSExR_En_MASK(n) (0x1UL << (n)) +#define QSExR_En_none(n) (0x0UL << (n)) +#define QSExR_En_stored(n) (0x1UL << (n)) +#define QSExR_En_clear(n) (0x1UL << (n)) + vcuint32_t QSER; + vuint32_t QSECR; +} EDMA3CC_rgn_t; + +typedef struct { +#define EDMA3CC_REVID 0x40015300UL + vcuint32_t REVID; +#define CCCFG_NUM_REGN_MASK (0x3UL << 20) +#define CCCFG_NUM_EVQUE_MASK (0x7UL << 16) +#define CCCFG_NUM_PAENTRY_MASK (0x7UL << 12) +#define CCCFG_NUM_INTCH_MASK (0x7UL << 8) +#define CCCFG_NUM_QDMACH_MASK (0x7UL << 4) +#define CCCFG_NUM_DMACH_MASK (0x7UL << 0) + vcuint32_t CCCFG; + uint32_t RESERVED0[_RS(0x200,0x004)]; +#define QCHMAP_PAENTRY_MASK (0x7FUL << 5) +#define QCHMAP_TRWORD_MASK (0x7UL << 2) + vuint32_t QCHMAPx[8]; + uint32_t RESERVED1[_RS(0x240,0x21C)]; +// n = 0..31 +#define DMAQNUM_IDX(n) ((n) >> 3) +#define DMAQNUM_En_MASK(n) (0x7UL << (((n) & 0x7UL) << 2)) + vuint32_t DMAQNUMx[4]; + uint32_t RESERVED2[_RS(0x260,0x24C)]; +// n = 0..7 +#define QDMAQNUM_En_MASK(n) (0x7UL << (((n) & 0x7UL) << 2)) + vuint32_t QDMAQNUM; + uint32_t RESERVED3[_RS(0x284,0x260)]; + vuint32_t QUEPRI; + uint32_t RESERVED4[_RS(0x300,0x284)]; +// n = 0..31 +#define EMxR_En_MASK(n) (0x1UL << (n)) +#define EMxR_En_none(n) (0x0UL << (n)) +#define EMxR_En_missed(n) (0x1UL << (n)) +#define EMxR_En_clear(n) (0x1UL << (n)) + vcuint32_t EMR; + uint32_t RESERVED5; + vuint32_t EMCR; + uint32_t RESERVED6; +// n = 0..7 +#define QEMxR_En_MASK(n) (0x1UL << (n)) +#define QEMxR_En_none(n) (0x0UL << (n)) +#define QEMxR_En_missed(n) (0x1UL << (n)) +#define QEMxR_En_clear(n) (0x1UL << (n)) + vcuint32_t QEMR; + vuint32_t QEMCR; + vcuint32_t CCERR; + vuint32_t CCERRCLR; + vuint32_t EEVAL; + uint32_t RESERVED7[_RS(0x340,0x320)]; +#define DRAE_IDX(r) ((r) << 1) +// n = 0..31 +#define DRAE_En_MASK(n) (0x1UL << (n)) +#define DRAE_En_none(n) (0x0UL << (n)) +#define DRAE_En_allow(n) (0x1UL << (n)) + vuint32_t DRAEx[8]; + uint32_t RESERVED8[_RS(0x380,0x35C)]; +// n = 0..7 +#define QRAE_En_MASK(n) (0x1UL << (n)) +#define QRAE_En_none(n) (0x0UL << (n)) +#define QRAE_En_allow(n) (0x1UL << (n)) + vuint32_t QRAEx[4]; + uint32_t RESERVED9[_RS(0x400,0x38C)]; +#define QyEx_ETYPE_MASK (0x3UL << 6) +#define QyEx_ETYPE_ER (0x0UL << 6) +#define QyEx_ETYPE_ESR (0x1UL << 6) +#define QyEx_ETYPE_CER (0x2UL << 6) +#define QyEx_ETYPE_QER (0x3UL << 6) +#define QyEx_ENUM_MASK (0x1FUL << 0) + vcuint32_t Q0Ex[16]; + vcuint32_t Q1Ex[16]; + uint32_t RESERVED10[_RS(0x600,0x47C)]; +#define QSTAT_WM_MASK (0x1FUL << 16) +#define QSTAT_WM_isLegal(x) (0 <= (x) && (x) <= 0x10UL) +#define QSTAT_NUMVAL_MASK (0x1FUL << 8) +#define QSTAT_NUMVAL_isLegal(x) (0 <= (x) && (x) <= 0x10UL) +#define QSTAT_STRTPTR_MASK (0xFUL << 0) + vcuint32_t QSTATx[2]; + uint32_t RESERVED11[_RS(0x620,0x604)]; +#define QWMTHRA_Q1_MASK (0x1FUL << 8) +#define QWMTHRA_Q0_MASK (0x1FUL << 0) + vuint32_t QWMTHRA; + uint32_t RESERVED12[_RS(0x640,0x620)]; +#define CCSTAT_COMPACTV_MASK (0x3FUL << 8) + vcuint32_t CCSTAT; + uint32_t RESERVED13[_RS(0x1000,0x640)]; + EDMA3CC_rgn_t Global; + uint32_t RESERVED14[_RS(0x2000,0x1094)]; + EDMA3CC_rgn_t Region0; + uint32_t RESERVED15[_RS(0x2200,0x2094)]; + EDMA3CC_rgn_t Region1; + uint32_t RESERVED16[_RS(0x4000,0x2294)]; +#define PAEntry_CNT 128 + PaRAM_entry_t PAEntry[PAEntry_CNT]; +} EDMA3CC_con_t; + +enum { + BIT_DEF(CCCFG,25,MP_EXIST,no,yes), + BIT_DEF(CCCFG,24,CHMAP_EXIST,no,yes), + BIT_DEF(CCERR,16,TCCERR,none,reached), + BIT_DEF(CCERR,1,QTHRXCD1,none,exceed), + BIT_DEF(CCERR,0,QTHRXCD0,none,exceed), + BIT_DEF(CCERRCLR,16,TCCERR,none,clear), + BIT_DEF(CCERRCLR,1,QTHRXCD1,none,clear), + BIT_DEF(CCERRCLR,0,QTHRXCD0,none,clear), + BIT_DEF(EEVAL,0,EVAL,none,pulsed), + BIT_DEF(QSTAT,24,THRXCD,no,yes), + BIT_DEF(CCSTAT,17,QUEACTV1,no,yes), + BIT_DEF(CCSTAT,16,QUEACTV0,no,yes), + BIT_DEF(CCSTAT,4,ACTV,no,yes), + BIT_DEF(CCSTAT,3,WSTATACTV,no,yes), + BIT_DEF(CCSTAT,2,TRACTV,no,yes), + BIT_DEF(CCSTAT,1,QEVTACTV,no,yes), + BIT_DEF(CCSTAT,0,EVTACTV,no,yes), + BIT_DEF(IEVAL,0,EVAL,none,pulsed), +}; + +typedef struct { + vuint32_t OPT; + vcuint32_t SRC; + vcuint32_t CNT; + vcuint32_t DST; + vcuint32_t BIDX; +#define MPPRXY_PRIVID_MASK (0xFUL << 0) + vcuint32_t MPPRXY; + // only valid for Source Active (SA) + vcuint32_t SACNTRLD; + vcuint32_t SASRCBREF; + vcuint32_t SADSTBREF; + uint32_t RESERVED0[_RS(0x40,0x20)]; +} EDMA3TC_fifo_t; + +enum { + BIT_DEF(MPPRXY,8,PRIV,user,supervisor), +}; + +typedef struct { +#define EDMA3TC_REVID 0x40003B00UL + vcuint32_t REVID; +#define TCCFG_DREGDEPTH_MASK (0x3UL << 8) +#define TCCFG_BUSWIDTH_MASK (0x3UL << 4) +#define TCCFG_FIFOSIZE_MASK (0x7UL << 0) + vcuint32_t TCCFG; + uint32_t RESERVED0[_RS(0x100,0x004)]; +#define TCSTAT_DFSTRTPTR_MASK (0x3UL << 11) +#define TCSTAT_DSTACTV_MASK (0x7UL << 4) + vcuint32_t TCSTAT; + uint32_t RESERVED1[_RS(0x120,0x100)]; + vcuint32_t ERRSTAT; + vuint32_t ERREN; + vuint32_t ERRCLR; +#define ERRDET_TCC_MASK (0x3FUL << 8) +#define ERRDET_STAT_MASK (0xFUL << 0) +#define ERRDET_STAT_NoError (0x0UL << 0) +#define ERRDET_STAT_ReadAddressing (0x1UL << 0) +#define ERRDET_STAT_ReadPrivilege (0x2UL << 0) +#define ERRDET_STAT_ReadTimeout (0x3UL << 0) +#define ERRDET_STAT_ReadData (0x4UL << 0) +#define ERRDET_STAT_ReadExclusive (0x7UL << 0) +#define ERRDET_STAT_WriteAddressing (0x9UL << 0) +#define ERRDET_STAT_WritePrivilege (0xAUL << 0) +#define ERRDET_STAT_WriteTimeout (0xBUL << 0) +#define ERRDET_STAT_WriteData (0xCUL << 0) +#define ERRDET_STAT_WriteExclusive (0xFUL << 0) + vcuint32_t ERRDET; + vuint32_t ERRCMD; + uint32_t RESERVED2[_RS(0x140,0x130)]; +#define RDRATE_X_MASK (0x7UL << 0) +#define RDRATE_X_AsFast (0x0UL << 0) +#define RDRATE_X_4cycles (0x1UL << 0) +#define RDRATE_X_8cycles (0x2UL << 0) +#define RDRATE_X_16cycles (0x3UL << 0) +#define RDRATE_X_32cycles (0x4UL << 0) + vuint32_t RDRATE; + uint32_t RESERVED3[_RS(0x240,0x140)]; + EDMA3TC_fifo_t SAx[1]; + vcuint32_t DFCNTRLD; + vcuint32_t DFSRCBREF; + vcuint32_t DFDSTBREF; + uint32_t RESERVED5[_RS(0x300,0x288)]; + EDMA3TC_fifo_t DFx[4]; +} EDMA3TC_con_t; + +enum { + BIT_DEF(TCSTAT,2,WSACTV,none,pending), + BIT_DEF(TCSTAT,1,SRCACTV,idle,busy), + BIT_DEF(TCSTAT,0,PROGBUSY,idle,busy), + BIT_DEF(ERRSTAT,3,MMRAERR,no,yes), + BIT_DEF(ERRSTAT,2,THERR,no,yes), + BIT_DEF(ERRSTAT,0,BUSERR,no,yes), + BIT_DEF(ERREN,3,MMRAERR,no,yes), + BIT_DEF(ERREN,2,THERR,no,yes), + BIT_DEF(ERREN,0,BUSERR,no,yes), + BIT_DEF(ERRCLR,3,MMRAERR,none,clear), + BIT_DEF(ERRCLR,2,THERR,none,clear), + BIT_DEF(ERRCLR,0,BUSERR,none,clear), + BIT_DEF(ERRDET,17,TCCHEN,no,yes), + BIT_DEF(ERRDET,16,TCINTEN,no,yes), + BIT_DEF(ERRCMD,0,EVAL,none,pulsed), +}; + +typedef struct { + EDMA3CC_con_t CC; + uint32_t RESERVED0[_RS(0x8000,0x4FFC)]; + EDMA3TC_con_t TC[2]; +} EDMA_con_t; + + +/*----------------------------------------------------------------------------*/ +// EMAC/MDIO Module +/*----------------------------------------------------------------------------*/ +typedef struct emac_desc { + struct emac_desc* next; + vuint8_t* buf_ptr; + vuint16_t len; /* valid data length */ + /* not include offset bytes */ + vuint16_t offset; /* valid if SOP set */ + /* unused bytes from buf_ptr */ + /* to start of valid data */ + vuint16_t pkt_len; /* data bytes in entire packet */ + /* not include offset bytes */ + /* summary of all fragment lens */ + vuint16_t flags; +} emac_desc_t; + +typedef enum { + BIT_DEF(EMACDF,15,SOP,none,start), /* Start of Packet, set by SW */ + BIT_DEF(EMACDF,14,EOP,none,end), /* End of Packet, set by SW */ + BIT_DEF(EMACDF,13,OWNER,sw,emac), /* SOP:Ownership, set by SW, clear by EMAC */ + BIT_DEF(EMACDF,12,EOQ,none,end), /* EOP:End of Queue, clear by SW, set by EMAC */ + BIT_DEF(EMACDF,11,TDOWNCMPLT,no,yes), /* SOP:Teardown or aborted */ + /* EMAC set this bit when abort transmission */ + BIT_DEF(EMACDF,10,PASSCRC,no,yes), /* SOP:Pass CRC */ + /* when set, packet data contain 4 bytes Ethernet CRC */ + /* when cleared, EMAC generates 4 bytes CRC */ + BIT_DEF(EMACDF,9,JABBER,no,yes), /* SOP:Jabber Flag */ + /* EMAC set this bit when exceeding RXMAXLEN & errors */ + BIT_DEF(EMACDF,8,OVERSIZE,no,yes), /* SOP:Oversize Flag, set by EMAC */ + BIT_DEF(EMACDF,7,FRAGMENT,no,yes), /* SOP:Fragment Flag, set by EMAC */ + BIT_DEF(EMACDF,6,UNDERSIZED,no,yes), /* SOP:Undersized Flag, set by EMAC */ + BIT_DEF(EMACDF,5,CONTROL,no,yes), /* SOP:Control Flag, set by EMAC */ + BIT_DEF(EMACDF,4,OVERRUN,no,yes), /* SOP:Overrun Flag, set by EMAC */ + BIT_DEF(EMACDF,3,CODEERROR,no,yes), /* SOP:Code Error, set by EMAC */ + BIT_DEF(EMACDF,2,ALIGNERROR,no,yes), /* SOP:Alignment Error, set by EMAC */ + BIT_DEF(EMACDF,1,CRCERROR,no,yes), /* SOP:CRC Error, set by EMAC */ + BIT_DEF(EMACDF,0,NOMATCH,no,yes), /* SOP:No Match, set by EMAC */ + /* if it did not pass any of */ + /* the EMAC's address match criteria */ +} emac_desc_flags_t; + +typedef struct { +#define EMACC_REVID 0x4EC80101UL + vcuint32_t REVID; + vuint32_t SOFTRESET; + uint32_t RESERVED0[1]; +// n = 0..2 +#define EMACCINTCTL_CxTXPACEEN_MASK(n) (0x1UL << (17 + ((n) << 1))) +#define EMACCINTCTL_CxTXPACEEN_no(n) (0x0UL << (17 + ((n) << 1))) +#define EMACCINTCTL_CxTXPACEEN_yes(n) (0x1UL << (17 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_MASK(n) (0x1UL << (16 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_no(n) (0x0UL << (16 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_yes(n) (0x1UL << (16 + ((n) << 1))) +#define EMACCINTCTL_PRESCALE_MASK (0x7FFUL << 0) +#define EMACCINTCTL_PRESCALE_VAL(x) (((x) & 0x7FFUL) << 0) + vuint32_t INTCONTROL; + struct { +// n = 0..7 +// include CxRXTHRESHEN,CxRXTHRESHSTAT +#define RXTHRESHXX_RXCHx_MASK(n) (0x1UL << (n)) +#define RXTHRESHXX_RXCHx_no(n) (0x0UL << (n)) +#define RXTHRESHXX_RXCHx_yes(n) (0x1UL << (n)) + vuint32_t RXTHRESHEN; // CnRXTHRESHPULSE +// n = 0..7 +// include CnRXEN, CnRXSTAT +#define CnRXXX_RXCHx_MASK(n) (0x1UL << (n)) +#define CnRXXX_RXCHx_no(n) (0x0UL << (n)) +#define CnRXXX_RXCHx_yes(n) (0x1UL << (n)) + vuint32_t RXEN; // CnRXPULSE +// n = 0..7 +// include CnTXEN,CnTXSTAT +#define CnTXXX_TXCHx_MASK(n) (0x1UL << (n)) +#define CnTXXX_TXCHx_no(n) (0x0UL << (n)) +#define CnTXXX_TXCHx_yes(n) (0x1UL << (n)) + vuint32_t TXEN; // CnTXPULSE + vuint32_t MISCEN; + } CxINT[3]; + struct { + vuint32_t RXTHRESHSTAT; // CnRXTHRESHPULSE + vuint32_t RXSTAT; // CnRXPULSE + vuint32_t TXSTAT; // CnTXPULSE + vuint32_t MISCSTAT; + } CxSTAT[3]; + struct { +#define CnRXIMAX_RXIMAX_MASK (0x3FUL << 0) +#define CnRXIMAX_RXIMAX_VAL(x) (((x) & 0x3FUL) << 0) + vuint32_t RXIMAX; +#define CnTXIMAX_TXIMAX_MASK (0x3FUL << 0) +#define CnTXIMAX_TXIMAX_VAL(x) (((x) & 0x3FUL) << 0) + vuint32_t TXIMAX; + } CxIMAX[3]; +} EMACC_con_t; + +enum { + BIT_DEF(EMACCSWRST,0,RESET,no,yes), + BIT_DEF(CnMISCEN,3,STATPENDEN,no,yes), + BIT_DEF(CnMISCEN,2,HOSTPENDEN,no,yes), + BIT_DEF(CnMISCEN,1,LINKINT0EN,no,yes), + BIT_DEF(CnMISCEN,0,USERINT0EN,no,yes), +}; + +typedef struct { +#define MDIO_REVID (0x00070104UL) + vcuint32_t REVID; +#define MDIOCTL_CLKDIV_MASK (0xFFFFUL << 0) +#define MDIOCTL_CLKDIV_VAL(x) (((x) & 0xFFFFUL) << 0) +#define MDIOCTL_HIGHCH_MASK (0x1FUL << 24) +#define MDIOCTL_HIGHCH_VAL(x) (((x) & 0x1FUL) << 24) + vuint32_t CONTROL; +#define MDIO_ALIVE_MASK(n) (0x1UL << (n)) +#define MDIO_ALIVE_no(n) (0x0UL << (n)) +#define MDIO_ALIVE_ack(n) (0x1UL << (n)) + vcuint32_t ALIVE; +#define MDIO_LINK_MASK(n) (0x1UL << (n)) +#define MDIO_LINK_no(n) (0x0UL << (0)) +#define MDIO_LINK_yes(n) (0x1UL << (0)) + vcuint32_t LINK; + vcuint32_t LINKINTRAW; + vcuint32_t LINKINTMASKED; + uint32_t RESERVED0[2]; + vcuint32_t USEINTRAW; + vcuint32_t USEINTMASKED; + vuint32_t USEINTMASKSET; + vuint32_t USEINTMASKCLEAR; + uint32_t RESERVED1[_RS(0x80,0x2C)]; + struct { +#define USERACCESSx_REGADR_MASK (0x1FUL << 21) +#define USERACCESSx_REGADR_VAL(x) (((x) & 0x1FUL) << 21) +#define USERACCESSx_PHYADR_MASK (0x1FUL << 16) +#define USERACCESSx_PHYADR_VAL(x) (((x) & 0x1FUL) << 16) +#define USERACCESSx_DATA_MASK (0xFFFFUL << 0) +#define USERACCESSx_DATA_VAL(x) (((x) & 0xFFFFUL) << 0) + vuint32_t ACCESS; +#define USERPHYSELx_PHYADRMON_MASK (0x1FUL << 0) +#define USERPHYSELx_PHYADRMON_VAL(x) (((x) & 0x1FUL) << 0) + vuint32_t PHYSEL; + } USER[2]; +} MDIO_con_t; + +enum { + BIT_DEF(MDIOCTL,31,IDLE,no,yes), + BIT_DEF(MDIOCTL,30,ENABLE,no,yes), + BIT_DEF(MDIOCTL,20,PREAMBLE,standard,none), + BIT_DEF(MDIOCTL,19,FAULT,no,phy), + BIT_DEF(MDIOCTL,18,FAULTENB,no,yes), + + // include LINKINTRAW,LINKINTMASKED + BIT_DEF(LINKINTXX,1,USERPHY1,no,yes), + BIT_DEF(LINKINTXX,0,USERPHY0,no,yes), + + // include USERINTRAW,USERINTMASKED,USERINTMASKSET,USERINTMASKCLEAR + BIT_DEF(USERINTXX,1,USERACCESS1,no,complete), + BIT_DEF(USERINTXX,0,USERACCESS0,no,complete), + + BIT_DEF(USERACCESSx,31,GO,none,run), + BIT_DEF(USERACCESSx,30,WRITE,no,yes), + BIT_DEF(USERACCESSx,29,ACK,no,yes), + BIT_DEF(USERPHYSELx,7,LINKSEL,mdio,reserved), + BIT_DEF(USERPHYSELx,6,LINKINTENB,no,yes), +}; + +typedef struct { + vcuint32_t RXGOODFRAMES; // 0x00 + vcuint32_t RXBCASTFRAMES; + vcuint32_t RXMCASTFRAMES; + vcuint32_t RXPAUSEFRAMES; + vcuint32_t RXCRCERRORS; // 0x10 + vcuint32_t RXALIGNCODEERRORS; + vcuint32_t RXOVERSIZED; + vcuint32_t RXJABBER; + vcuint32_t RXUNDERSIZED; // 0x20 + vcuint32_t RXFRAGMENTS; + vcuint32_t RXFILTERED; + vcuint32_t RXQOSFILTERED; + vcuint32_t RXOCTETS; // 0x30 + vcuint32_t TXGOODFRAMES; + vcuint32_t TXBCASTFRAMES; + vcuint32_t TXMCASTFRAMES; + vcuint32_t TXPAUSEFRAMES; // 0x40 + vcuint32_t TXDEFERRED; + vcuint32_t TXCOLLISION; + vcuint32_t TXSINGLECOLL; + vcuint32_t TXMULTICOLL; // 0x50 + vcuint32_t TXEXCESSIVECOLL; + vcuint32_t TXLATECOLL; + vcuint32_t TXTXUNDERRUN; + vcuint32_t TXCARRIERSENSE; // 0x60 + vcuint32_t TXOCTETS; + vcuint32_t FRAME64; + vcuint32_t FRAME65T127; + vcuint32_t FRAME128T255; // 0x70 + vcuint32_t FRAME256T511; + vcuint32_t FRAME512T1023; + vcuint32_t FRAME1024TUP; + vcuint32_t NETOCTETS; // 0x80 + vcuint32_t RXSOFOVERRUNS; + vcuint32_t RXMOFOVERRUNS; + vcuint32_t RXDMAOVERRUNS; +} EMAC_statis_t; + +typedef struct { + vcuint32_t TXREVID; + vuint32_t TXCONTROL; + vuint32_t TXTEARDOWN; + uint32_t RESERVED0[1]; + vcuint32_t RXREVID; + vuint32_t RXCONTROL; + vuint32_t RXTEARDOWN; + uint32_t RESERVED1[1]; + uint32_t RESERVED2[_RS(0x80,0x1C)]; + vcuint32_t TXINTSTATRAW; + vcuint32_t TXINTSTATMASKED; + vuint32_t TXINTMASKSET; + vuint32_t TXINTMASKCLEAR; + vuint32_t MACINVECTOR; + vuint32_t MACEOIVECTOR; + uint32_t RESERVED3[_RS(0xA0,0x94)]; + vcuint32_t RXINTSTATRAW; + vcuint32_t RXINTSTATMASKED; + vuint32_t RXINTMASKSET; + vuint32_t RXINTMASKCLEAR; + vcuint32_t MACINTSTATRAW; + vcuint32_t MACINTSTATMASKED; + vuint32_t MACINTMASKSET; + vuint32_t MACINTMASKCLEAR; + uint32_t RESERVED4[_RS(0x100,0xBC)]; + vuint32_t RXMPBENABLE; + vuint32_t RXUNICASTSET; + vuint32_t RXUNICASTCLEAR; + vuint32_t RXMAXLEN; + vuint32_t RXBUFFEROFFSET; + vuint32_t RXFILTERLOWTHRESH; + vuint32_t RXxFLOWTHRESH[8]; + vuint32_t RXxFREEBUFFER[8]; + vuint32_t MACCONTROL; + vcuint32_t MACSTATUS; + vuint32_t EMCONTROL; + vuint32_t FIFOCONTROL; + vuint32_t MACCONFIG; + vuint32_t SOFTRESET; + uint32_t RESERVED5[_RS(0x1D0,0x174)]; + vuint64_t MACSRCADDR; + vuint64_t MACHASH; + vuint32_t BOFFTEST; + vuint32_t TPACETEST; + vuint32_t RXPAUSE; + vuint32_t TXPAUSE; + uint32_t RESERVED6[_RS(0x200,0x1EC)]; + EMAC_statis_t STATIS; + uint32_t RESERVED7[_RS(0x500,0x28C)]; + vuint64_t MACADDR; + vuint32_t MACINDEX; + uint32_t RESERVED8[_RS(0x600,0x508)]; + vuint32_t TXxHDP[8]; + vuint32_t RXxHDP[8]; + vuint32_t TXxCP[8]; + vuint32_t RXxCP[8]; +} EMAC_con_t; + + +/*----------------------------------------------------------------------------*/ +// General-Purpose Input/Output(GPIO) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define XXX_GPkPj_MASK(j) (0x1UL << (j)) +#define DIR_GPkPj_output(j) (0x0UL << (j)) +#define DIR_GPkPj_input(j) (0x1UL << (j)) + vuint32_t DIR; +#define OUT_DATA_GPkPj_low(j) (0x0UL << (j)) +#define OUT_DATA_GPkPj_high(j) (0x1UL << (j)) + vuint32_t OUT_DATA; +#define SET_DATA_GPkPj_none(j) (0x0UL << (j)) +#define SET_DATA_GPkPj_high(j) (0x1UL << (j)) + vuint32_t SET_DATA; +#define CLR_DATA_GPkPj_none(j) (0x0UL << (j)) +#define CLR_DATA_GPkPj_low(j) (0x1UL << (j)) + vuint32_t CLR_DATA; +#define IN_DATA_GPkPj_low(j) (0x0UL << (j)) +#define IN_DATA_GPkPj_high(j) (0x1UL << (j)) + vuint32_t IN_DATA; +#define SET_RIS_TRIG_none(j) (0x0UL << (j)) +#define SET_RIS_TRIG_enable(j) (0x1UL << (j)) + vuint32_t SET_RIS_TRIG; +#define CLR_RIS_TRIG_none(j) (0x0UL << (j)) +#define CLR_RIS_TRIG_disable(j) (0x1UL << (j)) + vuint32_t CLR_RIS_TRIG; +#define SET_FAL_TRIG_none(j) (0x0UL << (j)) +#define SET_FAL_TRIG_disable(j) (0x1UL << (j)) + vuint32_t SET_FAL_TRIG; +#define CLR_FAL_TRIG_none(j) (0x0UL << (j)) +#define CLR_FAL_TRIG_disable(j) (0x1UL << (j)) + vuint32_t CLR_FAL_TRIG; +#define INTSTAT_none(j) (0x0UL << (j)) +#define INTSTAT_pending(j) (0x1UL << (j)) + vuint32_t INTSTAT; +} GPIO_pair_t; + +typedef struct { +#define GPIO_REVID 0x44830105UL + vcuint32_t REVID; + uint32_t RESERVED0; +#define BIT_ENx_MASK(x) (0x1UL << (x)) +#define BIT_ENx_no(x) (0x0UL << (x)) +#define BIT_ENx_yes(x) (0x1UL << (x)) + vuint32_t BINTEN; + uint32_t RESERVED1; +#define GPIO_BANKS_0_1 0 +#define GPIO_BANKS_2_3 1 +#define GPIO_BANKS_4_5 2 +#define GPIO_BANKS_6_7 3 +#define GPIO_BANKS_8 4 + GPIO_pair_t BANKS[5]; +} GPIO_con_t; + + +/*----------------------------------------------------------------------------*/ +// Inter-Integrated Circuit(I2C) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define ICOAR_OADDR_MASK (0x3FFUL << 0) +#define ICOAR_OADDR_VAL(x) ((0x3FFUL & (x)) << 0) + vuint32_t ICOAR; +#define ICIMR_AAS_MASK (0x1UL << 6) +#define ICIMR_AAS_disabled (0x0UL << 6) +#define ICIMR_AAS_enabled (0x1UL << 6) +#define ICIMR_SCD_MASK (0x1UL << 5) +#define ICIMR_SCD_disabled (0x0UL << 5) +#define ICIMR_SCD_enabled (0x1UL << 5) +#define ICIMR_ICXRDY_MASK (0x1UL << 4) +#define ICIMR_ICXRDY_disabled (0x0UL << 4) +#define ICIMR_ICXRDY_enabled (0x1UL << 4) +#define ICIMR_ICRRDY_MASK (0x1UL << 3) +#define ICIMR_ICRRDY_disabled (0x0UL << 3) +#define ICIMR_ICRRDY_enabled (0x1UL << 3) +#define ICIMR_ARDY_MASK (0x1UL << 2) +#define ICIMR_ARDY_disabled (0x0UL << 2) +#define ICIMR_ARDY_enabled (0x1UL << 2) +#define ICIMR_NACK_MASK (0x1UL << 1) +#define ICIMR_NACK_disabled (0x0UL << 1) +#define ICIMR_NACK_enabled (0x1UL << 1) +#define ICIMR_AL_MASK (0x1UL << 0) +#define ICIMR_AL_disabled (0x0UL << 0) +#define ICIMR_AL_enabled (0x1UL << 0) + vuint32_t ICIMR; +#define ICSTR_SDIR_MASK (0x1UL << 14) +#define ICSTR_SDIR_other (0x0UL << 14) +#define ICSTR_SDIR_slaveTX (0x1UL << 14) +#define ICSTR_SDIR_clear (0x1UL << 14) +#define ICSTR_NACKSNT_MASK (0x1UL << 13) +#define ICSTR_NACKSNT_none (0x0UL << 13) +#define ICSTR_NACKSNT_sent (0x1UL << 13) +#define ICSTR_NACKSNT_clear (0x1UL << 13) +#define ICSTR_BB_MASK (0x1UL << 12) +#define ICSTR_BB_free (0x0UL << 12) +#define ICSTR_BB_busy (0x1UL << 12) +#define ICSTR_BB_clear (0x1UL << 12) +#define ICSTR_RSFULL_MASK (0x1UL << 11) +#define ICSTR_RSFULL_none (0x0UL << 11) +#define ICSTR_RSFULL_overrun (0x1UL << 11) +#define ICSTR_XSMT_MASK (0x1UL << 10) +#define ICSTR_XSMT_underflow (0x0UL << 10) +#define ICSTR_XSMT_none (0x1UL << 10) +#define ICSTR_AAS_MASK (0x1UL << 9) +#define ICSTR_ASS_cleared (0x0UL << 9) +#define ICSTR_ASS_set (0x1UL << 9) +#define ICSTR_AD0_MASK (0x1UL << 8) +#define ICSTR_AD0_cleared (0x0UL << 8) +#define ICSTR_AD0_detected (0x1UL << 8) +#define ICSTR_SCD_MASK (0x1UL << 5) +#define ICSTR_SCD_none (0x0UL << 5) +#define ICSTR_SCD_detected (0x1UL << 5) +#define ICSTR_SCD_clear (0x1UL << 5) +#define ICSTR_ICXRDY_MASK (0x1UL << 4) +#define ICSTR_ICXRDY_none (0x0UL << 4) +#define ICSTR_ICXRDY_ready (0x1UL << 4) +#define ICSTR_ICXRDY_clear (0x1UL << 4) +#define ICSTR_ICRRDY_MASK (0x1UL << 3) +#define ICSTR_ICRRDY_none (0x0UL << 3) +#define ICSTR_ICRRDY_ready (0x1UL << 3) +#define ICSTR_ICRRDY_clear (0x1UL << 3) +#define ICSTR_ARDY_MASK (0x1UL << 2) +#define ICSTR_ARDY_none (0x0UL << 2) +#define ICSTR_ARDY_ready (0x1UL << 2) +#define ICSTR_ARDY_clear (0x1UL << 2) +#define ICSTR_NACK_MASK (0x1UL << 1) +#define ICSTR_NACK_ack (0x0UL << 1) +#define ICSTR_NACK_nack (0x1UL << 1) +#define ICSTR_NACK_clear (0x1UL << 1) +#define ICSTR_AL_MASK (0x1UL << 0) +#define ICSTR_AL_none (0x0UL << 0) +#define ICSTR_AL_lost (0x1UL << 0) +#define ICSTR_AL_clear (0x1UL << 0) + vuint32_t ICSTR; +#define ICCLKL_MASK (0xFFFFUL << 0) + vuint32_t ICCLKL; +#define ICCLKH_MASK (0xFFFFUL << 0) + vuint32_t ICCLKH; +#define ICCNT_MASK (0xFFFFUL << 0) + vuint32_t ICCNT; +#define ICDRR_MASK (0xFFUL << 0) + vuint32_t ICDRR; +#define ICSAR_SADDR_MASK (0x3FFUL << 0) +#define ICSAR_SADDR_VAL(x) ((0x3FFUL & (x)) << 0) + vuint32_t ICSAR; +#define ICDXR_MASK (0xFFUL << 0) + vuint32_t ICDXR; +#define ICMDR_NACKMOD_MASK (0x1UL << 15) +#define ICMDR_NACKMOD_no (0x0UL << 15) +#define ICMDR_NACKMOD_yes (0x1UL << 15) +#define ICMDR_FREE_MASK (0x1UL << 14) +#define ICMDR_FREE_emu (0x0UL << 14) +#define ICMDR_FREE_run (0x1UL << 14) +#define ICMDR_STT_MASK (0x1UL << 13) +#define ICMDR_STT_no (0x0UL << 13) +#define ICMDR_STT_yes (0x1UL << 13) +#define ICMDR_STP_MASK (0x1UL << 11) +#define ICMDR_STP_no (0x0UL << 11) +#define ICMDR_STP_yes (0x1UL << 11) +#define ICMDR_MST_MASK (0x1UL << 10) +#define ICMDR_MST_slave (0x0UL << 10) +#define ICMDR_MST_master (0x1UL << 10) +#define ICMDR_TRX_MASK (0x1UL << 9) +#define ICMDR_TRX_receiver (0x0UL << 9) +#define ICMDR_TRX_transmitter (0x1UL << 9) +#define ICMDR_XA_MASK (0x1UL << 8) +#define ICMDR_XA_7bit (0x0UL << 8) +#define ICMDR_XA_10bit (0x1UL << 8) +#define ICMDR_RM_MASK (0x1UL << 7) +#define ICMDR_RM_no (0x0UL << 7) +#define ICMDR_RM_yes (0x1UL << 7) +#define ICMDR_DLB_MASK (0x1UL << 6) +#define ICMDR_DLB_disable (0x0UL << 6) +#define ICMDR_DLB_enable (0x1UL << 6) +#define ICMDR_IRS_MASK (0x1UL << 5) +#define ICMDR_IRS_reset (0x0UL << 5) +#define ICMDR_IRS_none (0x1UL << 5) +#define ICMDR_STB_MASK (0x1UL << 4) +#define ICMDR_STB_no (0x0UL << 4) +#define ICMDR_STB_yes (0x1UL << 4) +#define ICMDR_FDF_MASK (0x1UL << 3) +#define ICMDR_FDF_no (0x0UL << 3) +#define ICMDR_FDF_yes (0x1UL << 3) +#define ICMDR_BC_MASK (0x7UL << 0) +#define ICMDR_BC_VAL(x) ((0x7UL & (x)) << 0) + vuint32_t ICMDR; +#define ICIVR_INTCODE_MASK (0x7UL << 0) +#define ICIVR_INTCODE_none (0x0UL << 0) +#define ICIVR_INTCODE_AL (0x1UL << 0) +#define ICIVR_INTCODE_NACK (0x2UL << 0) +#define ICIVR_INTCODE_ARDY (0x3UL << 0) +#define ICIVR_INTCODE_ICRRDY (0x4UL << 0) +#define ICIVR_INTCODE_ICXRDY (0x5UL << 0) +#define ICIVR_INTCODE_SCD (0x6UL << 0) +#define ICIVR_INTCODE_AAS (0x7UL << 0) + vuint32_t ICIVR; +#define ICEMDR_IGNACK_MASK (0x1UL << 1) +#define ICEMDR_IGNACK_no (0x0UL << 1) +#define ICEMDR_IGNACK_yes (0x1UL << 1) +#define ICEMDR_BCM_MASK (0x1UL << 0) +#define ICEMDR_BCM_ack (0x0UL << 0) +#define ICEMDR_BCM_none (0x1UL << 0) + vuint32_t ICEMDR; +#define ICPSC_IPSC_MASK (0xFFUL << 0) +#define ICPSC_IPSC_VAL(x) ((0xFFUL & (x)) << 0) + vuint32_t ICPSC; + vcuint32_t REVID[2]; +#define ICDMAC_TXDMAEN_MASK (0x1UL << 1) +#define ICDMAC_TXDMAEN_disable (0x0UL << 1) +#define ICDMAC_TXDMAEN_enable (0x1UL << 1) +#define ICDMAC_RXDMAEN_MASK (0x1UL << 0) +#define ICDMAC_RXDMAEN_disable (0x0UL << 0) +#define ICDMAC_RXDMAEN_enable (0x1UL << 0) + vuint32_t ICDMAC; + uint32_t RESERVED0[2]; +#define ICPFUNC_PFUNC0_MASK (0x1UL << 0) +#define ICPFUNC_PFUNC0_i2c (0x0UL << 0) +#define ICPFUNC_PFUNC0_gpio (0x1UL << 0) + vuint32_t ICPFUNC; +#define ICPXXX_SCL 0x0 +#define ICPXXX_SDA 0x1 +#define ICPDIR_PDIRx_MASK(x) (0x1UL << (x)) +#define ICPDIR_PDIRx_input(x) (0x0UL << (x)) +#define ICPDIR_PDIRx_output(x) (0x1UL << (x)) + vuint32_t ICPDIR; +#define ICPDIO_PDIO_MASK(x) (0x1UL << (x)) +#define ICPDIO_PDIO_low(x) (0x0UL << (x)) +#define ICPDIO_PDIO_high(x) (0x1UL << (x)) + vuint32_t ICPDIN; + vuint32_t ICPDOUT; +#define ICPDXXX_MASK(x) (0x1UL << (x)) +#define ICPDXXX_none(x) (0x0UL << (x)) +#define ICPDXXX_assert(x) (0x1UL << (x)) + vuint32_t ICPDSET; + vuint32_t ICPDCLR; +} I2C_con_t; + + +/*----------------------------------------------------------------------------*/ +// Liquid Crystal Display Controller(LCDC) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define LCDC_REVID 0x4C100100UL + vcuint32_t REVID; +#define LCD_CTRL_CLKDIV_MASK (0xFFUL << 8) +#define LCD_CTRL_CLKDIV_X(x) (((x) & 0xFFUL) << 8) + vuint32_t LCD_CTRL; + vuint32_t LCD_STAT; + vuint32_t LIDD_CTRL; + vuint32_t LIDD_CS0_CONF; + vuint32_t LIDD_CS0_ADDR; + vuint32_t LIDD_CS0_DATA; + vuint32_t LIDD_CS1_CONF; + vuint32_t LIDD_CS1_ADDR; + vuint32_t LIDD_CS1_DATA; +#define RASTER_CTRL_PLM_MASK (0x3UL << 20) +#define RASTER_CTRL_PLM_PaletteData (0x0UL << 20) +#define RASTER_CTRL_PLM_Palette (0x1UL << 20) +#define RASTER_CTRL_PLM_Data (0x2UL << 20) +#define RASTER_CTRL_FDD_MASK (0xFFUL << 12) +#define RASTER_CTRL_FDD_X(x) (((x) & 0xFFUL) << 12) + vuint32_t RASTER_CTRL; +#define RT0_HBP_MASK (0xFFUL << 24) +#define RT0_HBP_VAL(x) (((x) & 0xFFUL) << 24) +#define RT0_HFP_MASK (0xFFUL << 16) +#define RT0_HFP_VAL(x) (((x) & 0xFFUL) << 16) +#define RT0_HSW_MASK (0x3FUL << 10) +#define RT0_HSW_VAL(x) (((x) & 0x3FUL) << 10) +#define RT0_PPL_MASK (0x3FUL << 4) +#define RT0_PPL_VAL(x) (((x) & 0x3FUL) << 4) + vuint32_t RASTER_TIMING_0; +#define RT1_VBP_MASK (0xFFUL << 24) +#define RT1_VBP_VAL(x) (((x) & 0xFFUL) << 24) +#define RT1_VFP_MASK (0xFFUL << 16) +#define RT1_VFP_VAL(x) (((x) & 0xFFUL) << 16) +#define RT1_VSW_MASK (0x3FUL << 10) +#define RT1_VSW_VAL(x) (((x) & 0x3FUL) << 10) +#define RT1_LPP_MASK (0x3FFUL << 0) +#define RT1_LPP_VAL(x) (((x) & 0x3FFUL) << 0) + vuint32_t RASTER_TIMING_1; +#define RT2_ACBI_MASK (0xFUL << 16) +#define RT2_ACBI_VAL(x) (((x) & 0xFUL) << 16) +#define RT2_ACB_MASK (0xFFUL << 8) +#define RT2_ACB_VAL(x) (((x) & 0xFFUL) << 8) + vuint32_t RASTER_TIMING_2; +#define RSP_LPPT_MASK (0x3FFUL << 16) +#define RSP_LPPT_VAL(x) (((x) & 0x3FFUL) << 16) +#define RSP_DPD_MASK (0xFFFUL << 4) +#define RSP_DPD_VAL(x) (((x) & 0xFFFUL) << 4) + vuint32_t RASTER_SUBPANEL; + uint32_t RESERVED0[1]; +#define LDMAC_TFR_MASK (0x7UL << 8) +#define LDMAC_TFR_VAL(x) (((x) & 0x7UL) << 8) +#define LDMAC_TFR_8dwords (0x0UL << 8) +#define LDMAC_TFR_16dwords (0x1UL << 8) +#define LDMAC_TFR_32dwords (0x2UL << 8) +#define LDMAC_TFR_64dwords (0x3UL << 8) +#define LDMAC_TFR_128dwords (0x4UL << 8) +#define LDMAC_TFR_256dwords (0x5UL << 8) +#define LDMAC_TFR_512dwords (0x6UL << 8) +#define LDMAC_BURSTSIZE_MASK (0x7UL << 4) +#define LDMAC_BURSTSIZE_VAL(x) (((x) & 0x7UL) << 4) +#define LDMAC_BURSTSIZE_1 (0x0UL << 4) +#define LDMAC_BURSTSIZE_2 (0x1UL << 4) +#define LDMAC_BURSTSIZE_4 (0x2UL << 4) +#define LDMAC_BURSTSIZE_8 (0x3UL << 4) +#define LDMAC_BURSTSIZE_16 (0x4UL << 4) + vuint32_t LCDDMA_CTRL; + vuint32_t LCDDMA_FB0_BASE; + vuint32_t LCDDMA_FB0_CEILING; + vuint32_t LCDDMA_FB1_BASE; + vuint32_t LCDDMA_FB1_CEILING; +} LCD_con_t; + +enum { + BIT_DEF(LCD_CTRL,0,MODESEL,LIDD,Raster), + BIT_DEF(LCD_STAT,9,EOF1,no,yes), + BIT_DEF(LCD_STAT,8,EOF0,no,yes), + BIT_DEF(LCD_STAT,6,PL,no,yes), + BIT_DEF(LCD_STAT,5,FUF,no,yes), + BIT_DEF(LCD_STAT,3,ABC,none,zero), + BIT_DEF(LCD_STAT,2,SYNC,none,lost), + BIT_DEF(LCD_STAT,0,DONE,no,yes), + BIT_DEF(RASTER_CTRL,24,STN565,disabled,enabled), + BIT_DEF(RASTER_CTRL,23,ALTMAP,D11_0,D15_0), + BIT_DEF(RASTER_CTRL,22,NIB,disabled,enabled), + BIT_DEF(RASTER_CTRL,9,MONO8B,4bits,8bits), + BIT_DEF(RASTER_CTRL,8,RDORDER,Little,Big), + BIT_DEF(RASTER_CTRL,7,TS,STN,TFT), + BIT_DEF(RASTER_CTRL,6,FUFEN,no,yes), + BIT_DEF(RASTER_CTRL,5,SLEN,no,yes), + BIT_DEF(RASTER_CTRL,4,PLEN,no,yes), + BIT_DEF(RASTER_CTRL,3,DONEEN,no,yes), + BIT_DEF(RASTER_CTRL,2,ACEN,no,yes), + BIT_DEF(RASTER_CTRL,1,MC,Color,Mono), + BIT_DEF(RASTER_CTRL,0,EN,no,yes), + BIT_DEF(RT2,25,SYNCCTRL,Inactive,Active), + BIT_DEF(RT2,24,SYNCEDGE,Rising,Falling), + BIT_DEF(RT2,23,BIAS,high,low), + BIT_DEF(RT2,22,IPC,rising,falling), + BIT_DEF(RT2,21,IHS,high,low), + BIT_DEF(RT2,20,IVS,high,low), + BIT_DEF(RSP,31,SPEN,disabled,enabled), + BIT_DEF(RSP,29,HOLS,below,above), + BIT_DEF(LDMAC,2,EOFINTEN,no,yes), + BIT_DEF(LDMAC,1,BIGENDIAN,disabled,enabled), + BIT_DEF(LDMAC,0,FRAMEMODE,one,two), +}; + + +/*----------------------------------------------------------------------------*/ +// Multimedia Card(MMC)/Secure Digital(SD) Card(MMCSD) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define MMCCTL_DATEG_MASK (0x3UL << 6) +#define MMCCTL_DATEG_disabled (0x0UL << 6) +#define MMCCTL_DATEG_rising (0x1UL << 6) +#define MMCCTL_DATEG_falling (0x2UL << 6) +#define MMCCTL_DATEG_both (0x3UL << 6) + vuint32_t MMCCTL; +#define MMCCLK_CLKRT_MASK (0xFFUL << 0) +#define MMCCLK_CLKRT_VAL(x) ((((x) - 1) & 0xFFUL) << 0) + vuint32_t MMCCLK; + vcuint32_t MMCST0; + vcuint32_t MMCST1; + vuint32_t MMCIM; +#define MMCTOR_TOD25_16_MASK (0x3FFUL << 8) +#define MMCTOR_TOD25_16_VAL(x) ((((x) >> 16) & 0x3FFUL) << 8) +#define MMCTOR_TOR_MASK (0xFFUL << 0) +#define MMCTOR_TOR_VAL(x) (((x) & 0xFFUL) << 0) +#define MMCTOD_TOD15_0_MASK (0xFFFFUL << 0) +#define MMCTOD_TOD15_0_VAL(x) (((x) & 0xFFFFUL) << 0) + vuint32_t MMCTOR; + vuint32_t MMCTOD; +#define MMCBLEN_BLEN_MASK (0xFFFUL << 0) +#define MMCBLEN_BLEN_VAL(x) ((x) << 0) + vuint32_t MMCBLEN; +#define MMCNBLK_NBLK_MASK (0xFFFFUL << 0) +#define MMCNBLK_NBLK_Infinite 0x0UL +#define MMCNBLK_NBLK_VAL(x) ((x) << 0) + vuint32_t MMCNBLK; +#define MMCNBLC_NBLC_MASK (0xFFFFUL << 0) + vcuint32_t MMCNBLC; + vuint32_t MMCDRR; + vuint32_t MMCDXR; +#define MMCCMD_RSPFMT_MASK (0x3UL << 9) +#define MMCCMD_RSPFMT_none (0x0UL << 9) +#define MMCCMD_RSPFMT_48bCRC (0x1UL << 9) +#define MMCCMD_RSPFMT_136b (0x2UL << 9) +#define MMCCMD_RSPFMT_48b (0x3UL << 9) +#define MMCCMD_CMD_MASK (0x3FUL << 0) +#define MMCCMD_CMD_VAL(x) (((x) & 0x3FUL) << 0) + vuint32_t MMCCMD; +#define MMCARGHL_ARGH_MASK (0xFFFFUL << 16) +#define MMCARGHL_ARGH_VAL(x) (((x) & 0xFFFFUL) << 16) +#define MMCARGHL_ARGL_MASK (0xFFFFUL << 0) +#define MMCARGHL_ARGL_VAL(x) (((x) & 0xFFFFUL) << 0) + vuint32_t MMCARGHL; +// 48b +// 0-7 0x00FF0000 & MMCRSP[2];-- end bit & CRC7 +// 8-39 0xFFFFFFFF & MMCRSP[3];-- card status +// 40-47 0xFF & MMCCIDX; -- command index:6 & transmission bit:1 & start bit:1 +// 136b +// 0-127 MMCRSP[0] - MMCRSP[3]; -- end bit & [(CID or CSD) include CRC7]:127 +// 128-135 MMCCIDX; -- reserved:6 & transmission:1 & start bit:1 + vuint32_t MMCRSP[4]; +#define MMCDRSP_DRSP_MASK (0xFFUL << 0) + vuint32_t MMCDRSP; + uint32_t RESERVED0; +#define MMCCIDX_CIDX_MASK (0x3FUL << 0) + vuint32_t MMCCIDX; + uint32_t RESERVED1[_RS(0x64,0x50)]; + vuint32_t SDIOCTL; + vcuint32_t SDIOST0; + vuint32_t SDIOIEN; + vuint32_t SDIOIST; +#define MMCFIFOCTL_ACCWD_MASK (0x3UL << 3) +#define MMCFIFOCTL_ACCWD_4bytes (0x0UL << 3) +#define MMCFIFOCTL_ACCWD_3bytes (0x1UL << 3) +#define MMCFIFOCTL_ACCWD_2bytes (0x2UL << 3) +#define MMCFIFOCTL_ACCWD_1bytes (0x3UL << 3) + vuint32_t MMCFIFOCTL; +} MMCSD_con_t; + +enum { + BIT_DEF(MMCCTL,10,PERMDX,Little,Big), + BIT_DEF(MMCCTL,9,PERMDR,Little,Big), + BIT_DEF(MMCCTL,8,WIDTH1,1_4bit,8bit), + BIT_DEF(MMCCTL,2,WIDTH0,1bit,4bit), + BIT_DEF(MMCCTL,1,CMDRST,enabled,disabled), + BIT_DEF(MMCCTL,0,DATRST,enabled,disabled), + BIT_DEF(MMCCLK,9,DIV4,div2,div4), + BIT_DEF(MMCCLK,8,CLKEN,low,enabled), + BIT_DEF(MMCST0,13,CCS,none,completed), + BIT_DEF(MMCST0,12,TRNDNE,none,done), + BIT_DEF(MMCST0,11,DATED,none,detected), + BIT_DEF(MMCST0,10,DRRDY,none,ready), + BIT_DEF(MMCST0,9,DXRDY,none,ready), + BIT_DEF(MMCST0,7,CRCRS,none,detected), + BIT_DEF(MMCST0,6,CRCRD,none,detected), + BIT_DEF(MMCST0,5,CRCWR,none,detected), + BIT_DEF(MMCST0,4,TOUTRS,none,occurred), + BIT_DEF(MMCST0,3,TOUTRD,none,occurred), + BIT_DEF(MMCST0,2,RSPDNE,none,done), + BIT_DEF(MMCST0,1,BSYDNE,none,done), + BIT_DEF(MMCST0,0,DATDNE,none,done), + BIT_DEF(MMCST1,6,FIFOFUL,no,yes), + BIT_DEF(MMCST1,5,FIFOEMP,no,yes), + BIT_DEF(MMCST1,4,DAT3ST,low,high), + BIT_DEF(MMCST1,3,DRFUL,no,yes), + BIT_DEF(MMCST1,2,DXEMP,no,yes), + BIT_DEF(MMCST1,1,CLKSTP,active,low), + BIT_DEF(MMCST1,0,BUSY,none,detected), + BIT_DEF(MMCIM,13,ECCS,disabled,enabled), + BIT_DEF(MMCIM,12,ETRNDNE,disabled,enabled), + BIT_DEF(MMCIM,11,EDATED,disabled,enabled), + BIT_DEF(MMCIM,10,EDRRDY,disabled,enabled), + BIT_DEF(MMCIM,9,EDXRDY,disabled,enabled), + BIT_DEF(MMCIM,7,ECRCRS,disabled,enabled), + BIT_DEF(MMCIM,6,ECRCRD,disabled,enabled), + BIT_DEF(MMCIM,5,ECRCWR,disabled,enabled), + BIT_DEF(MMCIM,4,ETOUTRS,disabled,enabled), + BIT_DEF(MMCIM,3,ETOUTRD,disabled,enabled), + BIT_DEF(MMCIM,2,ERSPDNE,disabled,enabled), + BIT_DEF(MMCIM,1,EBSYDNE,disabled,enabled), + BIT_DEF(MMCIM,0,EDATDNE,disabled,enabled), + BIT_DEF(MMCCMD,16,DMATRIG,none,triggered), + BIT_DEF(MMCCMD,15,DCLR,none,clear), + BIT_DEF(MMCCMD,14,INITCK,no,yes), + BIT_DEF(MMCCMD,13,WDATX,no,yes), + BIT_DEF(MMCCMD,12,STRMTP,block,stream), + BIT_DEF(MMCCMD,11,DTRW,read,write), + BIT_DEF(MMCCMD,8,BSYEXP,none,expected), + BIT_DEF(MMCCMD,7,PPLEN,none,enabled), + BIT_DEF(MMCCIDX,7,STRT,0s,1s), + BIT_DEF(MMCCIDX,6,XMIT,0s,1s), + BIT_DEF(SDIOCTL,1,RDWTCR,disabled,enabled), + BIT_DEF(SDIOCTL,0,RDWTRQ,end,request), + BIT_DEF(SDIOST0,2,RDWTST,none,doing), + BIT_DEF(SDIOST0,1,INTPRD,none,doing), + BIT_DEF(SDIOST0,0,DAT1,low,high), + BIT_DEF(SDIOIEN,1,RWSEN,disabled,enabled), + BIT_DEF(SDIOIEN,0,IOINTEN,disabled,enabled), + BIT_DEF(SDIOIST,1,RWS,none,occurred), + BIT_DEF(SDIOIST,0,IOINT,none,occurred), + BIT_DEF(MMCFIFOCTL,2,FIFOLEV,32B,64B), + BIT_DEF(MMCFIFOCTL,1,FIFODIR,read,write), + BIT_DEF(MMCFIFOCTL,0,FIFORST,none,reset), +}; + + +/*----------------------------------------------------------------------------*/ +// Real-Time Clock(RTC) +/*----------------------------------------------------------------------------*/ +typedef struct { + vuint32_t SECOND; + vuint32_t MINUTE; + vuint32_t HOUR; + vuint32_t DAY; + vuint32_t MONTH; + vuint32_t YEAR; + vuint32_t DOTW; + uint32_t RESERVED0[1]; + vuint32_t ALARMSECOND; + vuint32_t ALARMMINUTE; + vuint32_t ALARMHOUR; + vuint32_t ALARMDAY; + vuint32_t ALARMMONTH; + vuint32_t ALARMYEAR; + uint32_t RESERVED1[2]; + vuint32_t CTRL; + vcuint32_t STATUS; +#define RTCINT_EVERY_MASK (0x3UL << 0) +#define RTCINT_EVERY_Second (0x0UL << 0) +#define RTCINT_EVERY_Minute (0x1UL << 0) +#define RTCINT_EVERY_Hour (0x2UL << 0) +#define RTCINT_EVERY_Day (0x3UL << 0) + vuint32_t INTERRUPT; +#define COMPxSB_MASK (0xFFUL << 0) + vuint32_t COMPLSB; + vuint32_t COMPMSB; + vuint32_t OSC; + uint32_t RESERVED2[2]; + vuint32_t SCRATCH[3]; +#define RTC_KICK0R_VAL (0x83E70B13UL) +#define RTC_KICK1R_VAL (0x95A4F1E0UL) + vuint32_t KICKnR[2]; +} RTC_con_t; + +enum { + BIT_DEF(HOUR,7,MERIDIEM,AM,PM), + BIT_DEF(RTCTL,7,SPLITPOWER,disabled,enabled), + BIT_DEF(RTCTL,6,DISABLE,no,yes), + BIT_DEF(RTCTL,5,SET32COUNTER,none,enabled), + BIT_DEF(RTCTL,3,HOURMODE,24,12), + BIT_DEF(RTCTL,2,AUTOCOMP,disabled,enabled), + BIT_DEF(RTCTL,1,ROUNDMIN,disabled,enabled), + BIT_DEF(RTCTL,0,RUN,no,yes), + BIT_DEF(RTCSTAT,6,ALARM,no,yes), + BIT_DEF(RTCSTAT,5,DAYEVT,no,yes), + BIT_DEF(RTCSTAT,4,HREVT,no,yes), + BIT_DEF(RTCSTAT,3,MINEVT,no,yes), + BIT_DEF(RTCSTAT,2,SECEVT,no,yes), + BIT_DEF(RTCSTAT,1,RUN,no,yes), + BIT_DEF(RTCSTAT,0,BUSY,no,yes), + BIT_DEF(RTCINT,3,ALARM,disabled,enabled), + BIT_DEF(RTCINT,2,TIMER,disabled,enabled), + BIT_DEF(OSC,5,SWRESET,none,reset), +}; + + +/*----------------------------------------------------------------------------*/ +// 64-Bit Timer Plus +/*----------------------------------------------------------------------------*/ +typedef struct { + vcuint32_t REVID; +#define EMUMGT_SOFT_MASK (0x1UL << 1) +#define EMUMGT_SOFT_stop (0x0UL << 1) +#define EMUMGT_SOFT_reach (0x1UL << 1) +#define EMUMGT_FREE_MASK (0x1UL << 0) +#define EMUMGT_FREE_soft (0x0UL << 0) +#define EMUMGT_FREE_run (0x1UL << 0) + vuint32_t EMUMGT; +#define GPINTGPEN_GPENO12_MASK (0x1UL << 17) +#define GPINTGPEN_GPENO12_timer (0x0UL << 17) +#define GPINTGPEN_GPENO12_gpio (0x1UL << 17) +#define GPINTGPEN_GPENI12_MASK (0x1UL << 16) +#define GPINTGPEN_GPENI12_timer (0x0UL << 16) +#define GPINTGPEN_GPENI12_gpio (0x1UL << 16) +#define GPINTGPEN_GPINT12INVO_MASK (0x1UL << 5) +#define GPINTGPEN_GPINT12INVO_rising (0x0UL << 5) +#define GPINTGPEN_GPINT12INVO_falling (0x1UL << 5) +#define GPINTGPEN_GPINT12INVI_MASK (0x1UL << 4) +#define GPINTGPEN_GPINT12INVI_rising (0x0UL << 4) +#define GPINTGPEN_GPINT12INVI_falling (0x1UL << 4) +#define GPINTGPEN_GPINT12ENO_MASK (0x1UL << 1) +#define GPINTGPEN_GPINT12ENO_rising (0x0UL << 1) +#define GPINTGPEN_GPINT12ENO_falling (0x1UL << 1) +#define GPINTGPEN_GPINT12ENI_MASK (0x1UL << 0) +#define GPINTGPEN_GPINT12ENI_rising (0x0UL << 0) +#define GPINTGPEN_GPINT12ENI_falling (0x1UL << 0) + vuint32_t GPINTGPEN; +#define GPDATGPDIR_GPDIRO12_MASK (0x1UL << 17) +#define GPDATGPDIR_GPDIRO12_gpio_in (0x0UL << 17) +#define GPDATGPDIR_GPDIRO12_gpio_out (0x1UL << 17) +#define GPDATGPDIR_GPDIRI12_MASK (0x1UL << 16) +#define GPDATGPDIR_GPDIRI12_gpio_in (0x0UL << 16) +#define GPDATGPDIR_GPDIRI12_gpio_out (0x1UL << 16) +#define GPDATGPDIR_GPDATO12_MASK (0x1UL << 1) +#define GPDATGPDIR_GPDATO12_low (0x0UL << 1) +#define GPDATGPDIR_GPDATO12_high (0x1UL << 1) +#define GPDATGPDIR_GPDATI12_MASK (0x1UL << 0) +#define GPDATGPDIR_GPDATI12_low (0x0UL << 0) +#define GPDATGPDIR_GPDATI12_high (0x1UL << 0) + vuint32_t GPDATGPDIR; + vuint32_t TIMx[2]; + vuint32_t PRDx[2]; +#define TCR_READRSTMODE34_MASK (0x1UL << 26) +#define TCR_READRSTMODE34_none (0x0UL << 26) +#define TCR_READRSTMODE34_reset (0x1UL << 26) +#define TCR_ENAMODE34_MASK (0x3UL << 22) +#define TCR_ENAMODE34_disabled (0x0UL << 22) +#define TCR_ENAMODE34_once (0x1UL << 22) +#define TCR_ENAMODE34_enabled (0x2UL << 22) +#define TCR_ENAMODE34_reload (0x3UL << 22) +#define TCR_CAPEVTMODE12_MASK (0x3UL << 12) +#define TCR_CAPEVTMODE12_rising (0x0UL << 12) +#define TCR_CAPEVTMODE12_falling (0x1UL << 12) +#define TCR_CAPEVTMODE12_both (0x2UL << 12) +#define TCR_CAPMODE12_MASK (0x1UL << 11) +#define TCR_CAPMODE12_none (0x0UL << 11) +#define TCR_CAPMODE12_capture (0x1UL << 11) +#define TCR_READRSTMODE12_MASK (0x1UL << 10) +#define TCR_READRSTMODE12_none (0x0UL << 10) +#define TCR_READRSTMODE12_reset (0x1UL << 10) +#define TCR_TIEN12_MASK (0x1UL << 9) +#define TCR_TIEN12_none (0x0UL << 9) +#define TCR_TIEN12_gated (0x1UL << 9) +#define TCR_CLKSRC12_MASK (0x1UL << 8) +#define TCR_CLKSRC12_internal (0x0UL << 8) +#define TCR_CLKSRC12_external (0x1UL << 8) +#define TCR_ENAMODE12_MASK (0x3UL << 6) +#define TCR_ENAMODE12_disabled (0x0UL << 6) +#define TCR_ENAMODE12_once (0x1UL << 6) +#define TCR_ENAMODE12_enabled (0x2UL << 6) +#define TCR_ENAMODE12_reload (0x3UL << 6) +#define TCR_PWID12_MASK (0x3UL << 4) +#define TCR_PWID12_VAL(x) ((0x3UL & (x - 1)) << 4) +#define TCR_CP12_MASK (0x1UL << 3) +#define TCR_CP12_pulse (0x0UL << 3) +#define TCR_CP12_clock (0x1UL << 3) +#define TCR_INVINP12_MASK (0x1UL << 2) +#define TCR_INVINP12_uninverted (0x0UL << 2) +#define TCR_INVINP12_inverted (0x1UL << 2) +#define TCR_INVOUTP12_MASK (0x1UL << 1) +#define TCR_INVOUTP12_uninverted (0x0UL << 1) +#define TCR_INVOUTP12_inverted (0x1UL << 1) +#define TCR_TSTAT12_MASK (0x1UL << 0) +#define TCR_TSTAT12_deasserted (0x0UL << 0) +#define TCR_TSTAT12_asserted (0x1UL << 0) + vuint32_t TCR; +#define TGCR_TDDR34_MASK (0xFUL << 12) +#define TGCR_TDDR34_VAL(x) ((0xFUL & (x)) << 12) +#define TGCR_PSC34_MASK (0xFUL << 8) +#define TGCR_PSC34_VAL(x) ((0xFUL & (x)) << 8) +#define TGCR_PLUSEN_MASK (0x1UL << 4) +#define TGCR_PLUSEN_unavilable (0x0UL << 4) +#define TGCR_PLUSEN_available (0x1UL << 4) +#define TGCR_TIMMODE_MASK (0x3UL << 2) +#define TGCR_TIMMODE_64bit (0x0UL << 2) +#define TGCR_TIMMODE_unchained (0x1UL << 2) +#define TGCR_TIMMODE_watchdog (0x2UL << 2) +#define TGCR_TIMMODE_chained (0x3UL << 2) +#define TGCR_TIM34RS_MASK (0x1UL << 1) +#define TGCR_TIM34RS_reset (0x0UL << 1) +#define TGCR_TIM34RS_none (0x1UL << 1) +#define TGCR_TIM12RS_MASK (0x1UL << 0) +#define TGCR_TIM12RS_reset (0x0UL << 0) +#define TGCR_TIM12RS_none (0x1UL << 0) + vuint32_t TGCR; +#define WDTCR_WDKEY_MASK (0xFFFFUL << 16) +#define WDTCR_WDKEY_VAL(x) ((x) << 16) +#define WDTCR_WDFLAG_MASK (0x1UL << 15) +#define WDTCR_WDFLAG_none (0x0UL << 15) +#define WDTCR_WDFLAG_timeout (0x1UL << 15) +#define WDTCR_WDEN_MASK (0x1UL << 14) +#define WDTCR_WDEN_disable (0x0UL << 14) +#define WDTCR_WDEN_enable (0x1UL << 14) + vuint32_t WDTCR; + uint32_t RESERVED0[2]; + vuint32_t RELx[2]; + vuint32_t CAPx[2]; +#define INTCTLSTAT_EVTINTSTAT34_MASK (0x1UL << 19) +#define INTCTLSTAT_EVTINTSTAT34_none (0x0UL << 19) +#define INTCTLSTAT_EVTINTSTAT34_occurred (0x1UL << 19) +#define INTCTLSTAT_EVTINTSTAT34_clear (0x1UL << 19) +#define INTCTLSTAT_EVTINTEN34_MASK (0x1UL << 18) +#define INTCTLSTAT_EVTINTEN34_disable (0x0UL << 18) +#define INTCTLSTAT_EVTINTEN34_enable (0x1UL << 18) +#define INTCTLSTAT_PRDINTSTAT34_MASK (0x1UL << 17) +#define INTCTLSTAT_PRDINTSTAT34_none (0x0UL << 17) +#define INTCTLSTAT_PRDINTSTAT34_occurred (0x1UL << 17) +#define INTCTLSTAT_PRDINTSTAT34_clear (0x1UL << 17) +#define INTCTLSTAT_PRDINTEN34_MASK (0x1UL << 16) +#define INTCTLSTAT_PRDINTEN34_disable (0x0UL << 16) +#define INTCTLSTAT_PRDINTEN34_enable (0x1UL << 16) +#define INTCTLSTAT_EVTINTSTAT12_MASK (0x1UL << 3) +#define INTCTLSTAT_EVTINTSTAT12_none (0x0UL << 3) +#define INTCTLSTAT_EVTINTSTAT12_occurred (0x1UL << 3) +#define INTCTLSTAT_EVTINTSTAT12_clear (0x1UL << 3) +#define INTCTLSTAT_EVTINTEN12_MASK (0x1UL << 2) +#define INTCTLSTAT_EVTINTEN12_disable (0x0UL << 2) +#define INTCTLSTAT_EVTINTEN12_enable (0x1UL << 2) +#define INTCTLSTAT_PRDINTSTAT12_MASK (0x1UL << 1) +#define INTCTLSTAT_PRDINTSTAT12_none (0x0UL << 1) +#define INTCTLSTAT_PRDINTSTAT12_occurred (0x1UL << 1) +#define INTCTLSTAT_PRDINTSTAT12_clear (0x1UL << 1) +#define INTCTLSTAT_PRDINTEN12_MASK (0x1UL << 0) +#define INTCTLSTAT_PRDINTEN12_disable (0x0UL << 0) +#define INTCTLSTAT_PRDINTEN12_enable (0x1UL << 0) + vuint32_t INTCTLSTAT; + uint32_t RESERVED1[6]; + vuint32_t CMPx[8]; +} TIMER_con_t; + + +/*----------------------------------------------------------------------------*/ +// Universal Asynchronous Reiceiver/Transmitter(UART) +/*----------------------------------------------------------------------------*/ +typedef struct { +#define RBR_DATA_MASK 0xFFUL +#define THRw RBRr +#define THR_DATA_MASK 0xFFUL + vuint32_t RBRr; +#define IER_EDSSI_MASK (0x1UL << 3) +#define IER_EDSSI_disable (0x0UL << 3) +#define IER_EDSSI_enable (0x1UL << 3) +#define IER_ELSI_MASK (0x1UL << 2) +#define IER_ELSI_disable (0x0UL << 2) +#define IER_ELSI_enable (0x1UL << 2) +#define IER_ETBEI_MASK (0x1UL << 1) +#define IER_ETBEI_disable (0x0UL << 1) +#define IER_ETBEI_enable (0x1UL << 1) +#define IER_ERBI_MASK (0x1UL << 0) +#define IER_ERBI_disable (0x0UL << 0) +#define IER_ERBI_enable (0x1UL << 0) + vuint32_t IER; +#define IIR_FIFOEN_MASK (0x3UL << 6) +#define IIR_FIFOEN_Non_FIFO (0x0UL << 6) +#define IIR_FIFOEN_enabled (0x3UL << 6) +#define IIR_INTID_MASK (0x7UL << 1) +#define IIR_INTID_thr_empty (0x1UL << 1) +#define IIR_INTID_data_avail (0x2UL << 1) +#define IIR_INTID_line_status (0x3UL << 1) +#define IIR_INTID_timeout (0x6UL << 1) +#define IIR_IPEND_MASK (0x1UL << 0) +#define IIR_IPEND_yes (0x0UL << 0) +#define IIR_IPEND_no (0x1UL << 0) +#define FCRw IIRr +#define FCR_RXFIFTL_MASK (0x3UL << 6) +#define FCR_RXFIFTL_1byte (0x0UL << 6) +#define FCR_RXFIFTL_4bytes (0x1UL << 6) +#define FCR_RXFIFTL_8bytes (0x2UL << 6) +#define FCR_RXFIFTL_14bytes (0x3UL << 6) +#define FCR_DMAMODE1_MASK (0x1UL << 3) +#define FCR_DMAMODE1_disable (0x0UL << 3) +#define FCR_DMAMODE1_enable (0x1UL << 3) +#define FCR_TXCLR_MASK (0x1UL << 2) +#define FCR_TXCLR_clear (0x1UL << 2) +#define FCR_RXCLR_MASK (0x1UL << 1) +#define FCR_RXCLR_clear (0x1UL << 1) +#define FCR_FIFOEN_MASK (0x1UL << 0) +#define FCR_FIFOEN_No (0x0UL << 0) +#define FCR_FIFOEN_Yes (0x1UL << 0) + vuint32_t IIRr; +#define LCR_DLAB_MASK (0x1UL << 7) +#define LCR_DLAB_rbr_thr_ier (0x0UL << 7) +#define LCR_DLAB_dll_dlh (0x1UL << 7) +#define LCR_BC_MASK (0x1UL << 6) +#define LCR_BC_disabled (0x0UL << 6) +#define LCR_BC_enabled (0x1UL << 6) +#define LCR_SP_MASK (0x1UL << 5) +#define LCR_SP_disabled (0x0UL << 5) +#define LCR_SP_enabled (0x1UL << 5) +#define LCR_EPS_MASK (0x1UL << 4) +#define LCR_EPS_Odd (0x0UL << 4) +#define LCR_EPS_Even (0x1UL << 4) +#define LCR_PEN_MASK (0x1UL << 3) +#define LCR_PEN_No (0x0UL << 3) +#define LCR_PEN_Yes (0x1UL << 3) +#define LCR_STB_MASK (0x1UL << 2) +#define LCR_STB_1STOP (0x0UL << 2) +#define LCR_STB_15_2STOP (0x1UL << 2) +#define LCR_WLS_MASK (0x3UL << 0) +#define LCR_WLS_5bits (0x0UL << 0) +#define LCR_WLS_6bits (0x1UL << 0) +#define LCR_WLS_7bits (0x2UL << 0) +#define LCR_WLS_8bits (0x3UL << 0) + vuint32_t LCR; +#define MCR_AFE_MASK (0x1UL << 5) +#define MCR_AFE_disabled (0x0UL << 5) +#define MCR_AFE_enabled (0x1UL << 5) +#define MCR_LOOP_MASK (0x1UL << 4) +#define MCR_LOOP_disabled (0x0UL << 4) +#define MCR_LOOP_enabled (0x1UL << 4) +#define MCR_RTS_MASK (0x1UL << 1) +#define MCR_RTS_disabled (0x0UL << 1) +#define MCR_RTS_enabled (0x1UL << 1) + vuint32_t MCR; +#define LSR_RXFIFOE_MASK (0x1UL << 7) +#define LSR_RXFIFOE_no_error (0x0UL << 7) +#define LSR_RXFIFOE_error (0x1UL << 7) +#define LSR_TEMT_MASK (0x1UL << 6) +#define LSR_TEMT_no (0x0UL << 6) +#define LSR_TEMT_yes (0x1UL << 6) +#define LSR_THRE_MASK (0x1UL << 5) +#define LSR_THRE_no (0x0UL << 5) +#define LSR_THRE_yes (0x1UL << 5) +#define LSR_BI_MASK (0x1UL << 4) +#define LSR_BI_no (0x0UL << 4) +#define LSR_BI_yes (0x1UL << 4) +#define LSR_FE_MASK (0x1UL << 3) +#define LSR_FE_no (0x0UL << 3) +#define LSR_FE_yes (0x1UL << 3) +#define LSR_PE_MASK (0x1UL << 2) +#define LSR_PE_no (0x0UL << 2) +#define LSR_PE_yes (0x1UL << 2) +#define LSR_OE_MASK (0x1UL << 1) +#define LSR_OE_no (0x0UL << 1) +#define LSR_OE_yes (0x1UL << 1) +#define LSR_DR_MASK (0x1UL << 0) +#define LSR_DR_no (0x0UL << 0) +#define LSR_DR_yes (0x1UL << 0) + vuint32_t LSR; +#define MSR_CD_MASK (0x1UL << 7) +#define MSR_CD_high (0x0UL << 7) +#define MSR_CD_low (0x1UL << 7) +#define MSR_RI_MASK (0x1UL << 6) +#define MSR_RI_high (0x0UL << 6) +#define MSR_RI_low (0x1UL << 6) +#define MSR_DSR_MASK (0x1UL << 5) +#define MSR_DSR_high (0x0UL << 5) +#define MSR_DSR_low (0x1UL << 5) +#define MSR_CTS_MASK (0x1UL << 4) +#define MSR_CTS_high (0x0UL << 4) +#define MSR_CTS_low (0x1UL << 4) +#define MSR_DCD_MASK (0x1UL << 3) +#define MSR_DCD_unchanged (0x0UL << 3) +#define MSR_DCD_changed (0x1UL << 3) +#define MSR_TERI_MASK (0x1UL << 2) +#define MSR_TERI_unchanged (0x0UL << 2) +#define MSR_TERI_changed (0x1UL << 2) +#define MSR_DDSR_MASK (0x1UL << 1) +#define MSR_DDSR_unchanged (0x0UL << 1) +#define MSR_DDSR_changed (0x1UL << 1) +#define MSR_DCTS_MASK (0x1UL << 0) +#define MSR_DCTS_unchanged (0x0UL << 0) +#define MSR_DCTS_changed (0x1UL << 0) + vuint32_t MSR; +#define SCR_MASK 0xFFUL + vuint32_t SCR; + vuint8_t DLL; + uint8_t RESERVED0[3]; + vuint8_t DLH; + uint8_t RESERVED1[3]; + vuint32_t REVID[2]; +#define PWREMU_UTRST_MASK (0x1UL << 14) +#define PWREMU_UTRST_reset (0x0UL << 14) +#define PWREMU_UTRST_enabled (0x1UL << 14) +#define PWREMU_URRST_MASK (0x1UL << 13) +#define PWREMU_URRST_reset (0x0UL << 13) +#define PWREMU_URRST_enabled (0x1UL << 13) +#define PWREMU_FREE_MASK (0x1UL << 0) +#define PWREMU_FREE_halt (0x0UL << 0) +#define PWREMU_FREE_run (0x1UL << 0) + vuint32_t PWREMU_MGMT; +#define MDR_OSM_SEL_MASK (0x1UL << 0) +#define MDR_OSM_SEL_16x (0x0UL << 0) +#define MDR_OSM_SEL_13x (0x1UL << 0) + vuint32_t MDR; +} UART_con_t; + + +/*----------------------------------------------------------------------------*/ +// Univeral Serial Bus 2.0(USB) +/*----------------------------------------------------------------------------*/ +typedef struct { +// TXMAXP, RXMAXP +#define xXMAXP_MAXPAYLOAD_MASK (0x7FFUL << 0) + vuint16_t TXMAXP; + // PERI_CSR0, HOST_CSR0 + // PERI_TXCSR, HOST_TXCSR + vuint16_t TXCSR; + vuint16_t RXMAXP; + // PERI_RXCSR, HOST_RXCSR + vuint16_t RXCSR; + // COUNT0 +#define COUNT0_EP0RXCOUNT_MASK (0x7FUL << 0) +#define RXCOUNT_EPRXCOUNT_MASK (0x1FFFUL << 0) + vcuint16_t RXCOUNT; + // HOST_TYPE0, HOST_TXTYPE + vuint8_t TXTYPE; + // HOST_NAKLIMIT0, HOST_TXINTERVAL + vuint8_t TXINTERVAL; + vuint8_t RXTYPE; + vuint8_t RXINTERVAL; + uint8_t RESERVED0; + vcuint8_t CONFIGDATA; +} USB0_endp_t; + +typedef enum { + INTUSB_SUSPEND = 0, + INTUSB_RESUME, + INTUSB_RESET, + INTUSB_SOF, + INTUSB_CONN, + INTUSB_DISCON, + INTUSB_SESSREQ, + INTUSB_VBUSERR, + INTUSB_DRVVBUS, + INTUSB_CNT, +} INTUSB_t; + +typedef struct { + // OTG memmory mapped Registers +#define USB0_REVID 0x4EA10800UL + vcuint32_t REVID; + vuint32_t CTRLR; + vcuint32_t STATR; + vuint32_t EMUR; +// ep = 1..4 +#define USB0_EP_CNT 5 +#define MODE_MODE_TX_MASK(ep) (0x3UL << (((ep) - 1) << 2)) +#define MODE_MODE_RX_MASK(ep) (0x30000UL << (((ep) - 1) << 2)) +#define MODE_xMODE_Transparent (0x0UL << 0) +#define MODE_xMODE_RNDIS (0x1UL << 0) +#define MODE_xMODE_CDC (0x2UL << 0) +#define MODE_xMODE_GenericRNDIS (0x3UL << 0) + vuint32_t MODE; +#define AUTOREQ_AUTREQ_MASK(ep) (0x3UL << (((ep) - 1) << 1)) +#define AUTOREQ_xAUTREQ_None (0x0UL << 0) +#define AUTOREQ_xAUTREQ_NotEOP (0x1UL << 0) +#define AUTOREQ_xAUTREQ_Always (0x3UL << 0) + vuint32_t AUTOREQ; + vuint32_t SPRFIXTIME; +#define TEARDOWN_RX_MASK(ep) (0x1UL << (ep)) +#define TEARDOWN_RX_diable(ep) (0x0UL << (ep)) +#define TEARDOWN_RX_enable(ep) (0x1UL << (ep)) +#define TEARDOWN_TX_MASK(ep) (0x10000UL << (ep)) +#define TEARDOWN_TX_diable(ep) (0x00000UL << (ep)) +#define TEARDOWN_TX_enable(ep) (0x10000UL << (ep)) + vuint32_t TEARDOWN; +// INTSRCR, INTSETR, INTCLRR +// INTMSKR, INTMSKSETR, INTMSKCLRR +// INTMSKEDR +// ep = 0..4 +#define INTxR_TXEPn_MASK(ep) (0x1UL << (ep)) +#define INTxR_TXEPn_no(ep) (0x0UL << (ep)) +#define INTxR_TXEPn_yes(ep) (0x1UL << (ep)) +// ep = 1..4 +#define INTxR_RXEPn_MASK(ep) (0x1UL << ((ep) + 8)) +#define INTxR_RXEPn_no(ep) (0x0UL << ((ep) + 8)) +#define INTxR_RXEPn_yes(ep) (0x1UL << ((ep) + 8)) +// ir = INTUSB_XXX +#define INTxR_INTUSB_MASK(ir) (0x1UL << ((ir) + 16)) +#define INTxR_INTUSB_no(ir) (0x0UL << ((ir) + 16)) +#define INTxR_INTUSB_yes(ir) (0x1UL << ((ir) + 16)) + vcuint32_t INTSRCR; // PDR + vuint32_t INTSETR; // PDR + vuint32_t INTCLRR; // PDR + vcuint32_t INTMSKR; // PDR + vuint32_t INTMSKSETR; // PDR + vuint32_t INTMSKCLRR; // PDR + vcuint32_t INTMASKEDR; // PDR +#define EOIR_EOI_MASK(ir) (0x1UL << (ir)) +#define EOIR_EOI_no(ir) (0x0UL << (ir)) +#define EOIR_EOI_yes(ir) (0x1UL << (ir)) + vuint32_t EOIR; + uint32_t RESERVED0[_RS(0x04C,0x03C)]; +#define GENRNDISSZx_SIZE_MASK (0x1FFFFUL << 0) + vuint32_t GENRNDISSZx[5]; + uint32_t RESERVED1[_RS(0x400,0x05C)]; + + // Common USB Registers + // MUSB memmory mapped Registers +#define FADDR_FUNCADDR_MASK (0x7FUL << 0) + vuint8_t FADDR; + vuint8_t POWER; +// INTRTX, INTRRX, INTRTXE, INTRRXE +// ep = 0..4 +#define INTRx_EP_MASK(ep) (0x1UL << (ep)) +#define INTRx_EP_disable(ep) (0x0UL << (ep)) +#define INTRx_EP_enable(ep) (0x1UL << (ep)) + vcuint16_t INTRTX; // non-PDR + vcuint16_t INTRRX; // non-PDR + vuint16_t INTRTXE; + vuint16_t INTRRXE; +// ir = INTUSB_XXX +#define INTRUSBx_INTUSB_MASK(ir) (0x1UL << (ir)) +#define INTRUSBx_INTUSB_no(ir) (0x0UL << (ir)) +#define INTRUSBx_INTUSB_yes(ir) (0x1UL << (ir)) + vcuint8_t INTRUSB; // non-PDR + vuint8_t INTRUSBE; +#define FRAME_FRAMENUMBER_MASK (0x7FFUL << 0) + vcuint16_t FRAME; +#define INDEX_EPSEL_MASK (0xFUL << 0) +// ep = 0..4 +#define INDEX_EPSEL_VAL(ep) ((ep) << 0) + vuint8_t INDEX; + + vuint8_t TESTMODE; + // Indexed Registers + USB0_endp_t INDXEP; + // FIFOn + vuint32_t FIFOx[5]; + uint32_t RESERVED2[_RS(0x460,0x430)]; + // OTG Device Control +#define DEVCTL_VBUS_MASK (0x3UL << 3) +#define DEVCTL_VBUS_BelowSEnd (0x0UL << 3) +#define DEVCTL_VBUS_SEnd_AValid (0x1UL << 3) +#define DEVCTL_VBUS_AValid_VBusValid (0x2UL << 3) +#define DEVCTL_VBUS_AboveVbusValid (0x3UL << 3) + vcuint8_t DEVCTL; + uint8_t RESERVED3; + // Dynamic FIFO Control + struct { +// TXFIFOSZ, RXFIFOSZ +#define xXFIFOSZ_SZ_MASK (0xFUL << 0) +#define xXFIFOSZ_SZ_8B (0x0UL << 0) +#define xXFIFOSZ_SZ_16B (0x1UL << 0) +#define xXFIFOSZ_SZ_32B (0x2UL << 0) +#define xXFIFOSZ_SZ_64B (0x3UL << 0) +#define xXFIFOSZ_SZ_128B (0x4UL << 0) +#define xXFIFOSZ_SZ_256B (0x5UL << 0) +#define xXFIFOSZ_SZ_512B (0x6UL << 0) +#define xXFIFOSZ_SZ_1KB (0x7UL << 0) +#define xXFIFOSZ_SZ_2KB (0x8UL << 0) +#define xXFIFOSZ_SZ_4KB (0x9UL << 0) +#define xXFIFOSZ_SZ_8KB (0xAUL << 0) +#define xXFIFOSZ_SZ_16KB (0xBUL << 0) +#define xXFIFOSZ_SZ_32KB (0xCUL << 0) +#define xXFIFOSZ_SZ_64KB (0xDUL << 0) +#define xXFIFOSZ_SZ_128KB (0xEUL << 0) +#define xXFIFOSZ_SZ_256KB (0xFUL << 0) + vuint8_t TXFIFOSZ; + vuint8_t RXFIFOSZ; +// TXFIFOADDR, RXFIFOADDR +#define xXFIFOADDR_ADDR_MASK (0x1FFFUL << 0) +#define xXFIFOADDR_ADDR_VAL(adr) (((adr) >> 3) << 0) + vuint16_t TXFIFOADDR; + vuint16_t RXFIFOADDR; + } INDXF; + uint8_t RESERVED4[0x46C - 0x468]; +#define HWVERS_REVMAJ_MASK (0x1FUL << 10) +#define HWVERS_REVMIN_MASK (0x3FFUL << 0) + vcuint16_t HWVERS; + uint16_t RESERVED5; + uint32_t RESERVED6[_RS(0x500,0x470)]; + // ignore + // Target Endpoint x Control Registers, Valid Only in Host Mode + // + // Control and Status Registers for Endpoint x + USB0_endp_t EPx[5]; + // CDMA Registers + // Queue Manager (QMGR) Registers +} USB0_con_t; + +enum { + BIT_DEF(CTRLR,4,RNDIS,disabled,enabled), + BIT_DEF(CTRLR,3,UINT,PDR,non_PDR), + BIT_DEF(CTRLR,1,CLKFACK,disabled,enabled), + BIT_DEF(CTRLR,0,RESET,none,reset), + BIT_DEF(STATR,0,DRVVBUS,0,1), + BIT_DEF(EMUR,2,RT_SEL,yes,no), + BIT_DEF(EMUR,1,SOFT,no,yes), + BIT_DEF(EMUR,0,FREERUN,no,yes), + BIT_DEF(INTxR,24,USBDRVVBUS,no,yes), + BIT_DEF(INTxR,23,VBUSERR,no,yes), + BIT_DEF(INTxR,22,SESSREQ,no,yes), + BIT_DEF(INTxR,21,DISCON,no,yes), + BIT_DEF(INTxR,20,CONN,no,yes), + BIT_DEF(INTxR,19,SOF,no,yes), + BIT_DEF(INTxR,18,BABBLE,no,yes), + BIT_DEF(INTxR,17,RESUME,no,yes), + BIT_DEF(INTxR,16,SUSPEND,no,yes), + BIT_DEF(POWER,7,ISOUPDATE,no,yes), + BIT_DEF(POWER,6,SOFTCONN,no,yes), + BIT_DEF(POWER,5,HSEN,full,high), + BIT_DEF(POWER,4,HSMODE,no,yes), // Read only + BIT_DEF(POWER,3,RESET,no,yes), // Read only in Peripheral + BIT_DEF(POWER,2,RESUME,no,gen), + BIT_DEF(POWER,1,SUSPENDM,no,entry), + BIT_DEF(POWER,0,ENSUSPM,disabled,enabled), + BIT_DEF(TESTMODE,7,FORCE_HOST,no,yes), + BIT_DEF(TESTMODE,6,FORCE_ACCESS,no,yes), + BIT_DEF(TESTMODE,5,FORCE_FS,no,yes), + BIT_DEF(TESTMODE,4,FORCE_HS,no,yes), + BIT_DEF(TESTMODE,3,TEST_PACKET,no,yes), + BIT_DEF(TESTMODE,2,TEST_K,no,yes), + BIT_DEF(TESTMODE,1,TEST_J,no,yes), + BIT_DEF(TESTMODE,0,TEST_SE0_NAK,no,yes), + BIT_DEF(PERI_CSR0,8,FLUSHFIFO,none,flush), + BIT_DEF(PERI_CSR0,7,SERV_SETUPEND,none,clear), + BIT_DEF(PERI_CSR0,6,SERV_RXPKTRDY,none,clear), + BIT_DEF(PERI_CSR0,5,SENDSTALL,none,terminate), + BIT_DEF(PERI_CSR0,4,SETUPEND,no,yes), + BIT_DEF(PERI_CSR0,3,DATAEND,no,yes), + BIT_DEF(PERI_CSR0,2,SENTSTALL,no,yes), + BIT_DEF(PERI_CSR0,1,TXPKTRDY,no,yes), + BIT_DEF(PERI_CSR0,0,RXPKTRDY,no,yes), + BIT_DEF(PERI_TXCSR,15,AUTOSET,DMA,CPU), + BIT_DEF(PERI_TXCSR,14,ISO,no,yes), + BIT_DEF(PERI_TXCSR,13,MODE,Rx,Tx), + BIT_DEF(PERI_TXCSR,12,DMAEN,disabled,enabled), + BIT_DEF(PERI_TXCSR,11,FRCDATATOG,no,yes), + BIT_DEF(PERI_TXCSR,10,DMAMODE,no,yes), + BIT_DEF(PERI_TXCSR,6,CLRDATATOG,none,clear), + BIT_DEF(PERI_TXCSR,5,SENTSTALL,no,yes), + BIT_DEF(PERI_TXCSR,4,SENDSTALL,none,issue), + BIT_DEF(PERI_TXCSR,3,FLUSHFIFO,none,flush), + BIT_DEF(PERI_TXCSR,2,UNDERRUN,no,yes), + BIT_DEF(PERI_TXCSR,1,FIFO,empty,notempty), + BIT_DEF(PERI_TXCSR,0,TXPKTRDY,no,yes), + BIT_DEF(PERI_RXCSR,15,AUTOCLEAR,DMA,CPU), + BIT_DEF(PERI_RXCSR,14,ISO,no,yes), + BIT_DEF(PERI_RXCSR,13,DMAEN,disabled,enabled), + BIT_DEF(PERI_RXCSR,12,DISNYET,diable,enable), + BIT_DEF(PERI_RXCSR,12,PID_ERROR,no,yes), + BIT_DEF(PERI_RXCSR,11,DMAMODE,true,none), + BIT_DEF(PERI_RXCSR,7,CLRDATATOG,none,clear), + BIT_DEF(PERI_RXCSR,6,SENTSTALL,no,yes), + BIT_DEF(PERI_RXCSR,5,SENDSTALL,none,issue), + BIT_DEF(PERI_RXCSR,4,FLUSHFIFO,none,flush), + BIT_DEF(PERI_RXCSR,3,DATA,none,error), + BIT_DEF(PERI_RXCSR,2,OVERRUN,no,yes), + BIT_DEF(PERI_RXCSR,1,FIFO,none,full), + BIT_DEF(PERI_RXCSR,0,RXPKTRDY,no,yes), + BIT_DEF(CONFIGDATA,7,MPRXE,none,amalgamation), + BIT_DEF(CONFIGDATA,6,MPTXE,none,splitting), + BIT_DEF(CONFIGDATA,5,BIGENDIAN,Little,Big), + BIT_DEF(CONFIGDATA,4,HBRXE,no,yes), + BIT_DEF(CONFIGDATA,3,HBTXE,no,yes), + BIT_DEF(CONFIGDATA,2,DYNFIFO,no,yes), + BIT_DEF(CONFIGDATA,1,SOFTCONE,no,yes), + BIT_DEF(CONFIGDATA,0,UTMIDATAWIDTH,8b,16b), + BIT_DEF(DEVCTL,7,BDEVICE,A,B), + BIT_DEF(DEVCTL,6,FSDEV,none,full_or_high), + BIT_DEF(DEVCTL,5,LSDEV,none,low), + BIT_DEF(DEVCTL,2,HOSTMODE,no,yes), + BIT_DEF(DEVCTL,1,HOSTREQ,none,initiate), // 'B' device only + BIT_DEF(DEVCTL,0,SESSION,none,start), + BIT_DEF(xXFIFOSZ,4,DPB,single,double), + BIT_DEF(HWVERS,15,RC,full,Candicate), +}; + +#undef _RS + +/*----------------------------------------------------------------------------*/ +// periheral addresses +/*----------------------------------------------------------------------------*/ +// AM1808 ARM Microprocessor +// 2.4 Memory Map Summary +#define EDMA3_0CC0_BASE 0x01C00000UL +#define EDMA3_0TC0_BASE 0x01C08000UL +#define EDMA3_0TC1_BASE 0x01C08400UL +#define PSC0_BASE 0x01C10000UL +#define PLL0_BASE 0x01C11000UL +#define SYSCFG0_BASE 0x01C14000UL +#define TIMER0_BASE 0x01C20000UL +#define TIMER1_BASE 0x01C21000UL +#define I2C0_BASE 0x01C22000UL +#define RTC_BASE 0x01C23000UL +#define PRU_DataRAM0_BASE 0x01C30000UL +#define PRU_DataRAM0_SIZE 0x00000200UL +#define PRU_DataRAM1_BASE 0x01C32000UL +#define PRU_DataRAM1_SIZE 0x00000200UL +#define PRU_INTC_BASE 0x01C34000UL +#define PRU0_BASE 0x01C37000UL +#define PRU1_BASE 0x01C37800UL +#define PRU_InstRAM0_BASE 0x01C38000UL +#define PRU_InstRAM0_SIZE 0x00001000UL +#define PRU_InstRAM1_BASE 0x01C3C000UL +#define PRU_InstRAM1_SIZE 0x00001000UL +#define MMCSD0_BASE 0x01C40000UL +#define UART0_BASE 0x01C42000UL +#define UART1_BASE 0x01D0C000UL +#define UART2_BASE 0x01D0D000UL +#define USB0_BASE 0x01E00000UL +#define LCD0_BASE 0x01E13000UL +#define MPU1_BASE 0x01E14000UL +#define MPU2_BASE 0x01E15000UL +#define PLL1_BASE 0x01E1A000UL +#define MMCSD1_BASE 0x01E1B000UL +#define EMACCRAM_BASE 0x01E20000UL +#define EMACCRAM_SIZE 0x00002000UL +#define EMACC_BASE 0x01E22000UL +#define EMAC_BASE 0x01E23000UL +#define MDIO_BASE 0x01E24000UL +#define GPIOCON_BASE 0x01E26000UL +#define PSC1_BASE 0x01E27000UL +#define I2C1_BASE 0x01E28000UL +#define SYSCFG1_BASE 0x01E2C000UL +#define EDMA3_1CC0_BASE 0x01E30000UL +#define EDMA3_1TC0_BASE 0x01E38000UL +#define ECAP0_BASE 0x01F06000UL +#define ECAP1_BASE 0x01F07000UL +#define ECAP2_BASE 0x01F08000UL +#define TIMER2_BASE 0x01F0C000UL +#define TIMER3_BASE 0x01F0D000UL +#define OnChipRAM_BASE 0x80000000UL +#define OnChipRAM_SISE 0x00020000UL +#define DDR0_BASE 0xB0000000UL +#define ARMLocalROM_BASE 0xFFFD0000UL +#define ARMLocalROM_SIZE 0x00010000UL +#define AINTC_BASE 0xFFFEE000UL +#define ARMLocalRAM_BASE 0xFFFF0000UL +#define ARMLocalRAM_SIZE 0x00002000UL + + + +/*----------------------------------------------------------------------------*/ +// peripheral names +/*----------------------------------------------------------------------------*/ + +#ifndef __MEM_REMAP +#ifdef _MPU1 + #define MPU1 ((MPU_con_t*)MPU1_BASE) +#endif +#ifdef _MPU2 + #define MPU2 ((MPU_con_t*)MPU2_BASE) +#endif +#ifdef _PLL0 + #define PLL0 ((PLL_con_t*)PLL0_BASE) +#endif +#ifdef _PLL1 + #define PLL1 ((PLL_con_t*)PLL1_BASE) +#endif +#ifdef _PSC0 + #define PSC0 ((PSC_con_t*)PSC0_BASE) +#endif +#ifdef _PSC1 + #define PSC1 ((PSC_con_t*)PSC1_BASE) +#endif +#ifdef _SYSCFG0 + #define SYSCFG0 ((SYSCFG0_con_t*)SYSCFG0_BASE) +#endif +#ifdef _SYSCFG1 + #define SYSCFG1 ((SYSCFG1_con_t*)SYSCFG1_BASE) +#endif +#ifdef _AINTC + #define AINTC ((AINTC_con_t*)AINTC_BASE) +#endif +#ifdef _PRU0 + #define PRU0 ((PRU_con_t*)PRU0_BASE) +#endif +#ifdef _PRU1 + #define PRU1 ((PRU_con_t*)PRU1_BASE) +#endif +#ifdef _DDR0 + #define DDR0 ((DDR_con_t*)DDR0_BASE) +#endif +#ifdef _ECAP0 + #define ECAP0 ((ECAP_con_t*)ECAP0_BASE) +#endif +#ifdef _ECAP1 + #define ECAP1 ((ECAP_con_t*)ECAP1_BASE) +#endif +#ifdef _ECAP2 + #define ECAP2 ((ECAP_con_t*)ECAP2_BASE) +#endif +#ifdef _EDMA0 + #define EDMA0 ((EDMA_con_t*)EDMA3_0CC0_BASE) +#endif +#ifdef _EDMA1 + #define EDMA1 ((EDMA_con_t*)EDMA3_1CC0_BASE) +#endif +#ifdef _EMAC + #define EMACC_RAM ((uint8_t*)EMACCRAM_BASE) + #define EMACC ((EMACC_con_t*)EMACC_BASE) + #define EMAC ((EMAC_con_t*)EMAC_BASE) + #define MDIO ((MDIO_con_t*)MDIO_BASE) +#endif +#ifdef _GPIO + #define GPIOCON ((GPIO_con_t*)GPIOCON_BASE) +#endif +#ifdef _I2C0 + #define I2C0 ((I2C_con_t*)I2C0_BASE) +#endif +#ifdef _I2C1 + #define I2C1 ((I2C_con_t*)I2C1_BASE) +#endif +#ifdef _LCD0 + #define LCD0 ((LCD_con_t*)LCD0_BASE) +#endif +#ifdef _MMCSD0 + #define MMCSD0 ((MMCSD_con_t*)MMCSD0_BASE) +#endif +#ifdef _MMCSD1 + #define MMCSD1 ((MMCSD_con_t*)MMCSD1_BASE) +#endif +#ifdef _RTC + #define RTC ((RTC_con_t*)RTC_BASE) +#endif +#ifdef _TIMER0 + #define TIMER0 ((TIMER_con_t*)TIMER0_BASE) +#endif +#ifdef _TIMER1 + #define TIMER1 ((TIMER_con_t*)TIMER1_BASE) +#endif +#ifdef _TIMER2 + #define TIMER2 ((TIMER_con_t*)TIMER2_BASE) +#endif +#ifdef _TIMER3 + #define TIMER3 ((TIMER_con_t*)TIMER3_BASE) +#endif +#ifdef _UART0 + #define UART0 ((UART_con_t*)UART0_BASE) +#endif +#ifdef _UART1 + #define UART1 ((UART_con_t*)UART1_BASE) +#endif +#ifdef _UART2 + #define UART2 ((UART_con_t*)UART2_BASE) +#endif +#ifdef _USB0 + #define USB0 ((USB0_con_t*)USB0_BASE) +#endif + +#else//__MEM_REMAP +#ifdef _MPU1 + _EXTERN MPU_con_t *MPU1; +#endif +#ifdef _MPU2 + _EXTERN MPU_con_t *MPU2; +#endif +#ifdef _PLL0 + _EXTERN PLL_con_t *PLL0; +#endif +#ifdef _PLL1 + _EXTERN PLL_con_t *PLL1; +#endif +#ifdef _PSC0 + _EXTERN PSC_con_t *PSC0; +#endif +#ifdef _PSC1 + _EXTERN PSC_con_t *PSC1; +#endif +#ifdef _SYSCFG0 + _EXTERN SYSCFG0_con_t *SYSCFG0; +#endif +#ifdef _SYSCFG1 + _EXTERN SYSCFG1_con_t *SYSCFG1; +#endif +#ifdef _AINTC + _EXTERN AINTC_con_t *AINTC; +#endif +#ifdef _PRU0 + _EXTERN PRU_con_t *PRU0; +#endif +#ifdef _PRU1 + _EXTERN PRU_con_t *PRU1; +#endif +#ifdef _DDR0 + _EXTERN DDR_con_t *DDR0; +#endif +#ifdef _ECAP0 + _EXTERN ECAP_con_t *ECAP0; +#endif +#ifdef _ECAP1 + _EXTERN ECAP_con_t *ECAP1; +#endif +#ifdef _ECAP2 + _EXTERN ECAP_con_t *ECAP2; +#endif +#ifdef _EDMA0 + _EXTERN EDMA_con_t *EDMA0; +#endif +#ifdef _EDMA1 + _EXTERN EDMA_con_t *EDMA1; +#endif +#ifdef _EMAC + _EXTERN uint8_t *EMACC_RAM; + _EXTERN EMACC_con_t *EMACC; + _EXTERN EMAC_con_t *EMAC; + _EXTERN MDIO_con_t *MDIO; +#endif +#ifdef _GPIO + _EXTERN GPIO_con_t *GPIOCON; +#endif +#ifdef _I2C0 + _EXTERN I2C_con_t *I2C0; +#endif +#ifdef _I2C1 + _EXTERN I2C_con_t *I2C1; +#endif +#ifdef _LCD0 + _EXTERN LCD_con_t *LCD0; +#endif +#ifdef _MMCSD0 + _EXTERN MMCSD_con_t *MMCSD0; +#endif +#ifdef _MMCSD1 + _EXTERN MMCSD_con_t *MMCSD1; +#endif +#ifdef _RTC + _EXTERN RTC_con_t *RTC; +#endif +#ifdef _TIMER0 + _EXTERN TIMER_con_t *TIMER0 +#endif +#ifdef _TIMER1 + _EXTERN TIMER_con_t *TIMER1 +#endif +#ifdef _TIMER2 + _EXTERN TIMER_con_t *TIMER2 +#endif +#ifdef _TIMER3 + _EXTERN TIMER_con_t *TIMER3 +#endif +#ifdef _UART0 + _EXTERN UART_con_t *UART0; +#endif +#ifdef _UART1 + _EXTERN UART_con_t *UART1; +#endif +#ifdef _UART2 + _EXTERN UART_con_t *UART2; +#endif +#ifdef _USB0 + _EXTERN USB0_con_t *USB0; +#endif +#endif//__MEM_REMAP + + +#endif//__AM18X_MAP_H__ +// to generate am18x_map_s.h, run the command +// sed -n -e "/^#define/{ s/\([^0]0x[0-9a-fA-F]\+\)UL/\1/g;p; }" am18x_map.h >am18x_map_s.h diff --git a/lib/am18x-lib/inc/am18x_map_s.h b/lib/am18x-lib/inc/am18x_map_s.h new file mode 100644 index 000000000..d4a00046f --- /dev/null +++ b/lib/am18x-lib/inc/am18x_map_s.h @@ -0,0 +1,1313 @@ +#define __AM18X_MAP_H__ +#define _EXTERN extern +#define _RS(b,a) (((b) - (a) - 0x4) >> 2) +#define MPU1_PROGxMPxAR_MASK 0xFFFFFC00 +#define MPU2_PROGxMPxAR_MASK 0xFFFF0000 +#define PROGxMPPA_AIDn_MASK(n) (0x1 << (10 + (n))) +#define PROGxMPPA_AIDn_denied(n) (0x0 << (10 + (n))) +#define PROGxMPPA_AIDn_granted(n) (0x1 << (10 + (n))) +#define MPU_REVID 0x4E810101 +#define CONFIG_ADDR_WIDTH_MASK (0xFF << 24) +#define CONFIG_NUM_FIXED_MASK (0xF << 20) +#define CONFIG_NUM_PROG_MASK (0xF << 16) +#define CONFIG_NUM_AIDS_MASK (0xF << 12) +#define CONFIG_ASSUME_ALLOWED_MASK (0x1 << 0) +#define CONFIG_ASSUME_ALLOWED_no (0x0 << 0) +#define CONFIG_ASSUME_ALLOWED_yes (0x1 << 0) +#define FXD_MPSAR_VAL 0xB0000000 +#define FXD_MPEAR_VAL 0xB0007FFF +#define FLTSTAT_MSTID_MASK (0xFF << 16) +#define FLTSTAT_PRIVID_MASK (0xF << 9) +#define FLTSTAT_TYPE_MASK (0x3F << 0) +#define FLTSTAT_TYPE_NoFault (0x0 << 0) +#define FLTSTAT_TYPE_UserExecute (0x1 << 0) +#define FLTSTAT_TYPE_UserWrite (0x2 << 0) +#define FLTSTAT_TYPE_UserRead (0x4 << 0) +#define FLTSTAT_TYPE_SupervisorExecute (0x8 << 0) +#define FLTSTAT_TYPE_SupervisorWrite (0x10 << 0) +#define FLTSTAT_TYPE_CacheWriteBack (0x12 << 0) +#define FLTSTAT_TYPE_SupervisorRead (0x20 << 0) +#define FLTSTAT_TYPE_CacheLineFill (0x3F << 0) +#define PLL0_REVID 0x44813C00 +#define PLL1_REVID 0x44814400 +#define RSTYPE_PLLSWRST_MASK (0x1 << 2) +#define RSTYPE_PLLSWRST_no (0x0 << 2) +#define RSTYPE_PLLSWRST_yes (0x1 << 2) +#define RSTYPE_XWRST_MASK (0x1 << 1) +#define RSTYPE_XWRST_no (0x0 << 1) +#define RSTYPE_XWRST_yes (0x1 << 1) +#define RSTYPE_POR_MASK (0x1 << 0) +#define RSTYPE_POR_no (0x0 << 0) +#define RSTYPE_POR_yes (0x1 << 0) +#define RSCTRL_SWRST_MASK (0x1 << 16) +#define RSCTRL_SWRST_yes (0x0 << 16) +#define RSCTRL_SWRST_no (0x1 << 16) +#define RSCTRL_KEY_MASK (0xFFFF << 0) +#define RSCTRL_KEY_locked (0x3 << 0) +#define RSCTRL_KEY_unlocked (0xC << 0) +#define RSCTRL_KEY_unlock (0x5A69 << 0) +#define PLLCTL_EXTCLKSRC_MASK (0x1 << 9) +#define PLLCTL_EXTCLKSRC_oscin (0x0 << 9) +#define PLLCTL_EXTCLKSRC_PLL1sysclk3 (0x1 << 9) +#define PLLCTL_CLKMODE_MASK (0x1 << 8) +#define PLLCTL_CLKMODE_crystal (0x0 << 8) +#define PLLCTL_CLKMODE_wave (0x1 << 8) +#define PLLCTL_PLLENSRC_MASK (0x1 << 5) +#define PLLCTL_PLLENSRC_cleared (0x0 << 5) +#define PLLCTL_PLLENSRC_none (0x1 << 5) +#define PLLCTL_PLLRST_MASK (0x1 << 3) +#define PLLCTL_PLLRST_asserted (0x0 << 3) +#define PLLCTL_PLLRST_deasserted (0x1 << 3) +#define PLLCTL_PLLPWRDN_MASK (0x1 << 1) +#define PLLCTL_PLLPWRDN_no (0x0 << 1) +#define PLLCTL_PLLPWRDN_yes (0x1 << 1) +#define PLLCTL_PLLEN_MASK (0x1 << 0) +#define PLLCTL_PLLEN_no (0x0 << 0) +#define PLLCTL_PLLEN_yes (0x1 << 0) +#define OCSEL_OCSRC_MASK (0x1F << 0) +#define OCSEL_OCSRC_oscin (0x14 << 0) +#define OCSEL_OCSRC_PLLsysclkx(x) ((0x16 + (x)) << 0) +#define OCSEL_OCSRC_PLL1obsclk (0x1E << 0) +#define OCSEL_OCSRC_Disabled (0x1F << 0) +#define PLLM_MASK (0x1F << 0) +#define PLLM_WR(m) (((m) - 0x1) << 0) +#define XXXDIVx_DxEN_MASK (0x1 << 15) +#define XXXDIVx_DxEN_disable (0x0 << 15) +#define XXXDIVx_DxEN_enable (0x1 << 15) +#define XXXDIVx_RATIO_MASK (0x1F << 0) +#define XXXDIVx_RATIO_WR(r) (((r) - 0x1) << 0) +#define PLLDIVxA_IDX_1 0x0 +#define PLLDIVxA_IDX_2 0x1 +#define PLLDIVxA_IDX_3 0x2 +#define PLLCMD_GOSET_MASK (0x1 << 0) +#define PLLCMD_GOSET_clear (0x0 << 0) +#define PLLCMD_GOSET_initiate (0x1 << 0) +#define PLLSTAT_STABLE_MASK (0x1 << 2) +#define PLLSTAT_STABLE_no (0x0 << 2) +#define PLLSTAT_STABLE_yes (0x1 << 2) +#define PLLSTAT_GOSTAT_MASK (0x1 << 0) +#define PLLSTAT_GOSTAT_done (0x0 << 0) +#define PLLSTAT_GOSTAT_in_progress (0x1 << 0) +#define ALNCTL_ALNx_MASK(x) (0x1 << ((x) - 1)) +#define ALNCTL_ALNx_no(x) (0x0 << ((x) - 1)) +#define ALNCTL_ALNx_yes(x) (0x1 << ((x) - 1)) +#define DCHANGE_SYSx_MASK(x) (0x1 << ((x) - 1)) +#define DCHANGE_SYSx_none(x) (0x0 << ((x) - 1)) +#define DCHANGE_SYSx_modified(x) (0x1 << ((x) - 1)) +#define CKEN_OBSEN_MASK (0x1 << 1) +#define CKEN_OBSEN_disable (0x0 << 1) +#define CKEN_OBSEN_enable (0x1 << 1) +#define CKEN_AUXEN_MASK (0x1 << 0) +#define CKEN_AUXEN_disable (0x0 << 0) +#define CKEN_AUXEN_enable (0x1 << 0) +#define CKSTAT_OBSEN_MASK (0x1 << 1) +#define CKSTAT_OBSEN_off (0x0 << 1) +#define CKSTAT_OBSEN_on (0x1 << 1) +#define CKSTAT_AUXEN_MASK (0x1 << 0) +#define CKSTAT_AUXEN_off (0x0 << 0) +#define CKSTAT_AUXEN_on (0x1 << 0) +#define SYSTAT_SYSxON_MASK(X) (0x1 << ((x) - 1)) +#define SYSTAT_SYSxON_off(x) (0x0 << ((x) - 1)) +#define SYSTAT_SYSxON_on(x) (0x1 << ((x) - 1)) +#define PLLDIVxB_IDX_4 0x0 +#define PLLDIVxB_IDX_5 0x1 +#define PLLDIVxB_IDX_6 0x2 +#define PLLDIVxB_IDX_7 0x3 +#define MODULE_NR_PER_PSC 32 +#define PSC_REVID 0x44825A00 +#define PTCMD_GO1 (0x1 << 1) +#define PTCMD_GO0 (0x1 << 0) +#define PTSTAT_GO1_MASK (0x1 << 1) +#define PTSTAT_GO1_no (0x0 << 1) +#define PTSTAT_GO1_yes (0x1 << 1) +#define PTSTAT_GO0_MASK (0x1 << 0) +#define PTSTAT_GO0_no (0x0 << 0) +#define PTSTAT_GO0_yes (0x1 << 0) +#define PDSTATx_EMUIHB_MASK (0x1 << 11) +#define PDSTATx_EMUIHB_unactive (0x0 << 11) +#define PDSTATx_EMUIHB_active (0x1 << 11) +#define PDSTATx_PORDONE_MASK (0x1 << 9) +#define PDSTATx_PORDONE_no (0x0 << 9) +#define PDSTATx_PORDONE_yes (0x1 << 9) +#define PDSTATx_POR_MASK (0x1 << 8) +#define PDSTATx_POR_asserted (0x0 << 8) +#define PDSTATx_POR_deasserted (0x1 << 8) +#define PDSTATx_STATE_MASK (0x1F << 0) +#define PDSTATx_STATE_off (0x0 << 0) +#define PDSTATx_STATE_on (0x1 << 0) +#define PDSTATx_STATE_in_transition(x) (0x10 <= (x) && (x) <= 0x1A) +#define PDCTLx_WAKECNT_MASK (0xFF << 16) +#define PDCTLx_GOOD2ACCESS_MASK (0xF << 20) +#define PDCTLx_ON2GOOD_MASK (0xF << 16) +#define PDCTLx_PDMODE_MASK (0xF << 12) +#define PDCTLx_PDMODE_on (0xF << 12) +#define PDCTLx_EMUIHBIE_MASK (0x1 << 9) +#define PDCTLx_EMUIHBIE_disable (0x0 << 9) +#define PDCTLx_EMUIHBIE_enable (0x1 << 9) +#define PDCTLx_NEXT_MASK (0x1 << 0) +#define PDCTLx_NEXT_off (0x0 << 0) +#define PDCTLx_NEXT_on (0x1 << 0) +#define PDCFGx_PD_LOCK_MASK (0x1 << 3) +#define PDCFGx_PD_LOCK_locked (0x0 << 3) +#define PDCFGx_PD_LOCK_unlocked (0x1 << 3) +#define PDCFGx_ICEPICK_MASK (0x1 << 2) +#define PDCFGx_ICEPICK_unpresent (0x0 << 2) +#define PDCFGx_ICEPICK_present (0x1 << 2) +#define PDCFGx_RAM_PSM_MASK (0x1 << 1) +#define PDCFGx_RAM_PSM_no (0x0 << 1) +#define PDCFGx_RAM_PSM_yes (0x1 << 1) +#define PDCFGx_ALWAYSON_MASK (0x1 << 0) +#define PDCFGx_ALWAYSON_no (0x0 << 0) +#define PDCFGx_ALWAYSON_yes (0x1 << 0) +#define MDSTATx_EMUIHB_MASK (0x1 << 17) +#define MDSTATx_EMUIHB_no (0x0 << 17) +#define MDSTATx_EMUIHB_yes (0x1 << 17) +#define MDSTATx_EMURST_MASK (0x1 << 16) +#define MDSTATx_EMURST_no (0x0 << 16) +#define MDSTATx_EMURST_yes (0x1 << 16) +#define MDSTATx_MCKOUT_MASK (0x1 << 12) +#define MDSTATx_MCKOUT_off (0x0 << 12) +#define MDSTATx_MCKOUT_on (0x1 << 12) +#define MDSTATx_MRST_MASK (0x1 << 10) +#define MDSTATx_MRST_asserted (0x0 << 10) +#define MDSTATx_MRST_deasserted (0x1 << 10) +#define MDSTATx_LRSTDONE_MASK (0x1 << 9) +#define MDSTATx_LRSTDONE_yes (0x0 << 9) +#define MDSTATx_LRSTDONE_no (0x1 << 9) +#define MDSTATx_LRST_MASK (0x1 << 8) +#define MDSTATx_LRST_asserted (0x0 << 8) +#define MDSTATx_LRST_deasserted (0x1 << 8) +#define MDSTATx_STATE_MASK (0x3F << 0) +#define MDSTATx_STATE_SwRstDisable (0x0) +#define MDSTATx_STATE_SyncReset (0x1) +#define MDSTATx_STATE_Disable (0x2) +#define MDSTATx_STATE_Enable (0x3) +#define MDSTATx_STATE_in_transition(x) (0x4 <= (x) && (x) <= 0x3F) +#define MDCTLx_FORCE_MASK (0x1 << 31) +#define MDCTLx_FORCE_disabled (0x0 << 31) +#define MDCTLx_FORCE_enabled (0x1 << 31) +#define MDCTLx_EMUIHBIE_MASK (0x1 << 10) +#define MDCTLx_EMUIHBIE_disable (0x0 << 10) +#define MDCTLx_EMUIHBIE_enable (0x1 << 10) +#define MDCTLx_EMURSTIE_MASK (0x1 << 9) +#define MDCTLx_EMURSTIE_disable (0x0 << 9) +#define MDCTLx_EMURSTIE_enable (0x1 << 9) +#define MDCTLx_LRST_MASK (0x1 << 8) +#define MDCTLx_LRST_assert (0x0 << 8) +#define MDCTLx_LRST_deassert (0x1 << 8) +#define MDCTLx_STATE_MASK (0x7 << 0) +#define MDCTLx_STATE_SwRstDisable (0x0 << 0) +#define MDCTLx_STATE_SyncReset (0x1 << 0) +#define MDCTLx_STATE_Disable (0x2 << 0) +#define MDCTLx_STATE_Enable (0x3 << 0) +#define SYSCFG0_REVID 0x4E840102 +#define BOOTCFG_BOOTMODE_MASK 0x001F +#define BOOTCFG_BOOTMODE_I2C0EEPROM 0x00 +#define BOOTCFG_BOOTMODE_I2C0SLAVE 0x01 +#define BOOTCFG_BOOTMODE_NOR 0x02 +#define BOOTCFG_BOOTMODE_HPI 0x04 +#define BOOTCFG_BOOTMODE_I2C1EEPROM 0x06 +#define BOOTCFG_BOOTMODE_I2C1SLAVE 0x07 +#define BOOTCFG_BOOTMODE_SPI0EEPROM 0x08 +#define BOOTCFG_BOOTMODE_SPI1EEPROM 0x09 +#define BOOTCFG_BOOTMODE_SPI0FLASH 0x0A +#define BOOTCFG_BOOTMODE_SPI1FLASH 0x0C +#define BOOTCFG_BOOTMODE_NAND8 0x0E +#define BOOTCFG_BOOTMODE_NAND16 0x10 +#define BOOTCFG_BOOTMODE_SPI0SLAVE 0x12 +#define BOOTCFG_BOOTMODE_SPI1SLAVE 0x13 +#define BOOTCFG_BOOTMODE_UART2 0x14 +#define BOOTCFG_BOOTMODE_UART0 0x16 +#define BOOTCFG_BOOTMODE_UART1 0x17 +#define BOOTCFG_BOOTMODE_MMCSD0 0x1C +#define BOOTCFG_BOOTMODE_EMU 0x1E +#define KICK0R_UNLOCK 0x83E70B13 +#define KICK0R_LOCK 0x00000000 +#define KICK1R_UNLOCK 0x95A4F1E0 +#define KICK1R_LOCK 0x00000000 +#define HOST0CFG_BOOTRDY_MASK (0x1 << 0) +#define HOST0CFG_BOOTRDY_reset (0x0 << 0) +#define HOST0CFG_BOOTRDY_released (0x1 << 0) +#define IRAWSTAT_ADDRERR_MASK (0x1 << 1) +#define IRAWSTAT_ADDRERR_unset (0x0 << 1) +#define IRAWSTAT_ADDRERR_set (0x1 << 1) +#define IRAWSTAT_PROTERR_MASK (0x1 << 0) +#define IRAWSTAT_PROTERR_unset (0x0 << 0) +#define IRAWSTAT_PROTERR_set (0x1 << 0) +#define IENSTAT_ADDRERR_MASK (0x1 << 1) +#define IENSTAT_ADDRERR_unset (0x0 << 1) +#define IENSTAT_ADDRERR_set (0x1 << 1) +#define IENSTAT_PROTERR_MASK (0x1 << 0) +#define IENSTAT_PROTERR_unset (0x0 << 0) +#define IENSTAT_PROTERR_set (0x1 << 0) +#define IENSET_ADDRERR_EN_enable (0x1 << 1) +#define IENSET_PROTERR_EN_enable (0x1 << 0) +#define IENCLR_ADDRERR_EN_enable (0x1 << 1) +#define IENCLR_PROTERR_EN_enable (0x1 << 0) +#define EOI_EOIVECT_MASK (0xFF << 0) +#define FLTSTAT_ID_MASK (0xFF << 24) +#define MSTPRIx_IDX(x) ((x) >> 3) +#define MSTPRIx_MASK(x) (0x7 << (((x) & 0x7) << 2)) +#define CHIPSIG_X_MASK(i) (0x1 << (i)) +#define CHIPSIG_X_assert(i) (0x1 << (i)) +#define CHIPSIG_X_clear(i) (0x1 << (i)) +#define CFGCHIP0_PLL_MASTER_LOCK_MASK (0x1 << 4) +#define CFGCHIP0_PLL_MASTER_LOCK_no (0x0 << 4) +#define CFGCHIP0_PLL_MASTER_LOCK_yes (0x1 << 4) +#define CFGCHIP0_EDMA30TCxDBS_MASK(x) (0x3 << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_16B(x) (0x0 << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_32B(x) (0x1 << (2*(x))) +#define CFGCHIP0_EDMA30TCxDBS_64B(x) (0x2 << (2*(x))) +#define CFGCHIP1_EDMA31TC0DBS_MASK (0x3 << 13) +#define CFGCHIP1_EDMA31TC0DBS_16B (0x0 << 13) +#define CFGCHIP1_EDMA31TC0DBS_32B (0x1 << 13) +#define CFGCHIP1_EDMA31TC0DBS_64B (0x2 << 13) +#define CFGCHIP2_USB0OTGMODE_MASK (0x3 << 13) +#define CFGCHIP2_USB0OTGMODE_none (0x0 << 13) +#define CFGCHIP2_USB0OTGMODE_host (0x1 << 13) +#define CFGCHIP2_USB0OTGMODE_device (0x2 << 13) +#define CFGCHIP2_USB0OTGMODE_VBUSlow (0x3 << 13) +#define CFGCHIP2_USB0REFFREQ_MASK (0xF << 0) +#define CFGCHIP2_USB0REFFREQ_12MHz (0x1 << 0) +#define CFGCHIP2_USB0REFFREQ_24MHz (0x2 << 0) +#define CFGCHIP2_USB0REFFREQ_48MHz (0x3 << 0) +#define CFGCHIP2_USB0REFFREQ_19_2MHz (0x4 << 0) +#define CFGCHIP2_USB0REFFREQ_38_4MHz (0x5 << 0) +#define CFGCHIP2_USB0REFFREQ_13MHz (0x6 << 0) +#define CFGCHIP2_USB0REFFREQ_26MHz (0x7 << 0) +#define CFGCHIP2_USB0REFFREQ_20MHz (0x8 << 0) +#define CFGCHIP2_USB0REFFREQ_40MHz (0x9 << 0) +#define CFGCHIP3_RMII_SEL_MASK (0x1 << 8) +#define CFGCHIP3_RMII_SEL_mii (0x0 << 8) +#define CFGCHIP3_RMII_SEL_rmii (0x1 << 8) +#define CFGCHIP3_UPP_TX_CLKSRC_MASK (0x1 << 6) +#define CFGCHIP3_UPP_TX_CLKSRC_asyn3 (0x0 << 6) +#define CFGCHIP3_UPP_TX_CLKSRC_2xTXCLK (0x1 << 6) +#define CFGCHIP3_PLL1_MASTER_LOCK_MASK (0x1 << 5) +#define CFGCHIP3_PLL1_MASTER_LOCK_no (0x0 << 5) +#define CFGCHIP3_PLL1_MASTER_LOCK_yes (0x1 << 5) +#define CFGCHIP3_ASYNC3_CLKSRC_MASK (0x1 << 4) +#define CFGCHIP3_ASYNC3_CLKSRC_pll0 (0x0 << 4) +#define CFGCHIP3_ASYNC3_CLKSRC_pll1 (0x1 << 4) +#define CFGCHIP3_PRUEVTSEL_MASK (0x1 << 3) +#define CFGCHIP3_PRUEVTSEL_normal (0x0 << 3) +#define CFGCHIP3_PRUEVTSEL_alternate (0x1 << 3) +#define CFGCHIP3_DIV45PENA_MASK (0x1 << 2) +#define CFGCHIP3_DIV45PENA_no (0x0 << 2) +#define CFGCHIP3_DIV45PENA_yes (0x1 << 2) +#define CFGCHIP3_EMA_CLKSRC_MASK (0x1 << 1) +#define CFGCHIP3_EMA_CLKSRC_sysclk3 (0x0 << 1) +#define CFGCHIP3_EMA_CLKSRC_pll_out (0x1 << 1) +#define CFGCHIP4_AMUTECLR0_MASK (0x1 << 0) +#define CFGCHIP4_AMUTECLR0_none (0x0 << 0) +#define CFGCHIP4_AMUTECLR0_clr_int (0x1 << 0) +#define CFGCHIP1_EDMA31TC0DBS_MASK (0x3 << 13) +#define CFGCHIP1_EDMA31TC0DBS_16B (0x0 << 13) +#define CFGCHIP1_EDMA31TC0DBS_32B (0x1 << 13) +#define CFGCHIP1_EDMA31TC0DBS_64B (0x2 << 13) +#define VTPIO_CTL_F_MASK (0x7 << 0) +#define VTPIO_CTL_F_Enable (0x7 << 0) +#define VTPIO_CTL_D_MASK (0x7 << 3) +#define VTPIO_CTL_D_100PS (0x6 << 3) +#define VTPIO_CTL_VREFTAP_MASK (0x3 << 16) +#define VTPIO_CTL_VREFTAP_50PS (0x0 << 16) +#define DEEPSLEEP_SLEEPCOUNT_MASK (0xFFFF << 0) +#define DEEPSLEEP_SLEEPCOUNT_VAL(x) (((x) & 0xFFFF) << 0) +#define CR_PRHOLDMODE_MASK (0x1 << 4) +#define CR_PRHOLDMODE_disable (0x0 << 4) +#define CR_PRHOLDMODE_enable (0x1 << 4) +#define CR_NESTMODE_MASK (0x3 << 2) +#define CR_NESTMODE_None (0x0 << 2) +#define CR_NESTMODE_Individual (0x1 << 2) +#define CR_NESTMODE_Global (0x2 << 2) +#define CR_NESTMODE_Manual (0x3 << 2) +#define GER_ENABLE_MASK (0x1 << 0) +#define GER_ENABLE_no (0x0 << 0) +#define GER_ENABLE_yes (0x1 << 0) +#define GNLR_OVERRIDE_SET (0x1 << 31) +#define GNLR_NESTLVL_MASK (0xFF << 0) +#define GNLR_NESTLVL_VAL(x) ((x) << 0) +#define AINTC_IDX_SET 0x00 +#define AINTC_IDX_CLR 0x01 +#define XIxR_INDEX_MASK (0x7F << 0) +#define XIxR_INDEX_VAL(x) ((x) << 0) +#define HIEIxR_INDEX_MASK (0x1 << 0) +#define HIEIxR_INDEX_FIQ (0x0 << 0) +#define HIEIxR_INDEX_IRQ (0x1 << 0) +#define VSR_SIZE_MASK (0xFF << 0) +#define VSR_SIZE_VAL(x) (((x) >> 2) - 1) +#define GPIR_NONE_MASK (0x1 << 31) +#define GPIR_NONE_no (0x0 << 31) +#define GPIR_NONE_yes (0x1 << 31) +#define GPIR_PRI_INDX_MASK (0x3FF << 0) +#define SXXRx_WR_X(x) ((x) >> 5) +#define SXXRx_WR_VAL(x) (0x1 << ((x) & 0x1F)) +#define EXRx_WR_X(x) ((x) >> 5) +#define EXRx_WR_VAL(x) (0x1 << ((x) & 0x1F)) +#define CMRx_X(x) ((x) >> 2) +#define CMRx_MASK(x) (0xFF << (((x) & 0x3) << 3)) +#define CMRx_VAL(x,v) ((0xFF & (v)) << (((x) & 0x3) << 3)) +#define AINTC_IDX_FIQ 0x00 +#define AINTC_IDX_IRQ 0x01 +#define HIPIRx_NONE_MASK (0x1 << 31) +#define HIPIRx_NONE_no (0x0 << 31) +#define HIPIRx_NONE_yes (0x1 << 31) +#define HIPIRx_PRI_INDX_MASK (0x3FF << 0) +#define HINLRx_OVERRIDE_SET (0x1 << 31) +#define HINLRx_NEST_LVL_MASK (0x1FF << 0) +#define HIER_IRQ_MASK (0x1 << 1) +#define HIER_IRQ_disabled (0x0 << 1) +#define HIER_IRQ_enabled (0x1 << 1) +#define HIER_FIQ_MASK (0x1 << 0) +#define HIER_FIQ_disabled (0x0 << 0) +#define HIER_FIQ_enabled (0x1 << 0) +#define CONTROL_PCRESETVAL_MASK (0xFFFF << 16) +#define STATUS_PCOUNTER_MASK 0x0000FFFF +#define WAKEUP_ENABLES_MASK(x) (0x1 << (x)) +#define WAKEUP_ENABLES_no(x) (0x0 << (x)) +#define WAKEUP_ENABLES_yes(x) (0x1 << (x)) +#define CONTABBLKIDX0_C25_MASK (0xF << 16) +#define CONTABBLKIDX0_C24_MASK (0xF << 0) +#define CONTABPROPTR_C29_MASK (0xFFFF << 16) +#define CONTABPROPTR_C28_MASK (0xFFFF << 0) +#define CONTABPROPTR_C31_MASK (0xFFFF << 16) +#define CONTABPROPTR_C30_MASK (0xFFFF << 0) +#define DDR0_REVID (0x40311B1F) +#define SDCR_DDR2TERM_MASK ((0x1 << 27) | (0x1 << 21)) +#define SDCR_DDR2TERM_disable (0x0) +#define SDCR_DDR2TERM_default (0x1 << 27) +#define SDCR_DDRDRIVE_MASK ((0x1 << 24) | (0x1 << 18)) +#define SDCR_DDRDRIVE_full ((0x0 << 24) | (0x0 << 18)) +#define SDCR_DDRDRIVE_half ((0x0 << 24) | (0x1 << 18)) +#define SDCR_DDRDRIVE_quarter ((0x1 << 24) | (0x0 << 18)) +#define SDCR_DDRDRIVE_3quarter ((0x1 << 24) | (0x1 << 18)) +#define SDCR_CL_MASK (0x7 << 9) +#define SDCR_CL_VAL(x) ((x) << 9) +#define SDCR_IBANK_MASK (0x7 << 4) +#define SDCR_IBANK_1bank (0x0 << 4) +#define SDCR_IBANK_2banks (0x1 << 4) +#define SDCR_IBANK_4banks (0x2 << 4) +#define SDCR_IBANK_8banks (0x3 << 4) +#define SDCR_PAGESIZE_MASK (0x7 << 0) +#define SDCR_PAGESIZE_256w8col (0x0 << 0) +#define SDCR_PAGESIZE_512w9col (0x1 << 0) +#define SDCR_PAGESIZE_1kw10col (0x2 << 0) +#define SDCR_PAGESIZE_2kw11col (0x3 << 0) +#define SDRCR_RR_MASK (0xFFFF << 0) +#define SDRCR_RR_VAL(x) ((x) << 0) +#define SDTIMR1_TRFC_MASK (0x7 << 25) +#define SDTIMR1_TRFC_VAL(x) ((x) << 25) +#define SDTIMR1_TRP_MASK (0x7 << 22) +#define SDTIMR1_TRP_VAL(x) ((x) << 22) +#define SDTIMR1_TRCD_MASK (0x7 << 19) +#define SDTIMR1_TRCD_VAL(x) ((x) << 19) +#define SDTIMR1_TWR_MASK (0x7 << 16) +#define SDTIMR1_TWR_VAL(x) ((x) << 16) +#define SDTIMR1_TRAS_MASK (0x1F << 11) +#define SDTIMR1_TRAS_VAL(x) ((x) << 11) +#define SDTIMR1_TRC_MASK (0x1F << 6) +#define SDTIMR1_TRC_VAL(x) ((x) << 6) +#define SDTIMR1_TRRD_MASK (0x7 << 3) +#define SDTIMR1_TRRD_VAL(x) ((x) << 3) +#define SDTIMR1_TWTR_MASK (0x3 << 0) +#define SDTIMR1_TWTR_VAL(x) ((x) << 0) +#define SDTIMR2_TRASMAX_MASK (0xF << 27) +#define SDTIMR2_TRASMAX_VAL(x) ((x) << 27) +#define SDTIMR2_TXP_MASK (0x3 << 25) +#define SDTIMR2_TXP_VAL(x) ((x) << 25) +#define SDTIMR2_TODT_MASK (0x3 << 23) +#define SDTIMR2_TODT_VAL(x) ((x) << 23) +#define SDTIMR2_TXSNR_MASK (0x7F << 16) +#define SDTIMR2_TXSNR_VAL(x) ((x) << 16) +#define SDTIMR2_TXSRD_MASK (0xFF << 8) +#define SDTIMR2_TXSRD_VAL(x) ((x) << 8) +#define SDTIMR2_TRTP_MASK (0x7 << 5) +#define SDTIMR2_TRTP_VAL(x) ((x) << 5) +#define SDTIMR2_TCKE_MASK (0x1F << 0) +#define SDTIMR2_TCKE_VAL(x) ((x) << 0) +#define SDCR2_PASR_MASK (0x7 << 16) +#define SDCR2_PASR_4banks (0x0 << 16) +#define SDCR2_PASR_2banks (0x1 << 16) +#define SDCR2_PASR_1banks (0x2 << 16) +#define SDCR2_PASR_half_bank (0x5 << 16) +#define SDCR2_PASR_quarter_bank (0x6 << 16) +#define SDCR2_ROWSIZE_MASK (0x7 << 0) +#define SDCR2_ROWSIZE_VAL(x) (((x) - 9) << 0) +#define PBBPR_PROLDCOUNT_MASK (0xFF << 0) +#define PBBPR_PROLDCOUNT_VAL(x) (((x) - 1) << 0) +#define PCC_CNTR2CFG_MASK (0xF << 16) +#define PCC_CNTR2CFG_VAL(x) ((x) << 16) +#define PCC_CNTR1CFG_MASK (0xF << 0) +#define PCC_CNTR1CFG_VAL(x) ((x) << 0) +#define PCMRS_MSTID2_MASK (0xFF << 24) +#define PCMRS_MSTID2_VAL(x) ((x) << 24) +#define PCMRS_REGIONSEL2_MASK (0xF << 16) +#define PCMRS_REGIONSEL2_access (0x0 << 16) +#define PCMRS_REGIONSEL2_register (0x7 << 16) +#define PCMRS_MSTID1_MASK (0xFF << 8) +#define PCMRS_MSTID1_VAL(x) ((x) << 8) +#define PCMRS_REGIONSEL1_MASK (0xF << 0) +#define PCMRS_REGIONSEL1_access (0x0 << 0) +#define PCMRS_REGIONSEL1_register (0x7 << 0) +#define DRPYC1R_RL_MASK (0x7 << 0) +#define DRPYC1R_RL_VAL(x) ((x) << 0) +#define ECCTL1_FREESOFT_MASK (0x3 << 14) +#define ECCTL1_FREESOFT_stop (0x0 << 14) +#define ECCTL1_FREESOFT_runs (0x1 << 14) +#define ECCTL1_FREESOFT_none (0x3 << 14) +#define ECCTL1_PRESCALE_MASK (0x1F << 9) +#define ECCTL1_PRESCALE_VAL(x) (((x) & 0x3E) << 8) +#define ECCTL1_CTRRSTx_MASK(x) (0x1 << (((x) << 1) + 1)) +#define ECCTL1_CTRRSTx_none(x) (0x0 << (((x) << 1) + 1)) +#define ECCTL1_CTRRSTx_reset(x) (0x1 << (((x) << 1) + 1)) +#define ECCTL1_CTRPOLx_MASK(x) (0x1 << (((x) << 1) + 0)) +#define ECCTL1_CTRPOLx_rising(x) (0x0 << (((x) << 1) + 0)) +#define ECCTL1_CTRPOLx_falling(x) (0x1 << (((x) << 1) + 0)) +#define ECCTL2_SYNCO_SEL_MASK (0x3 << 6) +#define ECCTL2_SYNCO_SEL_pass (0x0 << 6) +#define ECCTL2_SYNCO_SEL_ctr_equ_prd (0x1 << 6) +#define ECCTL2_SYNCO_SEL_disable (0x2 << 6) +#define ECCTL2_STOP_WARP_MASK (0x3 << 1) +#define ECCTL2_STOP_WARP_VAL(x) ((x) << 1) +#define ECINT_MASK(x) (0x1 << (x)) +#define ECINT_deassert(x) (0x0 << (x)) +#define ECINT_assert(x) (0x1 << (x)) +#define ECAP_REVID 0x44D22100 +#define OPT_PRIVID_MASK (0xF << 24) +#define OPT_PRIVID_X(x) (((x) & 0xF) << 24) +#define OPT_TCC_MASK (0x3F << 12) +#define OPT_TCC_X(x) (((x) & 0x3F) << 12) +#define OPT_FWID_MASK (0x7 << 8) +#define OPT_FWID_8b (0x0 << 8) +#define OPT_FWID_16b (0x1 << 8) +#define OPT_FWID_32b (0x2 << 8) +#define OPT_FWID_64b (0x3 << 8) +#define OPT_FWID_128b (0x4 << 8) +#define OPT_FWID_256b (0x5 << 8) +#define OPT_PRI_MASK (0x7 << 4) +#define PARAM_BCNT_MASK (0xFFFF << 16) +#define PARAM_ACNT_MASK (0xFFFF << 0) +#define PARAM_DSTBIDX_MASK (0xFFFF << 16) +#define PARAM_SRCBIDX_MASK (0xFFFF << 0) +#define PARAM_BCNTRLD_MASK (0xFFFF << 16) +#define PARAM_LINK_MASK (0xFFFF << 0) +#define PARAM_DSTCIDX_MASK (0xFFFF << 16) +#define PARAM_SRCCIDX_MASK (0xFFFF << 0) +#define PARAM_CCNT_MASK (0xFFFF << 0) +#define ExR_En_MASK(n) (0x1 << (n)) +#define ExR_En_none(n) (0x0 << (n)) +#define ExR_En_asserted(n) (0x1 << (n)) +#define ExR_En_clear(n) (0x1 << (n)) +#define ExR_En_set(n) (0x1 << (n)) +#define CER_En_MASK(n) (0x1 << (n)) +#define CER_En_none(n) (0x0 << (n)) +#define CER_En_prioritized(n) (0x1 << (n)) +#define EExR_En_MASK(n) (0x1 << (n)) +#define EExR_En_no(n) (0x0 << (n)) +#define EExR_En_yes(n) (0x1 << (n)) +#define EExR_En_clear(n) (0x1 << (n)) +#define EExR_En_set(n) (0x1 << (n)) +#define SExR_En_MASK(n) (0x1 << (n)) +#define SExR_En_none(n) (0x0 << (n)) +#define SExR_En_stored(n) (0x1 << (n)) +#define SExR_En_clear(n) (0x1 << (n)) +#define IExR_En_MASK(n) (0x1 << (n)) +#define IExR_En_no(n) (0x0 << (n)) +#define IExR_En_yes(n) (0x1 << (n)) +#define IExR_En_clear(n) (0x1 << (n)) +#define IExR_En_set(n) (0x1 << (n)) +#define IxR_En_MASK(n) (0x1 << (n)) +#define IxR_En_none(n) (0x0 << (n)) +#define IxR_En_pending(n) (0x1 << (n)) +#define IxR_En_clear(n) (0x1 << (n)) +#define QER_En_MASK(n) (0x1 << (n)) +#define QER_En_none(n) (0x0 << (n)) +#define QER_En_prioritized(n) (0x1 << (n)) +#define QEExR_En_MASK(n) (0x1 << (n)) +#define QEExR_En_no(n) (0x0 << (n)) +#define QEExR_En_yes(n) (0x1 << (n)) +#define QEExR_En_clear(n) (0x1 << (n)) +#define QEExR_En_set(n) (0x1 << (n)) +#define QSExR_En_MASK(n) (0x1 << (n)) +#define QSExR_En_none(n) (0x0 << (n)) +#define QSExR_En_stored(n) (0x1 << (n)) +#define QSExR_En_clear(n) (0x1 << (n)) +#define EDMA3CC_REVID 0x40015300 +#define CCCFG_NUM_REGN_MASK (0x3 << 20) +#define CCCFG_NUM_EVQUE_MASK (0x7 << 16) +#define CCCFG_NUM_PAENTRY_MASK (0x7 << 12) +#define CCCFG_NUM_INTCH_MASK (0x7 << 8) +#define CCCFG_NUM_QDMACH_MASK (0x7 << 4) +#define CCCFG_NUM_DMACH_MASK (0x7 << 0) +#define QCHMAP_PAENTRY_MASK (0x7F << 5) +#define QCHMAP_TRWORD_MASK (0x7 << 2) +#define DMAQNUM_IDX(n) ((n) >> 3) +#define DMAQNUM_En_MASK(n) (0x7 << (((n) & 0x7) << 2)) +#define QDMAQNUM_En_MASK(n) (0x7 << (((n) & 0x7) << 2)) +#define EMxR_En_MASK(n) (0x1 << (n)) +#define EMxR_En_none(n) (0x0 << (n)) +#define EMxR_En_missed(n) (0x1 << (n)) +#define EMxR_En_clear(n) (0x1 << (n)) +#define QEMxR_En_MASK(n) (0x1 << (n)) +#define QEMxR_En_none(n) (0x0 << (n)) +#define QEMxR_En_missed(n) (0x1 << (n)) +#define QEMxR_En_clear(n) (0x1 << (n)) +#define DRAE_IDX(r) ((r) << 1) +#define DRAE_En_MASK(n) (0x1 << (n)) +#define DRAE_En_none(n) (0x0 << (n)) +#define DRAE_En_allow(n) (0x1 << (n)) +#define QRAE_En_MASK(n) (0x1 << (n)) +#define QRAE_En_none(n) (0x0 << (n)) +#define QRAE_En_allow(n) (0x1 << (n)) +#define QyEx_ETYPE_MASK (0x3 << 6) +#define QyEx_ETYPE_ER (0x0 << 6) +#define QyEx_ETYPE_ESR (0x1 << 6) +#define QyEx_ETYPE_CER (0x2 << 6) +#define QyEx_ETYPE_QER (0x3 << 6) +#define QyEx_ENUM_MASK (0x1F << 0) +#define QSTAT_WM_MASK (0x1F << 16) +#define QSTAT_WM_isLegal(x) (0 <= (x) && (x) <= 0x10) +#define QSTAT_NUMVAL_MASK (0x1F << 8) +#define QSTAT_NUMVAL_isLegal(x) (0 <= (x) && (x) <= 0x10) +#define QSTAT_STRTPTR_MASK (0xF << 0) +#define QWMTHRA_Q1_MASK (0x1F << 8) +#define QWMTHRA_Q0_MASK (0x1F << 0) +#define CCSTAT_COMPACTV_MASK (0x3F << 8) +#define PAEntry_CNT 128 +#define MPPRXY_PRIVID_MASK (0xF << 0) +#define EDMA3TC_REVID 0x40003B00 +#define TCCFG_DREGDEPTH_MASK (0x3 << 8) +#define TCCFG_BUSWIDTH_MASK (0x3 << 4) +#define TCCFG_FIFOSIZE_MASK (0x7 << 0) +#define TCSTAT_DFSTRTPTR_MASK (0x3 << 11) +#define TCSTAT_DSTACTV_MASK (0x7 << 4) +#define ERRDET_TCC_MASK (0x3F << 8) +#define ERRDET_STAT_MASK (0xF << 0) +#define ERRDET_STAT_NoError (0x0 << 0) +#define ERRDET_STAT_ReadAddressing (0x1 << 0) +#define ERRDET_STAT_ReadPrivilege (0x2 << 0) +#define ERRDET_STAT_ReadTimeout (0x3 << 0) +#define ERRDET_STAT_ReadData (0x4 << 0) +#define ERRDET_STAT_ReadExclusive (0x7 << 0) +#define ERRDET_STAT_WriteAddressing (0x9 << 0) +#define ERRDET_STAT_WritePrivilege (0xA << 0) +#define ERRDET_STAT_WriteTimeout (0xB << 0) +#define ERRDET_STAT_WriteData (0xC << 0) +#define ERRDET_STAT_WriteExclusive (0xF << 0) +#define RDRATE_X_MASK (0x7 << 0) +#define RDRATE_X_AsFast (0x0 << 0) +#define RDRATE_X_4cycles (0x1 << 0) +#define RDRATE_X_8cycles (0x2 << 0) +#define RDRATE_X_16cycles (0x3 << 0) +#define RDRATE_X_32cycles (0x4 << 0) +#define EMACC_REVID 0x4EC80101 +#define EMACCINTCTL_CxTXPACEEN_MASK(n) (0x1 << (17 + ((n) << 1))) +#define EMACCINTCTL_CxTXPACEEN_no(n) (0x0 << (17 + ((n) << 1))) +#define EMACCINTCTL_CxTXPACEEN_yes(n) (0x1 << (17 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_MASK(n) (0x1 << (16 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_no(n) (0x0 << (16 + ((n) << 1))) +#define EMACCINTCTL_CxRXPACEEN_yes(n) (0x1 << (16 + ((n) << 1))) +#define EMACCINTCTL_PRESCALE_MASK (0x7FF << 0) +#define EMACCINTCTL_PRESCALE_VAL(x) (((x) & 0x7FF) << 0) +#define RXTHRESHXX_RXCHx_MASK(n) (0x1 << (n)) +#define RXTHRESHXX_RXCHx_no(n) (0x0 << (n)) +#define RXTHRESHXX_RXCHx_yes(n) (0x1 << (n)) +#define CnRXXX_RXCHx_MASK(n) (0x1 << (n)) +#define CnRXXX_RXCHx_no(n) (0x0 << (n)) +#define CnRXXX_RXCHx_yes(n) (0x1 << (n)) +#define CnTXXX_TXCHx_MASK(n) (0x1 << (n)) +#define CnTXXX_TXCHx_no(n) (0x0 << (n)) +#define CnTXXX_TXCHx_yes(n) (0x1 << (n)) +#define CnRXIMAX_RXIMAX_MASK (0x3F << 0) +#define CnRXIMAX_RXIMAX_VAL(x) (((x) & 0x3F) << 0) +#define CnTXIMAX_TXIMAX_MASK (0x3F << 0) +#define CnTXIMAX_TXIMAX_VAL(x) (((x) & 0x3F) << 0) +#define MDIO_REVID (0x00070104) +#define MDIOCTL_CLKDIV_MASK (0xFFFF << 0) +#define MDIOCTL_CLKDIV_VAL(x) (((x) & 0xFFFF) << 0) +#define MDIOCTL_HIGHCH_MASK (0x1F << 24) +#define MDIOCTL_HIGHCH_VAL(x) (((x) & 0x1F) << 24) +#define MDIO_ALIVE_MASK(n) (0x1 << (n)) +#define MDIO_ALIVE_no(n) (0x0 << (n)) +#define MDIO_ALIVE_ack(n) (0x1 << (n)) +#define MDIO_LINK_MASK(n) (0x1 << (n)) +#define MDIO_LINK_no(n) (0x0 << (0)) +#define MDIO_LINK_yes(n) (0x1 << (0)) +#define USERACCESSx_REGADR_MASK (0x1F << 21) +#define USERACCESSx_REGADR_VAL(x) (((x) & 0x1F) << 21) +#define USERACCESSx_PHYADR_MASK (0x1F << 16) +#define USERACCESSx_PHYADR_VAL(x) (((x) & 0x1F) << 16) +#define USERACCESSx_DATA_MASK (0xFFFF << 0) +#define USERACCESSx_DATA_VAL(x) (((x) & 0xFFFF) << 0) +#define USERPHYSELx_PHYADRMON_MASK (0x1F << 0) +#define USERPHYSELx_PHYADRMON_VAL(x) (((x) & 0x1F) << 0) +#define XXX_GPkPj_MASK(j) (0x1 << (j)) +#define DIR_GPkPj_output(j) (0x0 << (j)) +#define DIR_GPkPj_input(j) (0x1 << (j)) +#define OUT_DATA_GPkPj_low(j) (0x0 << (j)) +#define OUT_DATA_GPkPj_high(j) (0x1 << (j)) +#define SET_DATA_GPkPj_none(j) (0x0 << (j)) +#define SET_DATA_GPkPj_high(j) (0x1 << (j)) +#define CLR_DATA_GPkPj_none(j) (0x0 << (j)) +#define CLR_DATA_GPkPj_low(j) (0x1 << (j)) +#define IN_DATA_GPkPj_low(j) (0x0 << (j)) +#define IN_DATA_GPkPj_high(j) (0x1 << (j)) +#define SET_RIS_TRIG_none(j) (0x0 << (j)) +#define SET_RIS_TRIG_enable(j) (0x1 << (j)) +#define CLR_RIS_TRIG_none(j) (0x0 << (j)) +#define CLR_RIS_TRIG_disable(j) (0x1 << (j)) +#define SET_FAL_TRIG_none(j) (0x0 << (j)) +#define SET_FAL_TRIG_disable(j) (0x1 << (j)) +#define CLR_FAL_TRIG_none(j) (0x0 << (j)) +#define CLR_FAL_TRIG_disable(j) (0x1 << (j)) +#define INTSTAT_none(j) (0x0 << (j)) +#define INTSTAT_pending(j) (0x1 << (j)) +#define GPIO_REVID 0x44830105 +#define BIT_ENx_MASK(x) (0x1 << (x)) +#define BIT_ENx_no(x) (0x0 << (x)) +#define BIT_ENx_yes(x) (0x1 << (x)) +#define GPIO_BANKS_0_1 0 +#define GPIO_BANKS_2_3 1 +#define GPIO_BANKS_4_5 2 +#define GPIO_BANKS_6_7 3 +#define GPIO_BANKS_8 4 +#define ICOAR_OADDR_MASK (0x3FF << 0) +#define ICOAR_OADDR_VAL(x) ((0x3FF & (x)) << 0) +#define ICIMR_AAS_MASK (0x1 << 6) +#define ICIMR_AAS_disabled (0x0 << 6) +#define ICIMR_AAS_enabled (0x1 << 6) +#define ICIMR_SCD_MASK (0x1 << 5) +#define ICIMR_SCD_disabled (0x0 << 5) +#define ICIMR_SCD_enabled (0x1 << 5) +#define ICIMR_ICXRDY_MASK (0x1 << 4) +#define ICIMR_ICXRDY_disabled (0x0 << 4) +#define ICIMR_ICXRDY_enabled (0x1 << 4) +#define ICIMR_ICRRDY_MASK (0x1 << 3) +#define ICIMR_ICRRDY_disabled (0x0 << 3) +#define ICIMR_ICRRDY_enabled (0x1 << 3) +#define ICIMR_ARDY_MASK (0x1 << 2) +#define ICIMR_ARDY_disabled (0x0 << 2) +#define ICIMR_ARDY_enabled (0x1 << 2) +#define ICIMR_NACK_MASK (0x1 << 1) +#define ICIMR_NACK_disabled (0x0 << 1) +#define ICIMR_NACK_enabled (0x1 << 1) +#define ICIMR_AL_MASK (0x1 << 0) +#define ICIMR_AL_disabled (0x0 << 0) +#define ICIMR_AL_enabled (0x1 << 0) +#define ICSTR_SDIR_MASK (0x1 << 14) +#define ICSTR_SDIR_other (0x0 << 14) +#define ICSTR_SDIR_slaveTX (0x1 << 14) +#define ICSTR_SDIR_clear (0x1 << 14) +#define ICSTR_NACKSNT_MASK (0x1 << 13) +#define ICSTR_NACKSNT_none (0x0 << 13) +#define ICSTR_NACKSNT_sent (0x1 << 13) +#define ICSTR_NACKSNT_clear (0x1 << 13) +#define ICSTR_BB_MASK (0x1 << 12) +#define ICSTR_BB_free (0x0 << 12) +#define ICSTR_BB_busy (0x1 << 12) +#define ICSTR_BB_clear (0x1 << 12) +#define ICSTR_RSFULL_MASK (0x1 << 11) +#define ICSTR_RSFULL_none (0x0 << 11) +#define ICSTR_RSFULL_overrun (0x1 << 11) +#define ICSTR_XSMT_MASK (0x1 << 10) +#define ICSTR_XSMT_underflow (0x0 << 10) +#define ICSTR_XSMT_none (0x1 << 10) +#define ICSTR_AAS_MASK (0x1 << 9) +#define ICSTR_ASS_cleared (0x0 << 9) +#define ICSTR_ASS_set (0x1 << 9) +#define ICSTR_AD0_MASK (0x1 << 8) +#define ICSTR_AD0_cleared (0x0 << 8) +#define ICSTR_AD0_detected (0x1 << 8) +#define ICSTR_SCD_MASK (0x1 << 5) +#define ICSTR_SCD_none (0x0 << 5) +#define ICSTR_SCD_detected (0x1 << 5) +#define ICSTR_SCD_clear (0x1 << 5) +#define ICSTR_ICXRDY_MASK (0x1 << 4) +#define ICSTR_ICXRDY_none (0x0 << 4) +#define ICSTR_ICXRDY_ready (0x1 << 4) +#define ICSTR_ICXRDY_clear (0x1 << 4) +#define ICSTR_ICRRDY_MASK (0x1 << 3) +#define ICSTR_ICRRDY_none (0x0 << 3) +#define ICSTR_ICRRDY_ready (0x1 << 3) +#define ICSTR_ICRRDY_clear (0x1 << 3) +#define ICSTR_ARDY_MASK (0x1 << 2) +#define ICSTR_ARDY_none (0x0 << 2) +#define ICSTR_ARDY_ready (0x1 << 2) +#define ICSTR_ARDY_clear (0x1 << 2) +#define ICSTR_NACK_MASK (0x1 << 1) +#define ICSTR_NACK_ack (0x0 << 1) +#define ICSTR_NACK_nack (0x1 << 1) +#define ICSTR_NACK_clear (0x1 << 1) +#define ICSTR_AL_MASK (0x1 << 0) +#define ICSTR_AL_none (0x0 << 0) +#define ICSTR_AL_lost (0x1 << 0) +#define ICSTR_AL_clear (0x1 << 0) +#define ICCLKL_MASK (0xFFFF << 0) +#define ICCLKH_MASK (0xFFFF << 0) +#define ICCNT_MASK (0xFFFF << 0) +#define ICDRR_MASK (0xFF << 0) +#define ICSAR_SADDR_MASK (0x3FF << 0) +#define ICSAR_SADDR_VAL(x) ((0x3FF & (x)) << 0) +#define ICDXR_MASK (0xFF << 0) +#define ICMDR_NACKMOD_MASK (0x1 << 15) +#define ICMDR_NACKMOD_no (0x0 << 15) +#define ICMDR_NACKMOD_yes (0x1 << 15) +#define ICMDR_FREE_MASK (0x1 << 14) +#define ICMDR_FREE_emu (0x0 << 14) +#define ICMDR_FREE_run (0x1 << 14) +#define ICMDR_STT_MASK (0x1 << 13) +#define ICMDR_STT_no (0x0 << 13) +#define ICMDR_STT_yes (0x1 << 13) +#define ICMDR_STP_MASK (0x1 << 11) +#define ICMDR_STP_no (0x0 << 11) +#define ICMDR_STP_yes (0x1 << 11) +#define ICMDR_MST_MASK (0x1 << 10) +#define ICMDR_MST_slave (0x0 << 10) +#define ICMDR_MST_master (0x1 << 10) +#define ICMDR_TRX_MASK (0x1 << 9) +#define ICMDR_TRX_receiver (0x0 << 9) +#define ICMDR_TRX_transmitter (0x1 << 9) +#define ICMDR_XA_MASK (0x1 << 8) +#define ICMDR_XA_7bit (0x0 << 8) +#define ICMDR_XA_10bit (0x1 << 8) +#define ICMDR_RM_MASK (0x1 << 7) +#define ICMDR_RM_no (0x0 << 7) +#define ICMDR_RM_yes (0x1 << 7) +#define ICMDR_DLB_MASK (0x1 << 6) +#define ICMDR_DLB_disable (0x0 << 6) +#define ICMDR_DLB_enable (0x1 << 6) +#define ICMDR_IRS_MASK (0x1 << 5) +#define ICMDR_IRS_reset (0x0 << 5) +#define ICMDR_IRS_none (0x1 << 5) +#define ICMDR_STB_MASK (0x1 << 4) +#define ICMDR_STB_no (0x0 << 4) +#define ICMDR_STB_yes (0x1 << 4) +#define ICMDR_FDF_MASK (0x1 << 3) +#define ICMDR_FDF_no (0x0 << 3) +#define ICMDR_FDF_yes (0x1 << 3) +#define ICMDR_BC_MASK (0x7 << 0) +#define ICMDR_BC_VAL(x) ((0x7 & (x)) << 0) +#define ICIVR_INTCODE_MASK (0x7 << 0) +#define ICIVR_INTCODE_none (0x0 << 0) +#define ICIVR_INTCODE_AL (0x1 << 0) +#define ICIVR_INTCODE_NACK (0x2 << 0) +#define ICIVR_INTCODE_ARDY (0x3 << 0) +#define ICIVR_INTCODE_ICRRDY (0x4 << 0) +#define ICIVR_INTCODE_ICXRDY (0x5 << 0) +#define ICIVR_INTCODE_SCD (0x6 << 0) +#define ICIVR_INTCODE_AAS (0x7 << 0) +#define ICEMDR_IGNACK_MASK (0x1 << 1) +#define ICEMDR_IGNACK_no (0x0 << 1) +#define ICEMDR_IGNACK_yes (0x1 << 1) +#define ICEMDR_BCM_MASK (0x1 << 0) +#define ICEMDR_BCM_ack (0x0 << 0) +#define ICEMDR_BCM_none (0x1 << 0) +#define ICPSC_IPSC_MASK (0xFF << 0) +#define ICPSC_IPSC_VAL(x) ((0xFF & (x)) << 0) +#define ICDMAC_TXDMAEN_MASK (0x1 << 1) +#define ICDMAC_TXDMAEN_disable (0x0 << 1) +#define ICDMAC_TXDMAEN_enable (0x1 << 1) +#define ICDMAC_RXDMAEN_MASK (0x1 << 0) +#define ICDMAC_RXDMAEN_disable (0x0 << 0) +#define ICDMAC_RXDMAEN_enable (0x1 << 0) +#define ICPFUNC_PFUNC0_MASK (0x1 << 0) +#define ICPFUNC_PFUNC0_i2c (0x0 << 0) +#define ICPFUNC_PFUNC0_gpio (0x1 << 0) +#define ICPXXX_SCL 0x0 +#define ICPXXX_SDA 0x1 +#define ICPDIR_PDIRx_MASK(x) (0x1 << (x)) +#define ICPDIR_PDIRx_input(x) (0x0 << (x)) +#define ICPDIR_PDIRx_output(x) (0x1 << (x)) +#define ICPDIO_PDIO_MASK(x) (0x1 << (x)) +#define ICPDIO_PDIO_low(x) (0x0 << (x)) +#define ICPDIO_PDIO_high(x) (0x1 << (x)) +#define ICPDXXX_MASK(x) (0x1 << (x)) +#define ICPDXXX_none(x) (0x0 << (x)) +#define ICPDXXX_assert(x) (0x1 << (x)) +#define LCDC_REVID 0x4C100100 +#define LCD_CTRL_CLKDIV_MASK (0xFF << 8) +#define LCD_CTRL_CLKDIV_X(x) (((x) & 0xFF) << 8) +#define RASTER_CTRL_PLM_MASK (0x3 << 20) +#define RASTER_CTRL_PLM_PaletteData (0x0 << 20) +#define RASTER_CTRL_PLM_Palette (0x1 << 20) +#define RASTER_CTRL_PLM_Data (0x2 << 20) +#define RASTER_CTRL_FDD_MASK (0xFF << 12) +#define RASTER_CTRL_FDD_X(x) (((x) & 0xFF) << 12) +#define RT0_HBP_MASK (0xFF << 24) +#define RT0_HBP_VAL(x) (((x) & 0xFF) << 24) +#define RT0_HFP_MASK (0xFF << 16) +#define RT0_HFP_VAL(x) (((x) & 0xFF) << 16) +#define RT0_HSW_MASK (0x3F << 10) +#define RT0_HSW_VAL(x) (((x) & 0x3F) << 10) +#define RT0_PPL_MASK (0x3F << 4) +#define RT0_PPL_VAL(x) (((x) & 0x3F) << 4) +#define RT1_VBP_MASK (0xFF << 24) +#define RT1_VBP_VAL(x) (((x) & 0xFF) << 24) +#define RT1_VFP_MASK (0xFF << 16) +#define RT1_VFP_VAL(x) (((x) & 0xFF) << 16) +#define RT1_VSW_MASK (0x3F << 10) +#define RT1_VSW_VAL(x) (((x) & 0x3F) << 10) +#define RT1_LPP_MASK (0x3FF << 0) +#define RT1_LPP_VAL(x) (((x) & 0x3FF) << 0) +#define RT2_ACBI_MASK (0xF << 16) +#define RT2_ACBI_VAL(x) (((x) & 0xF) << 16) +#define RT2_ACB_MASK (0xFF << 8) +#define RT2_ACB_VAL(x) (((x) & 0xFF) << 8) +#define RSP_LPPT_MASK (0x3FF << 16) +#define RSP_LPPT_VAL(x) (((x) & 0x3FF) << 16) +#define RSP_DPD_MASK (0xFFF << 4) +#define RSP_DPD_VAL(x) (((x) & 0xFFF) << 4) +#define LDMAC_TFR_MASK (0x7 << 8) +#define LDMAC_TFR_VAL(x) (((x) & 0x7) << 8) +#define LDMAC_TFR_8dwords (0x0 << 8) +#define LDMAC_TFR_16dwords (0x1 << 8) +#define LDMAC_TFR_32dwords (0x2 << 8) +#define LDMAC_TFR_64dwords (0x3 << 8) +#define LDMAC_TFR_128dwords (0x4 << 8) +#define LDMAC_TFR_256dwords (0x5 << 8) +#define LDMAC_TFR_512dwords (0x6 << 8) +#define LDMAC_BURSTSIZE_MASK (0x7 << 4) +#define LDMAC_BURSTSIZE_VAL(x) (((x) & 0x7) << 4) +#define LDMAC_BURSTSIZE_1 (0x0 << 4) +#define LDMAC_BURSTSIZE_2 (0x1 << 4) +#define LDMAC_BURSTSIZE_4 (0x2 << 4) +#define LDMAC_BURSTSIZE_8 (0x3 << 4) +#define LDMAC_BURSTSIZE_16 (0x4 << 4) +#define MMCCTL_DATEG_MASK (0x3 << 6) +#define MMCCTL_DATEG_disabled (0x0 << 6) +#define MMCCTL_DATEG_rising (0x1 << 6) +#define MMCCTL_DATEG_falling (0x2 << 6) +#define MMCCTL_DATEG_both (0x3 << 6) +#define MMCCLK_CLKRT_MASK (0xFF << 0) +#define MMCCLK_CLKRT_VAL(x) ((((x) - 1) & 0xFF) << 0) +#define MMCTOR_TOD25_16_MASK (0x3FF << 8) +#define MMCTOR_TOD25_16_VAL(x) ((((x) >> 16) & 0x3FF) << 8) +#define MMCTOR_TOR_MASK (0xFF << 0) +#define MMCTOR_TOR_VAL(x) (((x) & 0xFF) << 0) +#define MMCTOD_TOD15_0_MASK (0xFFFF << 0) +#define MMCTOD_TOD15_0_VAL(x) (((x) & 0xFFFF) << 0) +#define MMCBLEN_BLEN_MASK (0xFFF << 0) +#define MMCBLEN_BLEN_VAL(x) ((x) << 0) +#define MMCNBLK_NBLK_MASK (0xFFFF << 0) +#define MMCNBLK_NBLK_Infinite 0x0 +#define MMCNBLK_NBLK_VAL(x) ((x) << 0) +#define MMCNBLC_NBLC_MASK (0xFFFF << 0) +#define MMCCMD_RSPFMT_MASK (0x3 << 9) +#define MMCCMD_RSPFMT_none (0x0 << 9) +#define MMCCMD_RSPFMT_48bCRC (0x1 << 9) +#define MMCCMD_RSPFMT_136b (0x2 << 9) +#define MMCCMD_RSPFMT_48b (0x3 << 9) +#define MMCCMD_CMD_MASK (0x3F << 0) +#define MMCCMD_CMD_VAL(x) (((x) & 0x3F) << 0) +#define MMCARGHL_ARGH_MASK (0xFFFF << 16) +#define MMCARGHL_ARGH_VAL(x) (((x) & 0xFFFF) << 16) +#define MMCARGHL_ARGL_MASK (0xFFFF << 0) +#define MMCARGHL_ARGL_VAL(x) (((x) & 0xFFFF) << 0) +#define MMCDRSP_DRSP_MASK (0xFF << 0) +#define MMCCIDX_CIDX_MASK (0x3F << 0) +#define MMCFIFOCTL_ACCWD_MASK (0x3 << 3) +#define MMCFIFOCTL_ACCWD_4bytes (0x0 << 3) +#define MMCFIFOCTL_ACCWD_3bytes (0x1 << 3) +#define MMCFIFOCTL_ACCWD_2bytes (0x2 << 3) +#define MMCFIFOCTL_ACCWD_1bytes (0x3 << 3) +#define RTCINT_EVERY_MASK (0x3 << 0) +#define RTCINT_EVERY_Second (0x0 << 0) +#define RTCINT_EVERY_Minute (0x1 << 0) +#define RTCINT_EVERY_Hour (0x2 << 0) +#define RTCINT_EVERY_Day (0x3 << 0) +#define COMPxSB_MASK (0xFF << 0) +#define RTC_KICK0R_VAL (0x83E70B13) +#define RTC_KICK1R_VAL (0x95A4F1E0) +#define EMUMGT_SOFT_MASK (0x1 << 1) +#define EMUMGT_SOFT_stop (0x0 << 1) +#define EMUMGT_SOFT_reach (0x1 << 1) +#define EMUMGT_FREE_MASK (0x1 << 0) +#define EMUMGT_FREE_soft (0x0 << 0) +#define EMUMGT_FREE_run (0x1 << 0) +#define GPINTGPEN_GPENO12_MASK (0x1 << 17) +#define GPINTGPEN_GPENO12_timer (0x0 << 17) +#define GPINTGPEN_GPENO12_gpio (0x1 << 17) +#define GPINTGPEN_GPENI12_MASK (0x1 << 16) +#define GPINTGPEN_GPENI12_timer (0x0 << 16) +#define GPINTGPEN_GPENI12_gpio (0x1 << 16) +#define GPINTGPEN_GPINT12INVO_MASK (0x1 << 5) +#define GPINTGPEN_GPINT12INVO_rising (0x0 << 5) +#define GPINTGPEN_GPINT12INVO_falling (0x1 << 5) +#define GPINTGPEN_GPINT12INVI_MASK (0x1 << 4) +#define GPINTGPEN_GPINT12INVI_rising (0x0 << 4) +#define GPINTGPEN_GPINT12INVI_falling (0x1 << 4) +#define GPINTGPEN_GPINT12ENO_MASK (0x1 << 1) +#define GPINTGPEN_GPINT12ENO_rising (0x0 << 1) +#define GPINTGPEN_GPINT12ENO_falling (0x1 << 1) +#define GPINTGPEN_GPINT12ENI_MASK (0x1 << 0) +#define GPINTGPEN_GPINT12ENI_rising (0x0 << 0) +#define GPINTGPEN_GPINT12ENI_falling (0x1 << 0) +#define GPDATGPDIR_GPDIRO12_MASK (0x1 << 17) +#define GPDATGPDIR_GPDIRO12_gpio_in (0x0 << 17) +#define GPDATGPDIR_GPDIRO12_gpio_out (0x1 << 17) +#define GPDATGPDIR_GPDIRI12_MASK (0x1 << 16) +#define GPDATGPDIR_GPDIRI12_gpio_in (0x0 << 16) +#define GPDATGPDIR_GPDIRI12_gpio_out (0x1 << 16) +#define GPDATGPDIR_GPDATO12_MASK (0x1 << 1) +#define GPDATGPDIR_GPDATO12_low (0x0 << 1) +#define GPDATGPDIR_GPDATO12_high (0x1 << 1) +#define GPDATGPDIR_GPDATI12_MASK (0x1 << 0) +#define GPDATGPDIR_GPDATI12_low (0x0 << 0) +#define GPDATGPDIR_GPDATI12_high (0x1 << 0) +#define TCR_READRSTMODE34_MASK (0x1 << 26) +#define TCR_READRSTMODE34_none (0x0 << 26) +#define TCR_READRSTMODE34_reset (0x1 << 26) +#define TCR_ENAMODE34_MASK (0x3 << 22) +#define TCR_ENAMODE34_disabled (0x0 << 22) +#define TCR_ENAMODE34_once (0x1 << 22) +#define TCR_ENAMODE34_enabled (0x2 << 22) +#define TCR_ENAMODE34_reload (0x3 << 22) +#define TCR_CAPEVTMODE12_MASK (0x3 << 12) +#define TCR_CAPEVTMODE12_rising (0x0 << 12) +#define TCR_CAPEVTMODE12_falling (0x1 << 12) +#define TCR_CAPEVTMODE12_both (0x2 << 12) +#define TCR_CAPMODE12_MASK (0x1 << 11) +#define TCR_CAPMODE12_none (0x0 << 11) +#define TCR_CAPMODE12_capture (0x1 << 11) +#define TCR_READRSTMODE12_MASK (0x1 << 10) +#define TCR_READRSTMODE12_none (0x0 << 10) +#define TCR_READRSTMODE12_reset (0x1 << 10) +#define TCR_TIEN12_MASK (0x1 << 9) +#define TCR_TIEN12_none (0x0 << 9) +#define TCR_TIEN12_gated (0x1 << 9) +#define TCR_CLKSRC12_MASK (0x1 << 8) +#define TCR_CLKSRC12_internal (0x0 << 8) +#define TCR_CLKSRC12_external (0x1 << 8) +#define TCR_ENAMODE12_MASK (0x3 << 6) +#define TCR_ENAMODE12_disabled (0x0 << 6) +#define TCR_ENAMODE12_once (0x1 << 6) +#define TCR_ENAMODE12_enabled (0x2 << 6) +#define TCR_ENAMODE12_reload (0x3 << 6) +#define TCR_PWID12_MASK (0x3 << 4) +#define TCR_PWID12_VAL(x) ((0x3 & (x - 1)) << 4) +#define TCR_CP12_MASK (0x1 << 3) +#define TCR_CP12_pulse (0x0 << 3) +#define TCR_CP12_clock (0x1 << 3) +#define TCR_INVINP12_MASK (0x1 << 2) +#define TCR_INVINP12_uninverted (0x0 << 2) +#define TCR_INVINP12_inverted (0x1 << 2) +#define TCR_INVOUTP12_MASK (0x1 << 1) +#define TCR_INVOUTP12_uninverted (0x0 << 1) +#define TCR_INVOUTP12_inverted (0x1 << 1) +#define TCR_TSTAT12_MASK (0x1 << 0) +#define TCR_TSTAT12_deasserted (0x0 << 0) +#define TCR_TSTAT12_asserted (0x1 << 0) +#define TGCR_TDDR34_MASK (0xF << 12) +#define TGCR_TDDR34_VAL(x) ((0xF & (x)) << 12) +#define TGCR_PSC34_MASK (0xF << 8) +#define TGCR_PSC34_VAL(x) ((0xF & (x)) << 8) +#define TGCR_PLUSEN_MASK (0x1 << 4) +#define TGCR_PLUSEN_unavilable (0x0 << 4) +#define TGCR_PLUSEN_available (0x1 << 4) +#define TGCR_TIMMODE_MASK (0x3 << 2) +#define TGCR_TIMMODE_64bit (0x0 << 2) +#define TGCR_TIMMODE_unchained (0x1 << 2) +#define TGCR_TIMMODE_watchdog (0x2 << 2) +#define TGCR_TIMMODE_chained (0x3 << 2) +#define TGCR_TIM34RS_MASK (0x1 << 1) +#define TGCR_TIM34RS_reset (0x0 << 1) +#define TGCR_TIM34RS_none (0x1 << 1) +#define TGCR_TIM12RS_MASK (0x1 << 0) +#define TGCR_TIM12RS_reset (0x0 << 0) +#define TGCR_TIM12RS_none (0x1 << 0) +#define WDTCR_WDKEY_MASK (0xFFFF << 16) +#define WDTCR_WDKEY_VAL(x) ((x) << 16) +#define WDTCR_WDFLAG_MASK (0x1 << 15) +#define WDTCR_WDFLAG_none (0x0 << 15) +#define WDTCR_WDFLAG_timeout (0x1 << 15) +#define WDTCR_WDEN_MASK (0x1 << 14) +#define WDTCR_WDEN_disable (0x0 << 14) +#define WDTCR_WDEN_enable (0x1 << 14) +#define INTCTLSTAT_EVTINTSTAT34_MASK (0x1 << 19) +#define INTCTLSTAT_EVTINTSTAT34_none (0x0 << 19) +#define INTCTLSTAT_EVTINTSTAT34_occurred (0x1 << 19) +#define INTCTLSTAT_EVTINTSTAT34_clear (0x1 << 19) +#define INTCTLSTAT_EVTINTEN34_MASK (0x1 << 18) +#define INTCTLSTAT_EVTINTEN34_disable (0x0 << 18) +#define INTCTLSTAT_EVTINTEN34_enable (0x1 << 18) +#define INTCTLSTAT_PRDINTSTAT34_MASK (0x1 << 17) +#define INTCTLSTAT_PRDINTSTAT34_none (0x0 << 17) +#define INTCTLSTAT_PRDINTSTAT34_occurred (0x1 << 17) +#define INTCTLSTAT_PRDINTSTAT34_clear (0x1 << 17) +#define INTCTLSTAT_PRDINTEN34_MASK (0x1 << 16) +#define INTCTLSTAT_PRDINTEN34_disable (0x0 << 16) +#define INTCTLSTAT_PRDINTEN34_enable (0x1 << 16) +#define INTCTLSTAT_EVTINTSTAT12_MASK (0x1 << 3) +#define INTCTLSTAT_EVTINTSTAT12_none (0x0 << 3) +#define INTCTLSTAT_EVTINTSTAT12_occurred (0x1 << 3) +#define INTCTLSTAT_EVTINTSTAT12_clear (0x1 << 3) +#define INTCTLSTAT_EVTINTEN12_MASK (0x1 << 2) +#define INTCTLSTAT_EVTINTEN12_disable (0x0 << 2) +#define INTCTLSTAT_EVTINTEN12_enable (0x1 << 2) +#define INTCTLSTAT_PRDINTSTAT12_MASK (0x1 << 1) +#define INTCTLSTAT_PRDINTSTAT12_none (0x0 << 1) +#define INTCTLSTAT_PRDINTSTAT12_occurred (0x1 << 1) +#define INTCTLSTAT_PRDINTSTAT12_clear (0x1 << 1) +#define INTCTLSTAT_PRDINTEN12_MASK (0x1 << 0) +#define INTCTLSTAT_PRDINTEN12_disable (0x0 << 0) +#define INTCTLSTAT_PRDINTEN12_enable (0x1 << 0) +#define RBR_DATA_MASK 0xFF +#define THRw RBRr +#define THR_DATA_MASK 0xFF +#define IER_EDSSI_MASK (0x1 << 3) +#define IER_EDSSI_disable (0x0 << 3) +#define IER_EDSSI_enable (0x1 << 3) +#define IER_ELSI_MASK (0x1 << 2) +#define IER_ELSI_disable (0x0 << 2) +#define IER_ELSI_enable (0x1 << 2) +#define IER_ETBEI_MASK (0x1 << 1) +#define IER_ETBEI_disable (0x0 << 1) +#define IER_ETBEI_enable (0x1 << 1) +#define IER_ERBI_MASK (0x1 << 0) +#define IER_ERBI_disable (0x0 << 0) +#define IER_ERBI_enable (0x1 << 0) +#define IIR_FIFOEN_MASK (0x3 << 6) +#define IIR_FIFOEN_Non_FIFO (0x0 << 6) +#define IIR_FIFOEN_enabled (0x3 << 6) +#define IIR_INTID_MASK (0x7 << 1) +#define IIR_INTID_thr_empty (0x1 << 1) +#define IIR_INTID_data_avail (0x2 << 1) +#define IIR_INTID_line_status (0x3 << 1) +#define IIR_INTID_timeout (0x6 << 1) +#define IIR_IPEND_MASK (0x1 << 0) +#define IIR_IPEND_yes (0x0 << 0) +#define IIR_IPEND_no (0x1 << 0) +#define FCRw IIRr +#define FCR_RXFIFTL_MASK (0x3 << 6) +#define FCR_RXFIFTL_1byte (0x0 << 6) +#define FCR_RXFIFTL_4bytes (0x1 << 6) +#define FCR_RXFIFTL_8bytes (0x2 << 6) +#define FCR_RXFIFTL_14bytes (0x3 << 6) +#define FCR_DMAMODE1_MASK (0x1 << 3) +#define FCR_DMAMODE1_disable (0x0 << 3) +#define FCR_DMAMODE1_enable (0x1 << 3) +#define FCR_TXCLR_MASK (0x1 << 2) +#define FCR_TXCLR_clear (0x1 << 2) +#define FCR_RXCLR_MASK (0x1 << 1) +#define FCR_RXCLR_clear (0x1 << 1) +#define FCR_FIFOEN_MASK (0x1 << 0) +#define FCR_FIFOEN_No (0x0 << 0) +#define FCR_FIFOEN_Yes (0x1 << 0) +#define LCR_DLAB_MASK (0x1 << 7) +#define LCR_DLAB_rbr_thr_ier (0x0 << 7) +#define LCR_DLAB_dll_dlh (0x1 << 7) +#define LCR_BC_MASK (0x1 << 6) +#define LCR_BC_disabled (0x0 << 6) +#define LCR_BC_enabled (0x1 << 6) +#define LCR_SP_MASK (0x1 << 5) +#define LCR_SP_disabled (0x0 << 5) +#define LCR_SP_enabled (0x1 << 5) +#define LCR_EPS_MASK (0x1 << 4) +#define LCR_EPS_Odd (0x0 << 4) +#define LCR_EPS_Even (0x1 << 4) +#define LCR_PEN_MASK (0x1 << 3) +#define LCR_PEN_No (0x0 << 3) +#define LCR_PEN_Yes (0x1 << 3) +#define LCR_STB_MASK (0x1 << 2) +#define LCR_STB_1STOP (0x0 << 2) +#define LCR_STB_15_2STOP (0x1 << 2) +#define LCR_WLS_MASK (0x3 << 0) +#define LCR_WLS_5bits (0x0 << 0) +#define LCR_WLS_6bits (0x1 << 0) +#define LCR_WLS_7bits (0x2 << 0) +#define LCR_WLS_8bits (0x3 << 0) +#define MCR_AFE_MASK (0x1 << 5) +#define MCR_AFE_disabled (0x0 << 5) +#define MCR_AFE_enabled (0x1 << 5) +#define MCR_LOOP_MASK (0x1 << 4) +#define MCR_LOOP_disabled (0x0 << 4) +#define MCR_LOOP_enabled (0x1 << 4) +#define MCR_RTS_MASK (0x1 << 1) +#define MCR_RTS_disabled (0x0 << 1) +#define MCR_RTS_enabled (0x1 << 1) +#define LSR_RXFIFOE_MASK (0x1 << 7) +#define LSR_RXFIFOE_no_error (0x0 << 7) +#define LSR_RXFIFOE_error (0x1 << 7) +#define LSR_TEMT_MASK (0x1 << 6) +#define LSR_TEMT_no (0x0 << 6) +#define LSR_TEMT_yes (0x1 << 6) +#define LSR_THRE_MASK (0x1 << 5) +#define LSR_THRE_no (0x0 << 5) +#define LSR_THRE_yes (0x1 << 5) +#define LSR_BI_MASK (0x1 << 4) +#define LSR_BI_no (0x0 << 4) +#define LSR_BI_yes (0x1 << 4) +#define LSR_FE_MASK (0x1 << 3) +#define LSR_FE_no (0x0 << 3) +#define LSR_FE_yes (0x1 << 3) +#define LSR_PE_MASK (0x1 << 2) +#define LSR_PE_no (0x0 << 2) +#define LSR_PE_yes (0x1 << 2) +#define LSR_OE_MASK (0x1 << 1) +#define LSR_OE_no (0x0 << 1) +#define LSR_OE_yes (0x1 << 1) +#define LSR_DR_MASK (0x1 << 0) +#define LSR_DR_no (0x0 << 0) +#define LSR_DR_yes (0x1 << 0) +#define MSR_CD_MASK (0x1 << 7) +#define MSR_CD_high (0x0 << 7) +#define MSR_CD_low (0x1 << 7) +#define MSR_RI_MASK (0x1 << 6) +#define MSR_RI_high (0x0 << 6) +#define MSR_RI_low (0x1 << 6) +#define MSR_DSR_MASK (0x1 << 5) +#define MSR_DSR_high (0x0 << 5) +#define MSR_DSR_low (0x1 << 5) +#define MSR_CTS_MASK (0x1 << 4) +#define MSR_CTS_high (0x0 << 4) +#define MSR_CTS_low (0x1 << 4) +#define MSR_DCD_MASK (0x1 << 3) +#define MSR_DCD_unchanged (0x0 << 3) +#define MSR_DCD_changed (0x1 << 3) +#define MSR_TERI_MASK (0x1 << 2) +#define MSR_TERI_unchanged (0x0 << 2) +#define MSR_TERI_changed (0x1 << 2) +#define MSR_DDSR_MASK (0x1 << 1) +#define MSR_DDSR_unchanged (0x0 << 1) +#define MSR_DDSR_changed (0x1 << 1) +#define MSR_DCTS_MASK (0x1 << 0) +#define MSR_DCTS_unchanged (0x0 << 0) +#define MSR_DCTS_changed (0x1 << 0) +#define SCR_MASK 0xFF +#define PWREMU_UTRST_MASK (0x1 << 14) +#define PWREMU_UTRST_reset (0x0 << 14) +#define PWREMU_UTRST_enabled (0x1 << 14) +#define PWREMU_URRST_MASK (0x1 << 13) +#define PWREMU_URRST_reset (0x0 << 13) +#define PWREMU_URRST_enabled (0x1 << 13) +#define PWREMU_FREE_MASK (0x1 << 0) +#define PWREMU_FREE_halt (0x0 << 0) +#define PWREMU_FREE_run (0x1 << 0) +#define MDR_OSM_SEL_MASK (0x1 << 0) +#define MDR_OSM_SEL_16x (0x0 << 0) +#define MDR_OSM_SEL_13x (0x1 << 0) +#define xXMAXP_MAXPAYLOAD_MASK (0x7FF << 0) +#define COUNT0_EP0RXCOUNT_MASK (0x7F << 0) +#define RXCOUNT_EPRXCOUNT_MASK (0x1FFF << 0) +#define USB0_REVID 0x4EA10800 +#define USB0_EP_CNT 5 +#define MODE_MODE_TX_MASK(ep) (0x3 << (((ep) - 1) << 2)) +#define MODE_MODE_RX_MASK(ep) (0x30000 << (((ep) - 1) << 2)) +#define MODE_xMODE_Transparent (0x0 << 0) +#define MODE_xMODE_RNDIS (0x1 << 0) +#define MODE_xMODE_CDC (0x2 << 0) +#define MODE_xMODE_GenericRNDIS (0x3 << 0) +#define AUTOREQ_AUTREQ_MASK(ep) (0x3 << (((ep) - 1) << 1)) +#define AUTOREQ_xAUTREQ_None (0x0 << 0) +#define AUTOREQ_xAUTREQ_NotEOP (0x1 << 0) +#define AUTOREQ_xAUTREQ_Always (0x3 << 0) +#define TEARDOWN_RX_MASK(ep) (0x1 << (ep)) +#define TEARDOWN_RX_diable(ep) (0x0 << (ep)) +#define TEARDOWN_RX_enable(ep) (0x1 << (ep)) +#define TEARDOWN_TX_MASK(ep) (0x10000 << (ep)) +#define TEARDOWN_TX_diable(ep) (0x00000 << (ep)) +#define TEARDOWN_TX_enable(ep) (0x10000 << (ep)) +#define INTxR_TXEPn_MASK(ep) (0x1 << (ep)) +#define INTxR_TXEPn_no(ep) (0x0 << (ep)) +#define INTxR_TXEPn_yes(ep) (0x1 << (ep)) +#define INTxR_RXEPn_MASK(ep) (0x1 << ((ep) + 8)) +#define INTxR_RXEPn_no(ep) (0x0 << ((ep) + 8)) +#define INTxR_RXEPn_yes(ep) (0x1 << ((ep) + 8)) +#define INTxR_INTUSB_MASK(ir) (0x1 << ((ir) + 16)) +#define INTxR_INTUSB_no(ir) (0x0 << ((ir) + 16)) +#define INTxR_INTUSB_yes(ir) (0x1 << ((ir) + 16)) +#define EOIR_EOI_MASK(ir) (0x1 << (ir)) +#define EOIR_EOI_no(ir) (0x0 << (ir)) +#define EOIR_EOI_yes(ir) (0x1 << (ir)) +#define GENRNDISSZx_SIZE_MASK (0x1FFFF << 0) +#define FADDR_FUNCADDR_MASK (0x7F << 0) +#define INTRx_EP_MASK(ep) (0x1 << (ep)) +#define INTRx_EP_disable(ep) (0x0 << (ep)) +#define INTRx_EP_enable(ep) (0x1 << (ep)) +#define INTRUSBx_INTUSB_MASK(ir) (0x1 << (ir)) +#define INTRUSBx_INTUSB_no(ir) (0x0 << (ir)) +#define INTRUSBx_INTUSB_yes(ir) (0x1 << (ir)) +#define FRAME_FRAMENUMBER_MASK (0x7FF << 0) +#define INDEX_EPSEL_MASK (0xF << 0) +#define INDEX_EPSEL_VAL(ep) ((ep) << 0) +#define DEVCTL_VBUS_MASK (0x3 << 3) +#define DEVCTL_VBUS_BelowSEnd (0x0 << 3) +#define DEVCTL_VBUS_SEnd_AValid (0x1 << 3) +#define DEVCTL_VBUS_AValid_VBusValid (0x2 << 3) +#define DEVCTL_VBUS_AboveVbusValid (0x3 << 3) +#define xXFIFOSZ_SZ_MASK (0xF << 0) +#define xXFIFOSZ_SZ_8B (0x0 << 0) +#define xXFIFOSZ_SZ_16B (0x1 << 0) +#define xXFIFOSZ_SZ_32B (0x2 << 0) +#define xXFIFOSZ_SZ_64B (0x3 << 0) +#define xXFIFOSZ_SZ_128B (0x4 << 0) +#define xXFIFOSZ_SZ_256B (0x5 << 0) +#define xXFIFOSZ_SZ_512B (0x6 << 0) +#define xXFIFOSZ_SZ_1KB (0x7 << 0) +#define xXFIFOSZ_SZ_2KB (0x8 << 0) +#define xXFIFOSZ_SZ_4KB (0x9 << 0) +#define xXFIFOSZ_SZ_8KB (0xA << 0) +#define xXFIFOSZ_SZ_16KB (0xB << 0) +#define xXFIFOSZ_SZ_32KB (0xC << 0) +#define xXFIFOSZ_SZ_64KB (0xD << 0) +#define xXFIFOSZ_SZ_128KB (0xE << 0) +#define xXFIFOSZ_SZ_256KB (0xF << 0) +#define xXFIFOADDR_ADDR_MASK (0x1FFF << 0) +#define xXFIFOADDR_ADDR_VAL(adr) (((adr) >> 3) << 0) +#define HWVERS_REVMAJ_MASK (0x1F << 10) +#define HWVERS_REVMIN_MASK (0x3FF << 0) +#define EDMA3_0CC0_BASE 0x01C00000 +#define EDMA3_0TC0_BASE 0x01C08000 +#define EDMA3_0TC1_BASE 0x01C08400 +#define PSC0_BASE 0x01C10000 +#define PLL0_BASE 0x01C11000 +#define SYSCFG0_BASE 0x01C14000 +#define TIMER0_BASE 0x01C20000 +#define TIMER1_BASE 0x01C21000 +#define I2C0_BASE 0x01C22000 +#define RTC_BASE 0x01C23000 +#define PRU_DataRAM0_BASE 0x01C30000 +#define PRU_DataRAM0_SIZE 0x00000200 +#define PRU_DataRAM1_BASE 0x01C32000 +#define PRU_DataRAM1_SIZE 0x00000200 +#define PRU_INTC_BASE 0x01C34000 +#define PRU0_BASE 0x01C37000 +#define PRU1_BASE 0x01C37800 +#define PRU_InstRAM0_BASE 0x01C38000 +#define PRU_InstRAM0_SIZE 0x00001000 +#define PRU_InstRAM1_BASE 0x01C3C000 +#define PRU_InstRAM1_SIZE 0x00001000 +#define MMCSD0_BASE 0x01C40000 +#define UART0_BASE 0x01C42000 +#define UART1_BASE 0x01D0C000 +#define UART2_BASE 0x01D0D000 +#define USB0_BASE 0x01E00000 +#define LCD0_BASE 0x01E13000 +#define MPU1_BASE 0x01E14000 +#define MPU2_BASE 0x01E15000 +#define PLL1_BASE 0x01E1A000 +#define MMCSD1_BASE 0x01E1B000 +#define EMACCRAM_BASE 0x01E20000 +#define EMACCRAM_SIZE 0x00002000 +#define EMACC_BASE 0x01E22000 +#define EMAC_BASE 0x01E23000 +#define MDIO_BASE 0x01E24000 +#define GPIOCON_BASE 0x01E26000 +#define PSC1_BASE 0x01E27000 +#define I2C1_BASE 0x01E28000 +#define SYSCFG1_BASE 0x01E2C000 +#define EDMA3_1CC0_BASE 0x01E30000 +#define EDMA3_1TC0_BASE 0x01E38000 +#define ECAP0_BASE 0x01F06000 +#define ECAP1_BASE 0x01F07000 +#define ECAP2_BASE 0x01F08000 +#define TIMER2_BASE 0x01F0C000 +#define TIMER3_BASE 0x01F0D000 +#define OnChipRAM_BASE 0x80000000 +#define OnChipRAM_SISE 0x00020000 +#define DDR0_BASE 0xB0000000 +#define ARMLocalROM_BASE 0xFFFD0000 +#define ARMLocalROM_SIZE 0x00010000 +#define AINTC_BASE 0xFFFEE000 +#define ARMLocalRAM_BASE 0xFFFF0000 +#define ARMLocalRAM_SIZE 0x00002000 diff --git a/lib/am18x-lib/inc/am18x_mmcsd.h b/lib/am18x-lib/inc/am18x_mmcsd.h new file mode 100644 index 000000000..0dc18b708 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_mmcsd.h @@ -0,0 +1,93 @@ +// tary, 21:11 2013/6/23 + +#ifndef __AM18X_MMCSD_H__ +#define __AM18X_MMCSD_H__ + +#include "am18x_map.h" + +#define MMCSD_BLOCK_SIZE 0x200 + +typedef struct { + uint32_t freq; +#define TIMEOUT_RSP_MAX 0xFFUL + uint32_t timeout_rsp; +#define TIMEOUT_DAT_MAX 0x3FFFFFFUL + uint32_t timeout_dat; +} mmcsd_conf_t; + +typedef enum { + MMCSD_CMD_F_NORSP = 0, + MMCSD_CMD_F_RSP = BIT(1), + MMCSD_CMD_F_SHORT = 0, + MMCSD_CMD_F_LONG = BIT(2), + MMCSD_CMD_F_NOCRC = 0, + MMCSD_CMD_F_CRC = BIT(3), + MMCSD_CMD_F_NODATA = 0, + MMCSD_CMD_F_DATA = BIT(4), + MMCSD_CMD_F_READ = 0, + MMCSD_CMD_F_WRITE = BIT(5), + MMCSD_CMD_F_NOBUSY = 0, + MMCSD_CMD_F_BUSY = BIT(6), +} mmcsd_cflags_t; + +typedef struct { + uint8_t index; + uint32_t cflags; + uint32_t arg; +} mmcsd_cmd_t; + +typedef enum { + MMCSD_SC_NONE, + MMCSD_SC_RSP_OK, + MMCSD_SC_CRC_ERR, + MMCSD_SC_RSP_TOUT, +} mmcsd_cmd_state_t; + +typedef enum { + MMCSD_SD_NONE, + MMCSD_SD_SENT, + MMCSD_SD_RECVED, + MMCSD_SD_CRC_ERR, + MMCSD_SD_TOUT, + MMCSD_SD_OK, + MMCSD_SD_BUSY, + MMCSD_SD_DONE, +} mmcsd_dat_state_t; + +typedef struct { + uint32_t v[4]; +} mmcsd_resp_t; + +typedef enum { + MMCSD_RESP_SHORT, + MMCSD_RESP_LONG, +} mmcsd_resp_type_t; + +typedef enum { + MMCSD_MISC_F_FIFO_RST = BIT(0), + MMCSD_MISC_F_FIFO_32B = 0, + MMCSD_MISC_F_FIFO_64B = BIT(1), + MMCSD_MISC_F_READ = 0, + MMCSD_MISC_F_WRITE = BIT(2), + MMCSD_MISC_F_BUSY = BIT(3), + MMCSD_MISC_F_BUS4BIT = BIT(4), +} mmcsd_mflags_t; + +typedef struct { + uint16_t mflags; + uint16_t blkcnt; +} mmcsd_misc_t; + +am18x_rt mmcsd_con_init(MMCSD_con_t* mcon, const mmcsd_conf_t* conf); +uint32_t mmcsd_xet_freq(MMCSD_con_t* mcon, uint32_t freq); +am18x_rt mmcsd_send_cmd(MMCSD_con_t* mcon, const mmcsd_cmd_t* cmd); +mmcsd_cmd_state_t mmcsd_cmd_state(const MMCSD_con_t* mcon, am18x_bool need_crc); +mmcsd_dat_state_t mmcsd_busy_state(const MMCSD_con_t* mcon); +mmcsd_dat_state_t mmcsd_rd_state(const MMCSD_con_t* mcon); +mmcsd_dat_state_t mmcsd_wr_state(const MMCSD_con_t* mcon); +am18x_rt mmcsd_get_resp(const MMCSD_con_t* mcon, mmcsd_resp_type_t type, mmcsd_resp_t* resp); +am18x_rt mmcsd_cntl_misc(MMCSD_con_t* mcon, const mmcsd_misc_t* misc); +uint32_t mmcsd_read(const MMCSD_con_t* mcon); +am18x_rt mmcsd_write(MMCSD_con_t* mcon, uint32_t data); + +#endif//__AM18X_MMCSD_H__ diff --git a/lib/am18x-lib/inc/am18x_mpu.h b/lib/am18x-lib/inc/am18x_mpu.h new file mode 100644 index 000000000..8ae852f8a --- /dev/null +++ b/lib/am18x-lib/inc/am18x_mpu.h @@ -0,0 +1,8 @@ +// tary, 0:25 2013/4/22 + +#ifndef __AM18X_MPU_H__ +#define __AM18X_MPU_H__ + +#include "am18x_map.h" + +#endif//__AM18X_MPU_H__ diff --git a/lib/am18x-lib/inc/am18x_pll.h b/lib/am18x-lib/inc/am18x_pll.h new file mode 100644 index 000000000..437a439f3 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_pll.h @@ -0,0 +1,48 @@ +// tary, 17:27 2013/4/14 + +#ifndef __AM18X_PLL_H__ +#define __AM18X_PLL_H__ + +#include "am18x_map.h" + +typedef enum { + PLL_CFLAG_EXT_CLK_OSCIN = 0x0, + PLL_CFLAG_EXT_CLK_PLL1 = BIT(0), + PLL_CFLAG_REF_CRYSTAL = 0x0, + PLL_CFLAG_REF_SQUARE = BIT(1), + PLL_CFLAG_POWER_NORM = 0x0, + PLL_CFLAG_POWER_DOWN = BIT(2), + PLL_CFLAG_FROM_POWERON = BIT(3), +} PLL_CFLAG_flag_t; + +typedef enum { + PLL_CMD_SOFT_RESET, + PLL_CMD_ENABLE_PLL1_DIVS, + PLL_CMD_POWER_DOWN, + PLL_CMD_BYPASS, + PLL_CMD_CHG_MULT, + PLL_CMD_UNBYPASS, + PLL_CMD_IS_ENABLE, +} pll_cmd_t; + +typedef enum { + PLL_RESET_SOFTWARE, + PLL_RESET_EXTERNAL, + PLL_RESET_POWER_ON, +} pll_reset_t; + +typedef struct { + uint8_t prediv; + uint8_t pllm; + uint8_t postdiv; + uint8_t plldiv[7]; + uint16_t cflag; +} pll_conf_t; + +am18x_rt pll_changing_sysclk_dividers(PLL_con_t* pcon, uint32_t plldivn, uint32_t divider); +am18x_rt pll_get_conf(const PLL_con_t* pcon, pll_conf_t* conf); +am18x_rt pll_set_conf(PLL_con_t* pcon, const pll_conf_t* conf); +am18x_rt pll_cmd(PLL_con_t* pcon, uint32_t cmd, uint32_t arg); +pll_reset_t pll_get_reset(void); + +#endif//__AM18X_PLL_H__ diff --git a/lib/am18x-lib/inc/am18x_pru.h b/lib/am18x-lib/inc/am18x_pru.h new file mode 100644 index 000000000..5ca5f4604 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_pru.h @@ -0,0 +1,19 @@ +// tary, 22:45 2013/5/10 + +#ifndef __AM18X_PRU_H__ +#define __AM18X_PRU_H__ + +#include "am18x_map.h" + +typedef enum { + PRU_CMD_DISABLE, + PRU_CMD_ENABLE, + PRU_CMD_RUN, + PRU_CMD_IS_HALT, +} pru_cmd_t; + +am18x_rt pru_load(PRU_con_t* pcon, const uint32_t* inst, uint32_t count); +am18x_rt pru_cmd(PRU_con_t* pcon, pru_cmd_t cmd, uint32_t arg); +am18x_rt pru_dump_regs(PRU_con_t* pcon); + +#endif//__AM18X_PRU_H__ diff --git a/lib/am18x-lib/inc/am18x_psc.h b/lib/am18x-lib/inc/am18x_psc.h new file mode 100644 index 000000000..1214aa94c --- /dev/null +++ b/lib/am18x-lib/inc/am18x_psc.h @@ -0,0 +1,21 @@ +// tary, 0:27 2012/12/27 + +#ifndef __AM18X_PSC_H__ +#define __AM18X_PSC_H__ + +#include "am18x_map.h" + +typedef enum { + PSC_STATE_SW_RST_DISABLE, + PSC_STATE_SYNC_RESET, + PSC_STATE_DISABLE, + PSC_STATE_ENABLE, + PSC_STATE_IN_TRANSITION, +} psc_state_t; + +am18x_rt psc_state_transition(psc_module_t module, psc_state_t state); +am18x_rt psc_enable_interrupt(psc_module_t module); +psc_state_t psc_get_state(psc_module_t module); +am18x_rt psc_dump_regs(PSC_con_t* pcon); + +#endif//__AM18X_PSC_H__ diff --git a/lib/am18x-lib/inc/am18x_rtc.h b/lib/am18x-lib/inc/am18x_rtc.h new file mode 100644 index 000000000..521accb65 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_rtc.h @@ -0,0 +1,37 @@ +// tary, 20:48 2016/4/1 + +#ifndef __AM18X_RTC_H__ +#define __AM18X_RTC_H__ + +#include "am18x_map.h" + +#define BCD2BIN(val) (((val) & 0x0F) + ((val) >> 4) * 10) +#define BIN2BCD(val) ((((val) / 10) << 4) + (val) % 10) + +typedef enum { + RTC_DISABLE = BIT(0), + RTC_ENABLE = BIT(1), + RTC_TICKINT_DISABLE = BIT(2), + RTC_TICKINT_ENABLE = BIT(3), + RTC_SET_TIME = BIT(4), +} rtc_cflag_t; + +#define RTC_INVALID_VAL (0xFF) + +typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t weekday; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t tickcnt; + uint8_t cflags; +} rtc_tm_t; + +am18x_rt rtc_conf(RTC_con_t* rtc, const rtc_tm_t* tm); +am18x_rt rtc_alarm(RTC_con_t* rtc, const rtc_tm_t* tm); +am18x_rt rtc_state(const RTC_con_t* rtc, rtc_tm_t* tm); + +#endif//__AM18X_RTC_H__ diff --git a/lib/am18x-lib/inc/am18x_syscfg.h b/lib/am18x-lib/inc/am18x_syscfg.h new file mode 100644 index 000000000..5900a3509 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_syscfg.h @@ -0,0 +1,20 @@ +// tary, 13:11 2012/12/28 + +#ifndef __AM18X_SYSCFG_H__ +#define __AM18X_SYSCFG_H__ + +#include "am18x_map.h" + +am18x_rt syscfg_kick(am18x_bool lock); +am18x_rt syscfg_pll(am18x_bool lock); +am18x_rt syscfg_aync3(am18x_bool src_y_pll0_n_pll1); +// pos = [0,4,8,12,16,20,24,28] +// val = [0..15] +am18x_rt syscfg_pinmux(uint32_t mux, uint32_t pos, uint32_t val); +int32_t syscfg_bootmode(void); +am18x_rt syscfg_vtpio_calibrate(void); +am18x_rt syscfg_ddr_slew(am18x_bool ddr2_not_mddr); +am18x_rt syscfg_set_usb0phy(am18x_bool y_on_n_off, uint32_t freq); +am18x_rt syscfg_set_usb1phy(am18x_bool y_on_n_off, am18x_bool phy_clk_y_usb0_n_refin); + +#endif//__AM18X_SYSCFG_H__ diff --git a/lib/am18x-lib/inc/am18x_timer.h b/lib/am18x-lib/inc/am18x_timer.h new file mode 100644 index 000000000..c000ee094 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_timer.h @@ -0,0 +1,56 @@ +// tary, 21:57 2013/3/6 + +#ifndef __AM18X_TIMER_H__ +#define __AM18X_TIMER_H__ + +#include "am18x_map.h" + +typedef enum { + TIMER_MODE_64_BIT, + TIMER_MODE_32_BIT_UNCHANINED, + TIMER_MODE_32_BIT_CHAINED, + TIMER_MODE_WATCHDOG, +} timer_mode_t; + +typedef enum { + TIMER_RESULT_NONE, + TIMER_RESULT_INTERRUPT, + TIMER_RESULT_DMA_SYNC, + TIMER_RESULT_OUTPUT, + TIMER_RESULT_CAPTURE, +} timer_result_t; + +typedef enum { + TIMER_SOURCE_INTERNAL, + TIMER_SOURCE_EXTERNAL, +} timer_source_t; + +typedef enum { + TIMER_OPER_ONE_TIME, + TIMER_OPER_CONTINUOUS, + TIMER_OPER_RELOAD, +} timer_operation_t; + +typedef enum { + TIMER_CMD_PAUSE, + TIMER_CMD_RESTART, + TIMER_CMD_RESET, + TIMER_CMD_START, + TIMER_CMD_RELOAD, + TIMER_CMD_INTR_CLEAR, +} timer_cmd_t; + +typedef struct { + uint32_t mode; + uint32_t result; + uint32_t source; + uint32_t operation; + uint32_t period; +} timer_conf_t; + +uint32_t timer_input_freq(TIMER_con_t* tcon); +am18x_rt timer_conf(TIMER_con_t* tcon, const timer_conf_t* conf); +am18x_rt timer_cmd(TIMER_con_t* tcon, timer_cmd_t cmd, uint32_t arg); +uint32_t timer_get_count(TIMER_con_t* tcon); + +#endif//__AM18X_TIMER_H__ diff --git a/lib/am18x-lib/inc/am18x_type.h b/lib/am18x-lib/inc/am18x_type.h new file mode 100644 index 000000000..303c842e8 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_type.h @@ -0,0 +1,142 @@ +// tary, 23:14 2012/12/16 + +#ifndef __AM18X_TYPE_H__ +#define __AM18X_TYPE_H__ + +#define __USE_STDINT_H + +#ifdef __USE_STDINT_H +#include + +#else +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#define INT8_MIN (-128) +#define INT16_MIN (-32767-1) +#define INT32_MIN (-2147483647-1) +#define INT64_MIN (-0x7FFFFFFFFFFFFFFFLL - 1) + +#define INT8_MAX (127) +#define INT16_MAX (32767) +#define INT32_MAX (2147483647) +#define INT64_MAX (0x7FFFFFFFFFFFFFFFLL) + +#define UINT8_MAX (255) +#define UINT16_MAX (65535) +#define UINT32_MAX (4294967295U) +#define UINT64_MAX (0xFFFFFFFFFFFFFFFFULL) + +#endif //__USE_STDINT_H + +typedef signed char const cint8_t; +typedef short const cint16_t; +typedef int const cint32_t; +typedef long long const cint64_t; + +typedef unsigned char const cuint8_t; +typedef unsigned short const cuint16_t; +typedef unsigned int const cuint32_t; +typedef unsigned long long const cuint64_t; + +typedef volatile signed char vint8_t; +typedef volatile short vint16_t; +typedef volatile int vint32_t; +typedef volatile long long vint64_t; + +typedef volatile unsigned char vuint8_t; +typedef volatile unsigned short vuint16_t; +typedef volatile unsigned int vuint32_t; +typedef volatile unsigned long long vuint64_t; + +typedef volatile signed char const vcint8_t; +typedef volatile short const vcint16_t; +typedef volatile int const vcint32_t; +typedef volatile long long const vcint64_t; + +typedef volatile unsigned char const vcuint8_t; +typedef volatile unsigned short const vcuint16_t; +typedef volatile unsigned int const vcuint32_t; +typedef volatile unsigned long long const vcuint64_t; + +#define _MASK_OFFSET_8BIT(x) (((x) & 0x00000001UL)?0: \ + (((x) & 0x00000002UL)?1: \ + (((x) & 0x00000004UL)?2: \ + (((x) & 0x00000008UL)?3: \ + (((x) & 0x00000010UL)?4: \ + (((x) & 0x00000020UL)?5: \ + (((x) & 0x00000040UL)?6: \ + (((x) & 0x00000080UL)?7:128 \ + )))))))) + +#define MASK_OFFSET(x) (((x) & 0x000000FFUL)? _MASK_OFFSET_8BIT(x): \ + (((x) & 0x0000FF00UL)? (8 + _MASK_OFFSET_8BIT((x)>>8)): \ + (((x) & 0x00FF0000UL)? (16 + _MASK_OFFSET_8BIT((x)>>16)): \ + (((x) & 0xFF000000UL)? (24 + _MASK_OFFSET_8BIT((x)>>24)):128 \ + )))) + +/* unaligned bits operations */ +#define FIELD_GET(_reg,_msk) ((_reg) & (_msk)) +#define FIELD_SET(_reg,_msk,_v) (((_reg) & ~(_msk)) | ((_v) & (_msk))) +/* bit 0 aligned bits operations */ +#define FIELD_XGET(_reg,_msk) (((_reg) & (_msk)) >> MASK_OFFSET(_msk)) +#define FIELD_XSET(_reg,_msk,_vx) (((_reg) & ~(_msk)) | (((_vx) << MASK_OFFSET(_msk)) & (_msk))) + +#ifndef __ASSEMBLY__ +static inline uint32_t __ffs(uint32_t x) +{ + uint32_t r = 0; + + if (!x) return 0; + + if (!(x & 0xffff)) { + x >>= 16; r += 16; + } + if (!(x & 0xff)) { + x >>= 8; r += 8; + } + if (!(x & 0xf)) { + x >>= 4; r += 4; + } + if (!(x & 3)) { + x >>= 2; r += 2; + } + if (!(x & 1)) { + x >>= 1; r += 1; + } + return r; +} + +static inline uint32_t __field_xget(uint32_t reg, uint32_t msk) { + return ((reg & msk) >> __ffs(msk)); +} + +static inline uint32_t __field_xset(uint32_t reg, uint32_t msk, uint32_t vx) { + return (reg & ~msk) | ((vx << __ffs(msk)) & msk); +} + +typedef enum { AM18X_ERR = -1, AM18X_OK = 0} am18x_rt; +typedef enum { AM18X_FALSE = 0, AM18X_TRUE = !AM18X_FALSE} am18x_bool; + +#ifndef NULL +#define NULL ((void*)0UL) +#endif + +#endif + +#define countof(x) (sizeof(x) / sizeof(x[0])) +#define BIT(x) (0x1UL << (x)) +#define BIT_DEF(r,of,b,bdis,ben) \ + r##_##b##_##MASK = (0x1UL << (of)), \ + r##_##b##_##bdis = (0x0UL << (of)), \ + r##_##b##_##ben = (0x1UL << (of)) + + +#endif//__AM18X_TYPE_H__ diff --git a/lib/am18x-lib/inc/am18x_uart.h b/lib/am18x-lib/inc/am18x_uart.h new file mode 100644 index 000000000..3cdc87390 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_uart.h @@ -0,0 +1,120 @@ +// tary, 0:36 2012/12/23 + +#ifndef __AM18X_UART_H__ +#define __AM18X_UART_H__ + +#include "am18x_map.h" + +typedef enum { + UART_PARITY_NONE, + UART_PARITY_ODD, + UART_PARITY_EVEN, + UART_PARITY_1S, + UART_PARITY_0S, +} uart_parity_t; + +typedef enum { + UART_STOP_1BIT, + UART_STOP_2BIT, +} uart_stop_t; + +typedef enum { + UART_LENGTH_5BIT, + UART_LENGTH_6BIT, + UART_LENGTH_7BIT, + UART_LENGTH_8BIT, +} uart_length_t; + +typedef enum { + UART_FLOW_NONE, + UART_FLOW_SOFT, + UART_FLOW_AFC, +} uart_flow_t; + +typedef enum { + UART_MODE_DISABLE, + UART_MODE_INTR, + UART_MODE_DMA, +} uart_xmode_t; + +typedef struct { + uint32_t baudrate; + uart_length_t length; + uart_stop_t stop; + uart_parity_t parity; + uart_flow_t flow; + uart_xmode_t mode; +} uart_conf_t; + +typedef enum { + UART_TTRIG_EMPTY, + UART_TTRIG_16BYTE, + UART_TTRIG_32BYTE, + UART_TTRIG_48BYTE, +} uart_ttrig_t; + +typedef enum { + UART_RTRIG_1BYTE, + UART_RTRIG_8BYTE, + UART_RTRIG_16BYTE, + UART_RTRIG_32BYTE, +} uart_rtrig_t; + +typedef enum { + UFIFO_CMD_TX_RESET, + UFIFO_CMD_RX_RESET, + UFIFO_CMD_RESET, + UFIFO_CMD_DISABLE, + UFIFO_CMD_ENABLE, +} ufifo_cmd_t; + +typedef struct { + ufifo_cmd_t cmd; + uart_ttrig_t ttrig; + uart_rtrig_t rtrig; +} uart_fifo_t; + +#define UFIFO_SIZE (64) + +typedef enum { + FIFO_TYPE_TX, + FIFO_TYPE_RX, +} fifo_type_t; + +typedef enum { + UART_MISC_BREAK, + /* only valid AFC disabled */ + UART_MISC_REQSEND, +} uart_misc_t; + +typedef enum { + STATE_TX_EMPTY, + STATE_TX_BUF_EMPTY, + STATE_RX_READY, + + STATE_ERROR_ANY, + STATE_ERROR_BREAK, + STATE_ERROR_FRAME, + STATE_ERROR_PARITY, + STATE_ERROR_OVERRUN, + + STATE_CTS_ACTIVE, + STATE_CTS_CHANGED, + + STATE_FIFO_XXFULL, + STATE_FIFO_TXFULL, + STATE_FIFO_RXFULL, +} uart_state_type_t; + +am18x_rt uart_init_conf(uart_conf_t* conf); +am18x_rt uart_set_conf(UART_con_t* con, const uart_conf_t* conf); +am18x_rt uart_get_conf(const UART_con_t* con, uart_conf_t* conf); +am18x_rt uart_set_fifo(UART_con_t* con, const uart_fifo_t* fifo); +/* return number of data in specified fifo */ +uint32_t uart_fifo_state(const UART_con_t* con, fifo_type_t type); +am18x_rt uart_cntl_misc(UART_con_t* con, uart_misc_t misc); +am18x_bool uart_state(const UART_con_t* con, uart_state_type_t type); +am18x_rt uart_write_byte(UART_con_t* con, uint8_t c); +uint8_t uart_read_byte(const UART_con_t* con); + +#endif//__AM18X_UART_H__ diff --git a/lib/am18x-lib/inc/am18x_usb.h b/lib/am18x-lib/inc/am18x_usb.h new file mode 100644 index 000000000..ce5075221 --- /dev/null +++ b/lib/am18x-lib/inc/am18x_usb.h @@ -0,0 +1,17 @@ +// tary, 21:10 2015/6/4 + +#ifndef __AM18X_USB_H__ +#define __AM18X_USB_H__ + +#include "am18x_map.h" + +typedef struct { + am18x_bool highspeed; + am18x_bool host_n_device; +} usb0_conf_t; + +am18x_rt usb0_conf(const usb0_conf_t* conf); +uint32_t usb0_intr_state(void); +am18x_rt usb0_intr_clear(void); + +#endif//__AM18X_USB_H__ diff --git a/lib/am18x-lib/lib/_uart.h b/lib/am18x-lib/lib/_uart.h new file mode 100644 index 000000000..e6f81e0a9 --- /dev/null +++ b/lib/am18x-lib/lib/_uart.h @@ -0,0 +1,11 @@ +// tary, 22:14 2012/12/28 +#ifndef __UART_H__ +#define __UART_H__ + +int uart_init(void); +int putchar(int c); +int getchar(void); +int peekchar(void); +int uart_gets(char *line, int n); + +#endif//__UART_H__ diff --git a/lib/am18x-lib/lib/arm920t.c b/lib/am18x-lib/lib/arm920t.c new file mode 100644 index 000000000..c4bc133d4 --- /dev/null +++ b/lib/am18x-lib/lib/arm920t.c @@ -0,0 +1,67 @@ +// tary, 1:15 2011/8/3 +#include "arm920t.h" +#include "auxlib.h" + +int arm_mmu_show_id_code(void) { + cp15_id_code_t id[1]; + + id[0] = arm_read_cp15_id_code(); + + printk("MMU\tLayoutRev\t= 0x%X\n", id->LayoutRev); + printk("\tPartNumber\t= 0x%X\n", id->PartNumber); + printk("\tArchitecture\t= 0x%X\n", id->Architecture); + printk("\tSpecRev \t= 0x%X\n", id->SpecRev); + printk("\tImplementer\t= 0x%X\n", id->Implementer); + + return 0; +} + +int arm_mmu_show_cache_type(void) { + cp15_cache_type_t ctype[1]; + + ctype[0] = arm_read_cp15_cache_type(); + + printk("MMU\tIlen\t= 0x%X\n", ctype->Ilen); + printk("\tIM\t= 0x%X\n", ctype->IM); + printk("\tIassoc\t= 0x%X\n", ctype->Iassoc); + printk("\tIsize\t= 0x%X\n", ctype->Isize); + printk("\tDlen\t= 0x%X\n", ctype->Dlen); + printk("\tDM\t= 0x%X\n", ctype->DM); + printk("\tDassoc\t= 0x%X\n", ctype->Dassoc); + printk("\tDsize\t= 0x%X\n", ctype->Dsize); + printk("\tS\t= 0x%X\n", ctype->S); + printk("\tctype\t= 0x%X\n", ctype->ctype); + + printk("MMU\tDCache Size \t= %d KB\n", (1 << ctype->Dsize) >> 1); + printk("\tDCache Line length\t= %d bytes\n", 8 << ctype->Dlen); + printk("\tDCache associativity\t= %d-way\n", (1 << ctype->Dassoc)); + printk("\tICache Size \t= %d KB\n", (1 << ctype->Isize) >> 1); + printk("\tICache Line length\t= %d bytes\n", 8 << ctype->Ilen); + printk("\tICache associativity\t= %d-way\n", (1 << ctype->Iassoc)); + + return 0; +} + +int arm_mmu_show_control(const cp15_control_t* c1) { + printk("M = %d \tMMU \t%s\n", c1->M, c1->M? "enabled": "disabled"); + printk("A = %d \tAlignFault \t%s\n", c1->A, c1->A? "enabled": "disabled"); + printk("C = %d \tDCache \t%s\n", c1->C, c1->C? "enabled": "disabled"); + printk("B = %d \tEndianness \t%s-endian\n", c1->B, c1->B? "Big": "Little"); + printk("S = %d \tSystemProtect\n", c1->S); + printk("R = %d \tROMProtect\n", c1->R); + printk("I = %d \tICache \t%s\n", c1->I, c1->I? "enabled": "disabled"); + printk("V = %d \tVectLocate \t%s\n", c1->V, c1->V? "High(0xFFFF0000)": "Normal(0x00000000)"); + printk("RR = %d \tCacheReplace\t%s\n", c1->RR,c1->RR? "Round-robin": "Random"); + printk("L4 = %d \tLoadSetTbit\n", c1->L4); + + return 0; +} + +unsigned arm_read_cp15_fault_address(void) { + unsigned fadr; + + asm volatile( + "mrc p15, 0, %0, c6, c0, 0\n" + : "=r"(fadr)); + return fadr; +} diff --git a/lib/am18x-lib/lib/arm920t.h b/lib/am18x-lib/lib/arm920t.h new file mode 100644 index 000000000..fffff7588 --- /dev/null +++ b/lib/am18x-lib/lib/arm920t.h @@ -0,0 +1,401 @@ +// tary, 0:20 2011/8/1 +#ifndef __ARM920T_H__ +#define __ARM920T_H__ + +// ARM920T (Rev 1) Technical Reference Manual + +#define XPSR_MODE_MASK 0x1F +#define XPSR_Mode_User 0x10 //usr +#define XPSR_Mode_FIQ 0x11 //fiq +#define XPSR_Mode_IRQ 0x12 //irq +#define XPSR_Mode_Supervisor 0x13 //svc +#define XPSR_Mode_Abort 0x17 //abt +#define XPSR_Mode_Undefined 0x1B //und +#define XPSR_Mode_System 0x1F //sys +#define XPSR_F_Thumb (0x1 << 5) +#define XPSR_F_FIQ (0x1 << 6) +#define XPSR_F_IRQ (0x1 << 7) +//#define XPSR_F_Q (0x1 << 27) +#define XPSR_F_oVerflow (0x1 << 28) +#define XPSR_F_Carry (0x1 << 29) +#define XPSR_F_Zero (0x1 << 30) +#define XPSR_F_Negative (0x1 << 31) + +#ifndef __ASSEMBLY__ +void arm_intr_disable(void); +void arm_intr_enable(void); +#else +.EXTERN arm_intr_disable +.EXTERN arm_intr_enable +.EXTERN arm_mmu_disable +.EXTERN arm_mmu_enable +#endif + +// 2.3 CP15 register map summary + +#define CP15_C0_IDCode c0 +#define CP15_C0_CacheType c0 +#define CP15_C1_Control c1 +#define CP15_C2_TransTableBase c2 +#define CP15_C3_Domain c3 +//#define CP15_C4_Unpredictable c4 +#define CP15_C5_FaultStatus c5 +#define CP15_C6_FaultAddress c6 +#define CP15_C7_CacheOps c7 +#define CP15_C8_TLBOps c8 +#define CP15_C9_CacheLockdown c9 +#define CP15_C10_TLBLockdown c10 +//#define CP15_C11_Unpredictable c11 +//#define CP15_C12_Unpredictable c12 +#define CP15_C13_FCSEPID c13 +//#define CP15_C14_Unpredictable c14 +#define CP15_C15_TestConfig c15 + +#ifndef __ASSEMBLY__ +// c0, ID code register, read-only +typedef struct { + unsigned LayoutRev: 4; + unsigned PartNumber: 12; + unsigned Architecture: 4; + unsigned SpecRev: 4; + unsigned Implementer: 8; +} cp15_id_code_t; + +static inline cp15_id_code_t arm_read_cp15_id_code(void) { + cp15_id_code_t c0; + + asm volatile( + "mrc p15, 0, %0, c0, c0, 0\n" + : "=r" (c0) + ); + return c0; +} +int arm_mmu_show_id_code(void); +#endif + +#define CP15_C0_LayoutRev_MASK (0xF << 0) +#define CP15_C0_PartNumber_MASK (0xFFF << 4) +#define CP15_C0_Architecture_MASK (0xF << 16) +#define CP15_C0_SpecRev_MASK (0xF << 20) +#define CP15_C0_Implementer_MASK (0xFF << 24) + +#ifndef __ASSEMBLY__ +// c0, cache type register, read-only +typedef struct { + unsigned Ilen: 2; + unsigned IM: 1; + unsigned Iassoc: 3; + unsigned Isize: 3; + unsigned Ires: 3; + unsigned Dlen: 2; + unsigned DM: 1; + unsigned Dassoc: 3; + unsigned Dsize: 3; + unsigned Dres: 3; + unsigned S: 1; + unsigned ctype: 4; +} cp15_cache_type_t; + +static inline cp15_cache_type_t arm_read_cp15_cache_type(void) { + cp15_cache_type_t c0; + + asm volatile( + "mrc p15, 0, %0, c0, c0, 1\n" + : "=r" (c0) + ); + return c0; +} +int arm_mmu_show_cache_type(void); +#endif + +#define CP15_C0_Isize_MASK (0xFFF << 0) +#define CP15_C0_Dsize_MASK (0xFFF << 12) +#define CP15_C0_S_MASK (0x1 << 24) +#define CP15_C0_ctype_MASK (0xF << 25) + +#ifndef __ASSEMBLY__ +// c1, control register, read-write +typedef struct { + unsigned M: 1; // 0 + unsigned A: 1; // 1 + unsigned C: 1; // 2 + unsigned SBO0: 4; // 3 + unsigned B: 1; // 7 + unsigned S: 1; // 8 + unsigned R: 1; // 9 + unsigned SBZ0: 2; // 10 + unsigned I: 1; // 12 + unsigned V: 1; // 13 + unsigned RR: 1; // 14 + unsigned L4: 1; // 15 + unsigned SBO1: 1; // 16 + unsigned SBZ1: 1; // 17 + unsigned SBO2: 1; // 18 + unsigned RES0: 13;// 19 +} cp15_control_t; + +static inline cp15_control_t arm_read_cp15_control(void) { + cp15_control_t c1; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + : "=r" (c1) + ); + return c1; +} +static inline cp15_control_t arm_write_cp15_control(cp15_control_t c1) { + asm volatile( + "mcr p15, 0, %0, c1, c0, 0\n" + : "=r" (c1) + ); + return c1; +} +int arm_mmu_show_control(const cp15_control_t* c1); +#endif + +#define CP15_C1_ClockMode_MASK (0x3 << 30) +#define CP15_C1_ClockMode_FastBus (0x0 << 30) +#define CP15_C1_ClockMode_Sync (0x1 << 30) +#define CP15_C1_ClockMode_Async (0x3 << 30) +#define CP15_C1_M_MMU_Enable (0x1 << 0) +#define CP15_C1_A_AlignFaultEnable (0x1 << 1) +#define CP15_C1_C_DCacheEnable (0x1 << 2) +#define CP15_C1_B_BigEndian (0x1 << 7) +#define CP15_C1_S_SystemProtect (0x1 << 8) +#define CP15_C1_R_ROM_Protect (0x1 << 9) +#define CP15_C1_I_ICacheEnable (0x1 << 12) +#define CP15_C1_V_ExceptionHighAddr (0x1 << 13) +#define CP15_C1_RR_RoundRobin (0x1 << 14) +#define CP15_C1_nF_notFastBus (0x1 << 30) +#define CP15_C1_iA_AsyncClock (0x1 << 31) + +// c2, translation table base, read-write +#define CP15_C2_TTB_MASK 0xFFFFC000 + +// c3, domain access control register, read-write +#define CP15_C3_Domain_MASK(x) (0x3 << (x << 1)) +#define CP15_C3_Domain_X(acc, x) ((acc) << (x << 1)) + +// c5, fault status registers, read-modify-write +#define CP15_C5_FaultType_MASK (0xF << 0) +#define CP15_C5_DomainAccess_MASK (0xF << 4) +#define CP15_C5_DataFSR c5, c0, 0 +#define CP15_C5_PrefetchFSR c5, c0, 1 + +// c6, fault address register, read-write +#define CP15_C6_MASK ((unsigned long)-1) + +#ifndef __ASSEMBLY__ +unsigned arm_read_cp15_fault_address(void); +#else +.EXTERN arm_read_cp15_fault_address +#endif + +// c7, cache operation register, write-only +#define CP15_C7_InvalidICacheDCache c7, c7, 0 +#define CP15_C7_InvalidICache c7, c5, 0 +#define CP15_C7_InvalidICacheEntry c7, c5, 1 +#define CP15_C7_PretechICacheLine c7, c13, 1 +#define CP15_C7_InvalidDCache c7, c6, 0 +#define CP15_C7_InvalidDCacheEntry c7, c6, 1 +#define CP15_C7_CleanDCacheEntry c7, c10, 1 +#define CP15_C7_CleanInvalidDCacheEntry c7, c14, 1 +#define CP15_C7_CleanDCacheIndex c7, c10, 2 +#define CP15_C7_CleanInvalidDCacheIndex c7, c14, 2 +#define CP15_C7_DrainWriteBuffer c7, c10, 4 +#define CP15_C7_WaitForInterrupt c7, c0, 4 + +#ifndef __ASSEMBLY__ +static inline int arm_wfi(void) { + asm volatile( + "mov r0, #0\n" + "mcr p15, 0, r0, c7, c0, 4\n" /* wait for interrupt */ + ::: "r0" + ); + return 0; +} +#endif + +#define CP15_C7_MVA_MASK 0xFFFFFFE0 +#define CP15_C7_IndexIdx_MASK (0x3F << 26) +#define CP15_C7_IndexIdx_X(x) ((x) << 26) +#define CP15_C7_IndexSeg_MASK (0x7 << 5) +#define CP15_C7_IndexSeg_X(x) ((x) << 5) + +// c8, TLB operations register, write-only +#define CP15_C8_InvalidTLB c8, c7, 0 +#define CP15_C8_InvalidITLB c8, c5, 0 +#define CP15_C8_InvalidITLBEntry c8, c5, 1 +#define CP15_C8_InvalidDTLB c8, c6, 0 +#define CP15_C8_InvalidDTLBEntry c8, c6, 1 + +#ifndef __ASSEMBLY__ +static inline int arm_tlb_invalid_all(void) { + asm volatile( + "mov r0, #0\n" + "mcr p15, 0, r0, c7, c10, 4\n" /* drain WB */ + "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate I & D TLBs */ + ::: "r0" + ); + return 0; +} +#endif + + +#define CP15_C8_MVA_MASK 0xFFFFFC00 + +// c9, cache lockdown register, read-write +#define CP15_C9_DCacheLockdown c9, c0, 0 +#define CP15_C9_ICacheLockdown c9, c0, 1 + +#define CP15_C9_Index_MASK (0x3F << 26) + +// c10, TLB lockdown register, read-write +#define CP15_C10_DTLBLockdown c10, c0, 0 +#define CP15_C10_ITLBLockdown c10, c0, 1 + +#define CP15_C10_Base_MASK (0x3F << 26) +#define CP15_C10_Victim_MASK (0x3F << 20) +#define CP15_C10_P_PreserveMASK (0x1 << 0) + +// c13, FCSE PID register, read-write +#define CP15_C13_FCSE_PID_MASK (0x7F << 25) + +// c15, test configuration register + + +// 3.3.3 Level one descriptor +#define DESC_L1_TYPE_MASK (0x3 << 0) +#define DESC_L1_TYPE_Invalid 0x0 +#define DESC_L1_TYPE_CoarsePage 0x1 +#define DESC_L1_TYPE_Section 0x2 +#define DESC_L1_TYPE_FinePage 0x3 + +#define DESC_CB_MASK (0x3 << 2) +#define DESC_NCNB (0x0 << 2) //Noncached, nonbuffered +#define DESC_NCB (0x1 << 2) //Noncached, buffered +#define DESC_WT (0x2 << 2) //Cached write-through mode +#define DESC_WB (0x3 << 2) //Cached write-back mode + +#define DESC_L1_CONST_Bit4 (0x1 << 4) +#define DESC_L1_Domain_MASK (0xF << 5) +#define DESC_L1_Domain_X(x) ((x) << 5) +#define DESC_L1_Sec_AP_MASK (0x3 << 10) +#define DESC_L1_Sec_AP_X(x) ((x) << 10) + +// coarse page tables have 256 entries +// occupy space 256 * 4 = 1KB +// 1 entry for (1MB / 256) = 4KB +#define DESC_L1_CoarseBase_MASK 0xFFFFFC00 +// 1 section entry for 1MB +#define DESC_L1_SectionBase_MASK 0xFFF00000 +// fine page tables have 1024 entries +// occupy space 1024 * 4 = 4KB +// 1 entry for (1MB / 1024) = 1KB +#define DESC_L1_FineBase_MASK 0xFFFFF000 + +// 3.3.8 Level two descriptor +#define DESC_L2_TYPE_MASK (0x3 << 0) +#define DESC_L2_TYPE_Invalid 0x0 +#define DESC_L2_TYPE_Large 0x1 +#define DESC_L2_TYPE_Small 0x2 +#define DESC_L2_TYPE_Tiny 0x3 + +// x = 0..3 +#define DESC_L2_APx_MASK(x) (0x30 << ((x) << 1)) +#define DESC_L2_Tiny_ap_MASK 0x30 + +// 64KB, 16 identical entries in Coarse table +// 64 identical entries in Fine table +#define DESC_L2_LargeBase_MASK 0xFFFF0000 +// 4KB, 1 entry in Coarse table +// 4 identical entries in Fine table +#define DESC_L2_SmallBase_MASK 0xFFFFF000 +// only provide by Fine page table entry +// 1KB, 1 entry in Fine table +#define DESC_L2_TinyBase_MASK 0xFFFFFC00 + +// 3.4 MMU faults and CPU aborts +// Alignment fault isn't affected by whether +// or not the MMU is enabled. +// Translation, domain, permission faults +// are only generated when the MMU is enabled. + +// 3.5 Fault address and fault status register +// You can find the address for a prefetch fault in R14. +// The FAR is not updated by faults caused by instruction prefetches. + +// 3.6 Domain access control +#define DOMAIN_NoAccess 0x0 +#define DOMAIN_Client 0x1 +#define DOMAIN_Manager 0x3 + +// When AP == 0 +// Super read-only or Super & User read-only +#define RS_NoAccess 0x0 +#define RS_OnlySuperRead 0x1 +#define RS_OnlyRead 0x2 + +// Super for read-write, set for user permission +#define AP_SelectRS 0x0 +#define AP_NoUserAccess 0x1 +#define AP_NoUserWrite 0x2 +#define AP_NoCheck 0x3 + +// 3.7 Fault checking sequence +// 1 Alignment fault +// Check address alignment = Misaligned +// 2 Section translation fault +// Get Level one descriptor = Invalid +// 3 Page translation fault +// If page access and get page table entry = Invalid +// 4 Section or Page domain fault +// Check domain status = No access +// 5 Section or Page permission fault +// If domain client and check access permissions = Violation + +// 3.9 Interaction of the MMU and caches +// 3.9.1 Enabling the MMU +// 1 Program the TTB and domain access control registers +// 2 Program level 1 and level 2 page tables as required +// 3 Enable the MMU by setting bit 0 in the control register +// You can enable the ICache and DCache simultaneously with +// the MMU using a single MCR instruction +// 3.9.2 Disabling the MMU +// The data cache must be disabled prior to, +// or at the same time as, disable the MMU. +// If the MMU is enabled, then disabled and subsequently +// re-enabled, the contents of the TLBs are preserved. +// If these are now invalid, you must invalidate the TLBs +// before re-enabling the MMU. + +// 4.2 ICache +// 4.2.2 Enabling and disabling the ICache +// If the cache is subsequently re-enabled its contents +// are unchanged. If the contents are no longer coherent +// with main memory, you must invalidate the ICache before +// you re-enable it. +// 4.2.3 ICache operation +// Ctt bit in the relevant MMU translation table descriptor +// is only used for cache miss, whether there is a eight-word +// linefill or a noncacheable single nonsequential memory access +// appears. + +// 4.3 DCache and write buffer +// 4.3.1 Enabling and disabling the DCache and write buffer +// If the cache is subsequently re-enabled its contents are +// unchanged. Depending on the software system design, you might +// have to clean the cache after it is disabled, and invalidate it +// before you re-enable it. +// 4.3.2 DCache and write buffer operation +// If the DCache is enabled, a DCache lookup is performed for each +// data access initiated by the ARM9TDMI CPU core, regardless of +// the value of Ctt bit in the relevant MMU translation table +// descriptor. +// If the operating system has to change the C and B bits of a page +// table discriptor, it must ensure that the caches do not contain +// any data controlled by that descriptor. In some circumstances, +// the operating system might have to clean and flush the caches to +// ensure this. + +#endif//__ARM920T_H__ diff --git a/lib/am18x-lib/lib/arm920t_s.S b/lib/am18x-lib/lib/arm920t_s.S new file mode 100644 index 000000000..72cc0b6ad --- /dev/null +++ b/lib/am18x-lib/lib/arm920t_s.S @@ -0,0 +1,47 @@ +@ tary, 1:17 2011/8/3 +#include "arm920t.h" + + .SECTION .text, "ax" + .arm + + .GLOBAL arm_intr_disable +arm_intr_disable: + PUSH {R0} + MRS R0, CPSR + ORR R0, R0, # XPSR_F_IRQ | XPSR_F_FIQ + MSR CPSR_c, R0 + POP {R0} + MOV PC, LR + + .GLOBAL arm_intr_enable +arm_intr_enable: + PUSH {R0} + MRS R0, CPSR + BIC R0, R0, # XPSR_F_IRQ | XPSR_F_FIQ + MSR CPSR_c, R0 + POP {R0} + MOV PC, LR + + @ enable MMU + .GLOBAL arm_mmu_enable +arm_mmu_enable: + PUSH {R1} + MRC p15, 0, R1, C1, C0, 0 + ORR R1, #0x1 + MCR p15, 0, R1, C1, C0, 0 + @ !!! make here one instruction between mcr and mov + POP {R1} + MOV PC, LR + + @ disable MMU + .GLOBAL arm_mmu_disable +arm_mmu_disable: + PUSH {R1} + MRC p15, 0, R1, C1, C0, 0 + BIC R1, R1, #0x5 + MCR p15, 0, R1, C1, C0, 0 + @ !!! make here one instruction between mcr and mov + POP {R1} + MOV PC, LR + + .END diff --git a/lib/am18x-lib/lib/auxlib.c b/lib/am18x-lib/lib/auxlib.c new file mode 100644 index 000000000..246a16bac --- /dev/null +++ b/lib/am18x-lib/lib/auxlib.c @@ -0,0 +1,214 @@ +// tary 22:35 2011/6/19 +#include +#include "ctype.h" +#include "auxlib.h" +#include "_uart.h" + +#ifndef NULL +#define NULL ((void*)0) +#endif + +extern int vsprintf(char *buf, const char *fmt, va_list args); + +int delay(int d) { + for (;d > 0; d--) { + asm volatile("nop"); + } + return 0; +} + +int puts(const char* s) { + const char* st = s; + while (*s) { + putchar(*s++); + } + return s - st; +} + +int printk(const char* s, ...) { + static char prbuf[1024]; + va_list v; + int r; + + va_start(v, s); + r = vsprintf(prbuf, s, v); + puts(prbuf); + va_end(v); + return r; +} + +int memset(void* dst, int pattern, size_t size) { + char* dstc; + int i; + + dstc = (char*)dst; + for (i = 0; i < size; i++) { + dstc[i] = pattern; + } + return size; +} + +int memcpy(char* dst, const char* src, size_t size) { + int i; + + for (i = 0; i < size; i++) { + dst[i] = src[i]; + } + return size; +} + +size_t strlen(const char* s) { + const char* b = s; + + while (*++s); + return s - b; +} + +size_t strnlen(const char* s, size_t size) { + size_t i; + + for (i = 0; i < size && s[i] != 0; i++); + + return i; +} + +int strcmp(const char* ss, const char* sd) { + for (;*ss && *sd && *ss == *sd; ss++, sd++); + return *ss - *sd; +} + +int strncmp(const char* ss, const char* sd, size_t size) { + size_t i; + for (i = 0; i < size && *ss == *sd && *ss; ss++, sd++, i++); + return *ss - *sd; +} + +const char* strchr(const char* s, char c) { + for (; *s && *s != c; s++); + if (*s == c) { + return s; + } + return NULL; +} + +int debug_buf(const char* head, char* buf, int len) { + int i; + + printk("\nDBG:%s[%d] = \n\t", head, len); + for (i = 0; i < len; i++) { + printk("%.2X ", buf[i]); + if ((i & 0xFUL) == 0xFUL && i != len - 1) { + printk("\n\t"); + } + } + printk("\n"); + return len; +} + +int debug_line(const char* file, int lin, int nr, ...) { + int val = 0; + const char* s; + va_list ap; + + printk("\nDBG:%s() L%d\t", file, lin); + + va_start(ap, nr); + while (nr-- > 0) { + s = va_arg(ap, char*); + if (nr-- <= 0) { + printk(s); + break; + } + val = va_arg(ap, int); + if (strchr(s, '%') == NULL) { + printk("%s=%d", s, val); + } else { + printk(s, val); + } + } + va_end(ap); + printk("\n"); + + return nr; +} + +int dump_regs_word(const char* head, unsigned base, size_t size) { + int i; + + for (i = 0; i < size / sizeof (unsigned long); i++) { + printk("%s[0x%.2X] = 0x%.8X\n", head, i << 2, ((volatile unsigned*)base)[i]); + } + return 0; +} + +// read a unsigned value from bytes [buf, buf + size) +unsigned get_byte_uint(char* buf, int size, int bigend) { + int i; + unsigned r = 0; + unsigned char* ubuf = (unsigned char*)buf; + + if (size > sizeof(unsigned)) size = sizeof(unsigned); + + if (! bigend) { + memcpy((char*)&r, &buf[0], size); + return r; + } + + for(i = 0; i < size; i++) { + r = (r << 8) + ubuf[i]; + } + return r; +} + +// write a unsigned value to bytes [buf, buf + size) +int set_byte_uint(char* buf, int size, unsigned value, int bigend) { + int i; + unsigned r; + + r = value; + if (size > sizeof(unsigned)) size = sizeof(unsigned); + + if (! bigend) { + memcpy(&buf[0], (char*)&r, size); + return r; + } + + for (i = size - 1; i >= 0; i--) { + buf[i] = value & 0xFF; + value >>= 8; + } + return r; +} + +int make_argv(char* s, int size, char *argv[], int av_max) { + char* se; + int n; + + n = 0; + se = s + size - 1; + while (s < se && *s && isspace(*s)) { + s++; + } + + while (s < se && *s && n < av_max - 1) { + if (*s) { + argv[n++] = s; + } + + while (s < se && *s && ! isspace(*s)) { + s++; + } + + if (s < se && *s) { + *s++ = '\0'; + } + + while (s < se && *s && isspace(*s)) { + s++; + } + } + + argv[n] = NULL; + + return n; +} diff --git a/lib/am18x-lib/lib/auxlib.h b/lib/am18x-lib/lib/auxlib.h new file mode 100644 index 000000000..e778270fb --- /dev/null +++ b/lib/am18x-lib/lib/auxlib.h @@ -0,0 +1,56 @@ +// tary 22:22 2011/6/19 +#ifndef __AUXLIB_H__ +#define __AUXLIB_H__ + +#if defined(LBP_DBG) +#define DBG_LINE(nr, ...) do { \ + if (LOCAL_DBG) debug_line(__FUNCTION__, __LINE__, nr, __VA_ARGS__); \ + }while(0) +#define DBG_BUF(name, buf, size) do { \ + if (LOCAL_DBG) debug_buf(name, buf, size); \ + }while(0) +#define DBG_PRINT(fmt, ...) do { \ + if (LOCAL_DBG){ \ + printf("\r\nDBG:%s() L%d\t", __FUNCTION__, __LINE__); \ + printf(fmt, __VA_ARGS__); \ + } }while(0) +#else +#define DBG_LINE(...) +#define DBG_BUF(...) +#define DBG_PRINT(...) +#endif//LBP_DBG + +#include +#define KV(x) { x, #x } +#define KOF(s,x) { offsetof(s,x), #x } +typedef struct { + int key; + char* val; +} kv_t; + +// typedef unsigned long size_t; + +int delay(int d); +#ifndef __LINUX_STRING_H__ +int puts(const char* s); +#endif +int printk(const char* s, ...); +int sscanf(const char* buf, const char* fmt, ...); +int sprintf(char * buf, const char *fmt, ...); +size_t strlen(const char* s); +int strcmp(const char* ss, const char* sd); +int strncmp(const char* ss, const char* sd, size_t size); +#ifndef __LINUX_STRING_H__ +int memset(void* dst, int pattern, size_t size); +int memcpy(char* dst, const char* src, size_t size); +#endif +int debug_buf(const char* head, char* buf, int len); +int debug_line(const char* file, int lin, int nr, ...); +int dump_regs_word(const char* head, unsigned base, size_t size); +unsigned get_byte_uint(char* buf, int size, int bigend); +int set_byte_uint(char* buf, int size, unsigned value, int bigend); +int make_argv(char* s, int size, char *argv[], int av_max); + +unsigned get_exec_base(void); + +#endif //__AUXLIB_H__ diff --git a/lib/am18x-lib/lib/ctype.c b/lib/am18x-lib/lib/ctype.c new file mode 100644 index 000000000..300845f1c --- /dev/null +++ b/lib/am18x-lib/lib/ctype.c @@ -0,0 +1,34 @@ +/* + * linux/lib/ctype.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include "ctype.h" + +unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + diff --git a/lib/am18x-lib/lib/ctype.h b/lib/am18x-lib/lib/ctype.h new file mode 100644 index 000000000..afa363922 --- /dev/null +++ b/lib/am18x-lib/lib/ctype.h @@ -0,0 +1,54 @@ +#ifndef _LINUX_CTYPE_H +#define _LINUX_CTYPE_H + +/* + * NOTE! This ctype does not handle EOF like the standard C + * library is required to. + */ + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +extern unsigned char _ctype[]; + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char __toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) + +#endif diff --git a/lib/am18x-lib/lib/div64.S b/lib/am18x-lib/lib/div64.S new file mode 100644 index 000000000..9b37b0ed8 --- /dev/null +++ b/lib/am18x-lib/lib/div64.S @@ -0,0 +1,183 @@ +/* + * linux/arch/arm/lib/div64.S + * + * Optimized computation of 64-bit dividend / 32-bit divisor + * + * Author: Nicolas Pitre + * Created: Oct 5, 2003 + * Copyright: Monta Vista Software, Inc. + * + * 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. + */ + +#define ENDPROC(x) + +#ifdef __ARMEB__ +#define xh r0 +#define xl r1 +#define yh r2 +#define yl r3 +#else +#define xl r0 +#define xh r1 +#define yl r2 +#define yh r3 +#endif + +/* + * __do_div64: perform a division with 64-bit dividend and 32-bit divisor. + * + * Note: Calling convention is totally non standard for optimal code. + * This is meant to be used by do_div() from include/asm/div64.h only. + * + * Input parameters: + * xh-xl = dividend (clobbered) + * r4 = divisor (preserved) + * + * Output values: + * yh-yl = result + * xh = remainder + * + * Clobbered regs: xl, ip + */ + +.GLOBAL __do_div64 +__do_div64: + + + @ Test for easy paths first. + subs ip, r4, #1 + bls 9f @ divisor is 0 or 1 + tst ip, r4 + beq 8f @ divisor is power of 2 + + @ See if we need to handle upper 32-bit result. + cmp xh, r4 + mov yh, #0 + blo 3f + + @ Align divisor with upper part of dividend. + @ The aligned divisor is stored in yl preserving the original. + @ The bit position is stored in ip. + + mov yl, r4 + mov ip, #1 +1: cmp yl, #0x80000000 + cmpcc yl, xh + movcc yl, yl, lsl #1 + movcc ip, ip, lsl #1 + bcc 1b + + @ The division loop for needed upper bit positions. + @ Break out early if dividend reaches 0. +2: cmp xh, yl + orrcs yh, yh, ip + subcss xh, xh, yl + movnes ip, ip, lsr #1 + mov yl, yl, lsr #1 + bne 2b + + @ See if we need to handle lower 32-bit result. +3: cmp xh, #0 + mov yl, #0 + cmpeq xl, r4 + movlo xh, xl + movlo pc, lr + + @ The division loop for lower bit positions. + @ Here we shift remainer bits leftwards rather than moving the + @ divisor for comparisons, considering the carry-out bit as well. + mov ip, #0x80000000 +4: movs xl, xl, lsl #1 + adcs xh, xh, xh + beq 6f + cmpcc xh, r4 +5: orrcs yl, yl, ip + subcs xh, xh, r4 + movs ip, ip, lsr #1 + bne 4b + mov pc, lr + + @ The top part of remainder became zero. If carry is set + @ (the 33th bit) this is a false positive so resume the loop. + @ Otherwise, if lower part is also null then we are done. +6: bcs 5b + cmp xl, #0 + moveq pc, lr + + @ We still have remainer bits in the low part. Bring them up. + +7: movs xl, xl, lsl #1 + mov ip, ip, lsr #1 + bcc 7b + + + @ Current remainder is now 1. It is worthless to compare with + @ divisor at this point since divisor can not be smaller than 3 here. + @ If possible, branch for another shift in the division loop. + @ If no bit position left then we are done. + movs ip, ip, lsr #1 + mov xh, #1 + bne 4b + mov pc, lr + +8: @ Division by a power of 2: determine what that divisor order is + @ then simply shift values around + + mov yl, r4 + cmp r4, #(1 << 16) + mov ip, #0 + movhs yl, yl, lsr #16 + movhs ip, #16 + + cmp yl, #(1 << 8) + movhs yl, yl, lsr #8 + addhs ip, ip, #8 + + cmp yl, #(1 << 4) + movhs yl, yl, lsr #4 + addhs ip, ip, #4 + + cmp yl, #(1 << 2) + addhi ip, ip, #3 + addls ip, ip, yl, lsr #1 + + mov yh, xh, lsr ip + mov yl, xl, lsr ip + rsb ip, ip, #32 + orr yl, yl, xh, lsl ip + mov xh, xl, lsl ip + mov xh, xh, lsr ip + mov pc, lr + + @ eq -> division by 1: obvious enough... +9: moveq yl, xl + moveq yh, xh + moveq xh, #0 + moveq pc, lr + + @ Division by 0: + str lr, [sp, #-8]! + bl __div0 + + @ as wrong as it could be... + mov yl, #0 + mov yh, #0 + mov xh, #0 + ldr pc, [sp], #8 + +ENDPROC(__do_div64) + + .global __div0 + .extern puts +__div0: + push {lr} + adr r0, __div_0__ + bl puts + pop {pc} +__div_0__: + .string "division by 0\n" + .balign 4 + .end diff --git a/lib/am18x-lib/lib/div64.h b/lib/am18x-lib/lib/div64.h new file mode 100644 index 000000000..4bfa15df9 --- /dev/null +++ b/lib/am18x-lib/lib/div64.h @@ -0,0 +1,73 @@ +#ifndef __ASM_ARM_DIV64 +#define __ASM_ARM_DIV64 + +/* + * The semantics of do_div() are: + * + * uint32_t do_div(uint64_t *n, uint32_t base) + * { + * uint32_t remainder = *n % base; + * *n = *n / base; + * return remainder; + * } + * + * In other words, a 64-bit dividend with a 32-bit divisor producing + * a 64-bit result and a 32-bit remainder. To accomplish this optimally + * we call a special __do_div64 helper with completely non standard + * calling convention for arguments and results (beware). + */ + +#define __xl "r0" +#define __xh "r1" +#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" + + +#define __do_div_asm(n, base) \ +({ \ + register unsigned int __base asm("r4") = base; \ + register unsigned long long __n asm("r0") = n; \ + register unsigned long long __res asm("r2"); \ + register unsigned int __rem asm(__xh); \ + asm( __asmeq("%0", __xh) \ + __asmeq("%1", "r2") \ + __asmeq("%2", "r0") \ + __asmeq("%3", "r4") \ + "bl __do_div64" \ + : "=r" (__rem), "=r" (__res) \ + : "r" (__n), "r" (__base) \ + : "ip", "lr", "cc"); \ + n = __res; \ + __rem; \ +}) + + +/* + * If the divisor happens to be constant, we determine the appropriate + * inverse at compile time to turn the division into a few inline + * multiplications instead which is much faster. And yet only if compiling + * for ARMv4 or higher (we need umull/umlal) and if the gcc version is + * sufficiently recent to perform proper long long constant propagation. + * (It is unfortunate that gcc doesn't perform all this internally.) + */ +#define do_div(n, base) \ +({ \ + unsigned int __r, __b = (base); \ + /* non-constant divisor (or zero): slow path */ \ + __r = __do_div_asm(n, __b); \ + __r; \ +}) + +/* our own fls implementation to make sure constant propagation is fine */ +#define __div64_fls(bits) \ +({ \ + unsigned int __left = (bits), __nr = 0; \ + if (__left & 0xffff0000) __nr += 16, __left >>= 16; \ + if (__left & 0x0000ff00) __nr += 8, __left >>= 8; \ + if (__left & 0x000000f0) __nr += 4, __left >>= 4; \ + if (__left & 0x0000000c) __nr += 2, __left >>= 2; \ + if (__left & 0x00000002) __nr += 1; \ + __nr; \ +}) + + +#endif diff --git a/lib/am18x-lib/lib/dvfs.c b/lib/am18x-lib/lib/dvfs.c new file mode 100644 index 000000000..13a285f52 --- /dev/null +++ b/lib/am18x-lib/lib/dvfs.c @@ -0,0 +1,112 @@ +// tary, 14:11 2015/5/9 +#include "am18x_lib.h" +#include "tps6507x.h" +#include "_uart.h" +#include "dvfs.h" + +// am1808.pdf +// 4.2 Recommanded Operating Conditions +// Operating Frequency +typedef struct { + uint32_t freq; + uint16_t volt; +} opp_t; + +static opp_t opps[] = { + {F_OSCIN, 1000}, + {100000000UL, 1000}, + {200000000UL, 1100}, + {375000000UL, 1200}, + {456000000UL, 1300}, +}; + +static int abs(int x) { + return x > 0? x: -x; +} + +int dvfs_get_opp(void) { + int i, volt; + + if (pll_cmd(PLL0, PLL_CMD_IS_ENABLE, 0) != AM18X_OK) { + return 0; + } + + volt = tps6507x_get_output(PWR_TYPE_DCDC3); + for (i = 1; i < countof(opps); i++) { + if (abs(volt - opps[i].volt) < 50) { + break; + } + } + + if (i >= countof(opps)) { + i--; + } + return i; +} + +// unit, mV +int dvfs_get_volt(int opp) { + if (opp < 0 || opp >= countof(opps)) { + return 0; + } + return opps[opp].volt; +} + +int dvfs_get_freq(int opp) { + if (opp < 0 || opp >= countof(opps)) { + return 0; + } + return opps[opp].freq; +} + +#define _1K 1000UL +#define _1M 1000000UL + +int dvfs_set_opp(int opp) { + pll_conf_t pcf[1]; + int l_opp; + + l_opp = dvfs_get_opp(); + if (opp == l_opp) { + return 0; + } + + if (opp == 0) { + pll_cmd(PLL0, PLL_CMD_POWER_DOWN, 0); + tps6507x_set_output(PWR_TYPE_DCDC3, opps[opp].volt); + clk_node_recalc(); + uart_init(); + return 0; + } + + if (opp > l_opp) { + tps6507x_set_output(PWR_TYPE_DCDC3, opps[opp].volt); + } + pll_get_conf(PLL0, pcf); + + /* pll_freq = F_OSCIN / prediv * pllm / postdiv */ + pcf->prediv = 1UL; + pcf->postdiv = 1UL; + pcf->pllm = opps[opp].freq * pcf->postdiv / F_OSCIN * pcf->prediv; + + // am1808.pdf + // Page 79, + // The multiplier values must be chosen such that the PLL output + // frequency is between 300 and 600 MHz + while (F_OSCIN * pcf->pllm / pcf->prediv < 300UL * _1M) { + pcf->pllm <<= 1; + pcf->postdiv <<= 1; + } + while (F_OSCIN * pcf->pllm / pcf->prediv > 600UL * _1M) { + pcf->pllm >>= 1; + pcf->postdiv >>= 1; + } + pll_set_conf(PLL0, pcf); + if (opp < l_opp) { + tps6507x_set_output(PWR_TYPE_DCDC3, opps[opp].volt); + } + + clk_node_recalc(); + uart_init(); + return 0; +} diff --git a/lib/am18x-lib/lib/dvfs.h b/lib/am18x-lib/lib/dvfs.h new file mode 100644 index 000000000..5acec67e3 --- /dev/null +++ b/lib/am18x-lib/lib/dvfs.h @@ -0,0 +1,19 @@ +// tary, 14:17 2015/5/9 +#ifndef __DVFS_H__ +#define __DVFS_H__ + +enum { + OPP_OSC = 0, + OPP_100M, + OPP_200M, + OPP_375M, + OPP_456M, + OPP_CNT, +}; + +int dvfs_get_opp(void); +int dvfs_get_volt(int opp); +int dvfs_get_freq(int opp); +int dvfs_set_opp(int opp); + +#endif//__DVFS_H__ diff --git a/lib/am18x-lib/lib/i2c_inf.c b/lib/am18x-lib/lib/i2c_inf.c new file mode 100644 index 000000000..c6e1cb9fe --- /dev/null +++ b/lib/am18x-lib/lib/i2c_inf.c @@ -0,0 +1,101 @@ +// tary, 1:42 2013/4/28 +#include "am18x_lib.h" +#include "i2c_inf.h" + +// AM1808 I2C pins +#define I2C0_SCL 4,8,2 +#define I2C0_SDA 4,12,2 +#define I2C1_SCL 4,16,4 +#define I2C1_SDA 4,20,4 + +static i2c_conf_t iconf_buf[] = { +{ + 100000, + 0, + I2C_BITMODE_7BIT, + I2C_OPERMODE_Master_transmitter, +}, +{ + 100000, + 0, + I2C_BITMODE_7BIT, + I2C_OPERMODE_Master_transmitter, +}, +}; + +static i2c_conf_t* bus2conf(I2C_con_t* bus) { + if (bus == I2C0) { + return &iconf_buf[0]; + } + else if (bus == I2C1) { + return &iconf_buf[1]; + } + return NULL; +} + +int i2c_init(I2C_con_t* bus, uint32_t freq) { + if (bus == I2C0) { + syscfg_pinmux(I2C0_SCL); + syscfg_pinmux(I2C0_SDA); + } else + if (bus == I2C1) { + psc_state_transition(PSC_I2C1, PSC_STATE_ENABLE); + syscfg_pinmux(I2C1_SCL); + syscfg_pinmux(I2C1_SDA); + } + if (bus == I2C0 || bus == I2C1) { + bus2conf(bus)->freq = freq; + } + return 0; +} + +int i2c_read(I2C_con_t* bus, uint16_t dev, uint8_t* bytes, uint32_t cnt) { + int i; + i2c_conf_t* iconf = bus2conf(bus); + + iconf->opermode = I2C_OPERMODE_Master_receiver; + iconf->addr = dev; + i2c_conf(bus, iconf); + + i2c_cmd(bus, I2C_CMD_SET_CNT, cnt); + i2c_cmd(bus, I2C_CMD_WAIT_FREE, 0); + i2c_cmd(bus, I2C_CMD_BUS_START, 0); + i2c_cmd(bus, I2C_CMD_WAIT_BUSY, 0); + + for (i = 0; i < cnt; i++) { + // dump_regs_word("I2C0", (uint32_t)bus, sizeof(I2C_con_t)); + i2c_cmd(bus, I2C_CMD_WAIT_RX, 0); + bytes[i] = i2c_get_rx(bus); + } + + i2c_cmd(bus, I2C_CMD_WAIT_ARDY, 0); + i2c_cmd(bus, I2C_CMD_BUS_STOP, 0); + i2c_cmd(bus, I2C_CMD_WAIT_SLAVE, 0); + + return 0; +} + +int i2c_write(I2C_con_t* bus, uint16_t dev, cuint8_t* bytes, uint32_t cnt) { + int i; + i2c_conf_t* iconf = bus2conf(bus); + + iconf->opermode = I2C_OPERMODE_Master_transmitter; + iconf->addr = dev; + i2c_conf(bus, iconf); + + i2c_cmd(bus, I2C_CMD_SET_CNT, cnt); + i2c_cmd(bus, I2C_CMD_WAIT_FREE, 0); + i2c_cmd(bus, I2C_CMD_BUS_START, 0); + i2c_cmd(bus, I2C_CMD_WAIT_BUSY, 0); + + for (i = 0; i < cnt; i++) { + // dump_regs_word("I2C0", (uint32_t)bus, sizeof(I2C_con_t)); + i2c_cmd(bus, I2C_CMD_WAIT_TX, 0); + i2c_set_tx(bus, bytes[i]); + } + + i2c_cmd(bus, I2C_CMD_BUS_STOP, 0); + i2c_cmd(bus, I2C_CMD_WAIT_SLAVE, 0); + + return 0; +} diff --git a/lib/am18x-lib/lib/i2c_inf.h b/lib/am18x-lib/lib/i2c_inf.h new file mode 100644 index 000000000..b547f731d --- /dev/null +++ b/lib/am18x-lib/lib/i2c_inf.h @@ -0,0 +1,9 @@ +// tary, 1:42 2013/4/28 +#ifndef __I2C_INF_H__ +#define __I2C_INF_H__ + +int i2c_init(I2C_con_t* bus, uint32_t freq); +int i2c_read(I2C_con_t* bus, uint16_t dev, uint8_t* bytes, uint32_t cnt); +int i2c_write(I2C_con_t* bus, uint16_t dev, cuint8_t* bytes, uint32_t cnt); + +#endif//__I2C_INF_H__ diff --git a/lib/am18x-lib/lib/lib1funcs.S b/lib/am18x-lib/lib/lib1funcs.S new file mode 100644 index 000000000..8375a7bd0 --- /dev/null +++ b/lib/am18x-lib/lib/lib1funcs.S @@ -0,0 +1,346 @@ +/* + * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines + * + * Author: Nicolas Pitre + * - contributed to gcc-3.4 on Sep 30, 2003 + * - adapted for the Linux kernel on Oct 2, 2003 + */ + +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include + + +.macro ARM_DIV_BODY dividend, divisor, result, curbit + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \curbit, \divisor + clz \result, \dividend + sub \result, \curbit, \result + mov \curbit, #1 + mov \divisor, \divisor, lsl \result + mov \curbit, \curbit, lsl \result + mov \result, #0 + +#else + + @ Initially shift the divisor left 3 bits if possible, + @ set curbit accordingly. This allows for curbit to be located + @ at the left end of each 4 bit nibbles in the division loop + @ to save one loop in most cases. + tst \divisor, #0xe0000000 + moveq \divisor, \divisor, lsl #3 + moveq \curbit, #8 + movne \curbit, #1 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + movlo \curbit, \curbit, lsl #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + movlo \curbit, \curbit, lsl #1 + blo 1b + + mov \result, #0 + +#endif + + @ Division loop +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + orrhs \result, \result, \curbit + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + orrhs \result, \result, \curbit, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + orrhs \result, \result, \curbit, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + orrhs \result, \result, \curbit, lsr #3 + cmp \dividend, #0 @ Early termination? + movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? + movne \divisor, \divisor, lsr #4 + bne 1b + +.endm + + +.macro ARM_DIV2_ORDER divisor, order + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + rsb \order, \order, #31 + +#else + + cmp \divisor, #(1 << 16) + movhs \divisor, \divisor, lsr #16 + movhs \order, #16 + movlo \order, #0 + + cmp \divisor, #(1 << 8) + movhs \divisor, \divisor, lsr #8 + addhs \order, \order, #8 + + cmp \divisor, #(1 << 4) + movhs \divisor, \divisor, lsr #4 + addhs \order, \order, #4 + + cmp \divisor, #(1 << 2) + addhi \order, \order, #3 + addls \order, \order, \divisor, lsr #1 + +#endif + +.endm + + +.macro ARM_MOD_BODY dividend, divisor, order, spare + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + mov \divisor, \divisor, lsl \order + +#else + + mov \order, #0 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + addlo \order, \order, #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + addlo \order, \order, #1 + blo 1b + +#endif + + @ Perform all needed substractions to keep only the reminder. + @ Do comparisons in batch of 4 first. + subs \order, \order, #3 @ yes, 3 is intended here + blt 2f + +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + cmp \dividend, #1 + mov \divisor, \divisor, lsr #4 + subges \order, \order, #4 + bge 1b + + tst \order, #3 + teqne \dividend, #0 + beq 5f + + @ Either 1, 2 or 3 comparison/substractions are left. +2: cmn \order, #2 + blt 4f + beq 3f + cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +3: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +4: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor +5: +.endm + + +ENTRY(__udivsi3) +ENTRY(__aeabi_uidiv) + + subs r2, r1, #1 + moveq pc, lr + bcc Ldiv0 + cmp r0, r1 + bls 11f + tst r1, r2 + beq 12f + + ARM_DIV_BODY r0, r1, r2, r3 + + mov r0, r2 + mov pc, lr + +11: moveq r0, #1 + movne r0, #0 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + mov r0, r0, lsr r2 + mov pc, lr + +ENDPROC(__udivsi3) +ENDPROC(__aeabi_uidiv) + +ENTRY(__umodsi3) + + subs r2, r1, #1 @ compare divisor with 1 + bcc Ldiv0 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + movls pc, lr + + ARM_MOD_BODY r0, r1, r2, r3 + + mov pc, lr + +ENDPROC(__umodsi3) + +ENTRY(__divsi3) +ENTRY(__aeabi_idiv) + + cmp r1, #0 + eor ip, r0, r1 @ save the sign of the result. + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + subs r2, r1, #1 @ division by 1 or -1 ? + beq 10f + movs r3, r0 + rsbmi r3, r0, #0 @ positive dividend value + cmp r3, r1 + bls 11f + tst r1, r2 @ divisor is power of 2 ? + beq 12f + + ARM_DIV_BODY r3, r1, r0, r2 + + cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +10: teq ip, r0 @ same sign ? + rsbmi r0, r0, #0 + mov pc, lr + +11: movlo r0, #0 + moveq r0, ip, asr #31 + orreq r0, r0, #1 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + cmp ip, #0 + mov r0, r3, lsr r2 + rsbmi r0, r0, #0 + mov pc, lr + +ENDPROC(__divsi3) +ENDPROC(__aeabi_idiv) + +ENTRY(__modsi3) + + cmp r1, #0 + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + movs ip, r0 @ preserve sign of dividend + rsbmi r0, r0, #0 @ if negative make positive + subs r2, r1, #1 @ compare divisor with 1 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + bls 10f + + ARM_MOD_BODY r0, r1, r2, r3 + +10: cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +ENDPROC(__modsi3) + +#ifdef CONFIG_AEABI + +ENTRY(__aeabi_uidivmod) + + stmfd sp!, {r0, r1, ip, lr} + bl __aeabi_uidiv + ldmfd sp!, {r1, r2, ip, lr} + mul r3, r0, r2 + sub r1, r1, r3 + mov pc, lr + +ENDPROC(__aeabi_uidivmod) + +ENTRY(__aeabi_idivmod) + + stmfd sp!, {r0, r1, ip, lr} + bl __aeabi_idiv + ldmfd sp!, {r1, r2, ip, lr} + mul r3, r0, r2 + sub r1, r1, r3 + mov pc, lr + +ENDPROC(__aeabi_idivmod) + +#endif + +Ldiv0: + + str lr, [sp, #-8]! + bl __div0 + mov r0, #0 @ About as wrong as it could be. + ldr pc, [sp], #8 + .ltorg + .end diff --git a/lib/am18x-lib/lib/linkage.h b/lib/am18x-lib/lib/linkage.h new file mode 100644 index 000000000..5051cb802 --- /dev/null +++ b/lib/am18x-lib/lib/linkage.h @@ -0,0 +1,19 @@ +#ifndef __LINKAGE_H__ +#define __LINKAGE_H__ + +#define __LINUX_ARM_ARCH__ 5 +#define CONFIG_AEABI 1 +#define ENTRY(x) \ + .GLOBAL x; \ + .BALIGN 4; \ + x: +#define ENDPROC(x) \ + .type x, %function; \ + .size x, . - x; + +#define WARN_ON(x) +#define EXPORT_SYMBOL(x) +#define EXPORT_SYMBOL_GPL(x) +#define unlikely(x) (x) + +#endif //__LINKAGE_H__ diff --git a/lib/am18x-lib/lib/lshrdi3.S b/lib/am18x-lib/lib/lshrdi3.S new file mode 100644 index 000000000..399311b2c --- /dev/null +++ b/lib/am18x-lib/lib/lshrdi3.S @@ -0,0 +1,51 @@ +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 + Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + + +#include + +#ifdef __ARMEB__ +#define al r1 +#define ah r0 +#else +#define al r0 +#define ah r1 +#endif + +ENTRY(__lshrdi3) +ENTRY(__aeabi_llsr) + + subs r3, r2, #32 + rsb ip, r2, #32 + movmi al, al, lsr r2 + movpl al, ah, lsr r3 + orrmi al, al, ah, lsl ip + mov ah, ah, lsr r2 + mov pc, lr + +ENDPROC(__lshrdi3) +ENDPROC(__aeabi_llsr) diff --git a/lib/am18x-lib/lib/systick.c b/lib/am18x-lib/lib/systick.c new file mode 100644 index 000000000..918992b86 --- /dev/null +++ b/lib/am18x-lib/lib/systick.c @@ -0,0 +1,103 @@ +// tary, 17:10 2013/3/9 +#include "am18x_lib.h" +#include "auxlib.h" +#include "systick.h" + +#define TIMER_NR TIMER0 +#define TIMER_INTR_NR AINTC_T64P0_TINT12 + +static volatile systick_handler_t systick_handler = NULL; +static volatile unsigned long ticks = 0; +static unsigned inner_period = 1000U; +static void systick_isr(void); +static int dummy_handler(int ticks) { return 0;} + +int systick_init(unsigned period) { + am18x_rt r; + timer_conf_t tconf[1] = {{ + TIMER_MODE_32_BIT_UNCHANINED, + TIMER_RESULT_INTERRUPT, + TIMER_SOURCE_INTERNAL, + TIMER_OPER_CONTINUOUS, + 240000UL, + }}; + + tconf->period = timer_input_freq(TIMER_NR) * period / 1000; + inner_period = period; + + r = timer_conf(TIMER_NR, tconf); + if (AM18X_OK != r) { + printk("error timer_conf()\n"); + } + + systick_set_handler(NULL); + + isr_set_handler(TIMER_INTR_NR, systick_isr); + + aintc_sys_enable(TIMER_INTR_NR); + + return 0; +} + +int systick_start(void) { + timer_cmd(TIMER_NR, TIMER_CMD_START, 0); + return 0; +} + +int systick_stop(void) { + timer_cmd(TIMER_NR, TIMER_CMD_PAUSE, 0); + return 0; +} + +int systick_set_handler(systick_handler_t handle) { + systick_handler_t l_handle = systick_handler; + + if (handle == NULL) { + handle = dummy_handler; + } + systick_handler = handle; + return (int)l_handle; +} + +unsigned systick_elapsed(void) { + return ticks * inner_period; +} + +unsigned systick_period(void) { + return inner_period; +} + +int systick_timeout(int msecs) { + static volatile unsigned long l_ticks; + + if (msecs == 0) { + l_ticks = ticks; + return 0; + } + if (ticks * inner_period >= msecs + l_ticks * inner_period) { + l_ticks = ticks; + return 1; + } + return 0; +} + +int systick_sleep(int msecs) { + unsigned long goal; + + goal = msecs + ticks * inner_period; + while (goal > ticks * inner_period) { + ; + } + return 0; +} + +static void systick_isr(void) { + + if (systick_handler != NULL) { + systick_handler(ticks++); + } + + timer_cmd(TIMER_NR, TIMER_CMD_INTR_CLEAR, 0); + + return; +} diff --git a/lib/am18x-lib/lib/systick.h b/lib/am18x-lib/lib/systick.h new file mode 100644 index 000000000..028aa1e4a --- /dev/null +++ b/lib/am18x-lib/lib/systick.h @@ -0,0 +1,18 @@ +// tary, 23:39 2011/6/24 +#ifndef __SYSTICK_H__ +#define __SYSTICK_H__ + +typedef int (*systick_handler_t)(int); + +// period unit: milli seconds +int systick_init(unsigned period); +int systick_start(void); +int systick_stop(void); +int systick_set_handler(systick_handler_t handle); +int systick_timeout(int msecs); +int systick_sleep(int msecs); +// return unit: milli seconds +unsigned systick_period(void); +unsigned systick_elapsed(void); + +#endif //__SYSTICK_H__ diff --git a/lib/am18x-lib/lib/uart.c b/lib/am18x-lib/lib/uart.c new file mode 100644 index 000000000..5b4c22a35 --- /dev/null +++ b/lib/am18x-lib/lib/uart.c @@ -0,0 +1,79 @@ +// tary, 1:38 2012/12/23 +#include "am18x_lib.h" +#include "_uart.h" + +// AM1808 UART1 pins +#define UART1_TXD 4,28,2 +#define UART1_RXD 4,24,2 +#define UART_DEL 0x7F +#define UART_BACKSPACE 0x08 +#define UART_CR 0x0D +#define UART_LF 0x0A + +int uart_init(void) { + uart_conf_t conf; + + psc_state_transition(PSC_UART1, PSC_STATE_DISABLE); + psc_state_transition(PSC_UART1, PSC_STATE_ENABLE); + + syscfg_pinmux(UART1_TXD); + syscfg_pinmux(UART1_RXD); + + uart_init_conf(&conf); + uart_set_conf(UART1, &conf); + + return 0; +} + +int __putchar(int c) { + uart_write_byte(UART1, c); + while (AM18X_FALSE == uart_state(UART1, STATE_TX_EMPTY)); + return c; +} + +int putchar(int c) { + if (c == UART_LF) { + __putchar(UART_CR); + } + __putchar(c); + return c; +} + +int getchar(void) { + while (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)); + return uart_read_byte(UART1); +} + +int peekchar(void) { + if (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)) { + return -1; + } + return uart_read_byte(UART1); +} + +int uart_gets(char *line, int n) { + int cnt = 0; + char c; + + do { + if ((c = getchar()) == UART_CR) { + c = UART_LF; /* read character */ + } + + if (c != UART_BACKSPACE && c != UART_DEL) { /* process backspace */ + cnt++; + *line++ = c; + if (c != UART_LF) { /* echo and store character */ + putchar(c); + } + } else if (cnt != 0) { + cnt--; + line--; + putchar(UART_BACKSPACE); /* echo backspace */ + putchar(' '); + putchar(UART_BACKSPACE); + } + } while (cnt < n - 1 && c != UART_LF); /* check limit and line feed */ + *line = 0; /* mark end of string */ + return cnt; +} diff --git a/lib/am18x-lib/lib/vsprintf.c b/lib/am18x-lib/lib/vsprintf.c new file mode 100644 index 000000000..ece55bb18 --- /dev/null +++ b/lib/am18x-lib/lib/vsprintf.c @@ -0,0 +1,1786 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Fri Jul 13 2001 Crutcher Dunnavant + * - changed to provide snprintf and vsnprintf functions + * So Feb 1 16:51:32 CET 2004 Juergen Quade + * - scnprintf and vscnprintf + */ +#include +#include +#include +#include +#include "linkage.h" +#include "ctype.h" +#include "div64.h" + +#define EINVAL 1 +#define PAGE_SIZE 0x20 + +/* Works only for digits and letters, but small and fast */ +#define TOLOWER(x) ((x) | 0x20) + +static unsigned int simple_guess_base(const char *cp) +{ + if (cp[0] == '0') { + if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) + return 16; + else + return 8; + } else { + return 10; + } +} + +/** + * simple_strtoul - convert a string to an unsigned long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) +{ + unsigned long result = 0; + + if (!base) + base = simple_guess_base(cp); + + if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') + cp += 2; + + while (isxdigit(*cp)) { + unsigned int value; + + value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; + if (value >= base) + break; + result = result * base + value; + cp++; + } + + if (endp) + *endp = (char *)cp; + return result; +} +EXPORT_SYMBOL(simple_strtoul); + +/** + * simple_strtol - convert a string to a signed long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +long simple_strtol(const char *cp, char **endp, unsigned int base) +{ + if(*cp == '-') + return -simple_strtoul(cp + 1, endp, base); + return simple_strtoul(cp, endp, base); +} +EXPORT_SYMBOL(simple_strtol); + +/** + * simple_strtoull - convert a string to an unsigned long long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) +{ + unsigned long long result = 0; + + if (!base) + base = simple_guess_base(cp); + + if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') + cp += 2; + + while (isxdigit(*cp)) { + unsigned int value; + + value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; + if (value >= base) + break; + result = result * base + value; + cp++; + } + + if (endp) + *endp = (char *)cp; + return result; +} +EXPORT_SYMBOL(simple_strtoull); + +/** + * simple_strtoll - convert a string to a signed long long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +long long simple_strtoll(const char *cp, char **endp, unsigned int base) +{ + if(*cp=='-') + return -simple_strtoull(cp + 1, endp, base); + return simple_strtoull(cp, endp, base); +} + +/** + * strict_strtoul - convert a string to an unsigned long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtoul converts a string to an unsigned long only if the + * string is really an unsigned long string, any string containing + * any invalid char at the tail will be rejected and -EINVAL is returned, + * only a newline char at the tail is acceptible because people generally + * change a module parameter in the following way: + * + * echo 1024 > /sys/module/e1000/parameters/copybreak + * + * echo will append a newline to the tail. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + * + * simple_strtoul just ignores the successive invalid characters and + * return the converted value of prefix part of the string. + */ +int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) +{ + char *tail; + unsigned long val; + size_t len; + + *res = 0; + len = strlen(cp); + if (len == 0) + return -EINVAL; + + val = simple_strtoul(cp, &tail, base); + if (tail == cp) + return -EINVAL; + if ((*tail == '\0') || + ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { + *res = val; + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL(strict_strtoul); + +/** + * strict_strtol - convert a string to a long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtol is similiar to strict_strtoul, but it allows the first + * character of a string is '-'. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + */ +int strict_strtol(const char *cp, unsigned int base, long *res) +{ + int ret; + if (*cp == '-') { + ret = strict_strtoul(cp + 1, base, (unsigned long *)res); + if (!ret) + *res = -(*res); + } else { + ret = strict_strtoul(cp, base, (unsigned long *)res); + } + + return ret; +} +EXPORT_SYMBOL(strict_strtol); + +/** + * strict_strtoull - convert a string to an unsigned long long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtoull converts a string to an unsigned long long only if the + * string is really an unsigned long long string, any string containing + * any invalid char at the tail will be rejected and -EINVAL is returned, + * only a newline char at the tail is acceptible because people generally + * change a module parameter in the following way: + * + * echo 1024 > /sys/module/e1000/parameters/copybreak + * + * echo will append a newline to the tail of the string. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + * + * simple_strtoull just ignores the successive invalid characters and + * return the converted value of prefix part of the string. + */ +int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res) +{ + char *tail; + unsigned long long val; + size_t len; + + *res = 0; + len = strlen(cp); + if (len == 0) + return -EINVAL; + + val = simple_strtoull(cp, &tail, base); + if (tail == cp) + return -EINVAL; + if ((*tail == '\0') || + ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { + *res = val; + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL(strict_strtoull); + +/** + * strict_strtoll - convert a string to a long long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtoll is similiar to strict_strtoull, but it allows the first + * character of a string is '-'. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + */ +int strict_strtoll(const char *cp, unsigned int base, long long *res) +{ + int ret; + if (*cp == '-') { + ret = strict_strtoull(cp + 1, base, (unsigned long long *)res); + if (!ret) + *res = -(*res); + } else { + ret = strict_strtoull(cp, base, (unsigned long long *)res); + } + + return ret; +} +EXPORT_SYMBOL(strict_strtoll); + +static int skip_atoi(const char **s) +{ + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +/* Decimal conversion is by far the most typical, and is used + * for /proc and /sys data. This directly impacts e.g. top performance + * with many processes running. We optimize it for speed + * using code from + * http://www.cs.uiowa.edu/~jones/bcd/decimal.html + * (with permission from the author, Douglas W. Jones). */ + +/* Formats correctly any integer in [0,99999]. + * Outputs from one to five digits depending on input. + * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ +static char* put_dec_trunc(char *buf, unsigned q) +{ + unsigned d3, d2, d1, d0; + d1 = (q>>4) & 0xf; + d2 = (q>>8) & 0xf; + d3 = (q>>12); + + d0 = 6*(d3 + d2 + d1) + (q & 0xf); + q = (d0 * 0xcd) >> 11; + d0 = d0 - 10*q; + *buf++ = d0 + '0'; /* least significant digit */ + d1 = q + 9*d3 + 5*d2 + d1; + if (d1 != 0) { + q = (d1 * 0xcd) >> 11; + d1 = d1 - 10*q; + *buf++ = d1 + '0'; /* next digit */ + + d2 = q + 2*d2; + if ((d2 != 0) || (d3 != 0)) { + q = (d2 * 0xd) >> 7; + d2 = d2 - 10*q; + *buf++ = d2 + '0'; /* next digit */ + + d3 = q + 4*d3; + if (d3 != 0) { + q = (d3 * 0xcd) >> 11; + d3 = d3 - 10*q; + *buf++ = d3 + '0'; /* next digit */ + if (q != 0) + *buf++ = q + '0'; /* most sign. digit */ + } + } + } + return buf; +} +/* Same with if's removed. Always emits five digits */ +static char* put_dec_full(char *buf, unsigned q) +{ + /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ + /* but anyway, gcc produces better code with full-sized ints */ + unsigned d3, d2, d1, d0; + d1 = (q>>4) & 0xf; + d2 = (q>>8) & 0xf; + d3 = (q>>12); + + /* Possible ways to approx. divide by 10 */ + /* gcc -O2 replaces multiply with shifts and adds */ + // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) + // (x * 0x67) >> 10: 1100111 + // (x * 0x34) >> 9: 110100 - same + // (x * 0x1a) >> 8: 11010 - same + // (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) + + d0 = 6*(d3 + d2 + d1) + (q & 0xf); + q = (d0 * 0xcd) >> 11; + d0 = d0 - 10*q; + *buf++ = d0 + '0'; + d1 = q + 9*d3 + 5*d2 + d1; + q = (d1 * 0xcd) >> 11; + d1 = d1 - 10*q; + *buf++ = d1 + '0'; + + d2 = q + 2*d2; + q = (d2 * 0xd) >> 7; + d2 = d2 - 10*q; + *buf++ = d2 + '0'; + + d3 = q + 4*d3; + q = (d3 * 0xcd) >> 11; /* - shorter code */ + /* q = (d3 * 0x67) >> 10; - would also work */ + d3 = d3 - 10*q; + *buf++ = d3 + '0'; + *buf++ = q + '0'; + return buf; +} + +/* No inlining helps gcc to use registers better */ +static char* put_dec(char *buf, unsigned long long num) +{ + while (1) { + unsigned rem; + if (num < 100000) + return put_dec_trunc(buf, num); + rem = do_div(num, 100000); + buf = put_dec_full(buf, rem); + } +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SMALL 32 /* Must be 32 == 0x20 */ +#define SPECIAL 64 /* 0x */ + +enum format_type { + FORMAT_TYPE_NONE, /* Just a string part */ + FORMAT_TYPE_WIDTH, + FORMAT_TYPE_PRECISION, + FORMAT_TYPE_CHAR, + FORMAT_TYPE_STR, + FORMAT_TYPE_PTR, + FORMAT_TYPE_PERCENT_CHAR, + FORMAT_TYPE_INVALID, + FORMAT_TYPE_LONG_LONG, + FORMAT_TYPE_ULONG, + FORMAT_TYPE_LONG, + FORMAT_TYPE_UBYTE, + FORMAT_TYPE_BYTE, + FORMAT_TYPE_USHORT, + FORMAT_TYPE_SHORT, + FORMAT_TYPE_UINT, + FORMAT_TYPE_INT, + FORMAT_TYPE_NRCHARS, + FORMAT_TYPE_SIZE_T, + FORMAT_TYPE_PTRDIFF +}; + +struct printf_spec { + enum format_type type; + int flags; /* flags to number() */ + int field_width; /* width of output field */ + int base; + int precision; /* # of digits/chars */ + int qualifier; +}; + +static char *number(char *buf, char *end, unsigned long long num, + struct printf_spec spec) +{ + /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ + static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ + + char tmp[66]; + char sign; + char locase; + int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); + int i; + + /* locase = 0 or 0x20. ORing digits or letters with 'locase' + * produces same digits or (maybe lowercased) letters */ + locase = (spec.flags & SMALL); + if (spec.flags & LEFT) + spec.flags &= ~ZEROPAD; + sign = 0; + if (spec.flags & SIGN) { + if ((signed long long) num < 0) { + sign = '-'; + num = - (signed long long) num; + spec.field_width--; + } else if (spec.flags & PLUS) { + sign = '+'; + spec.field_width--; + } else if (spec.flags & SPACE) { + sign = ' '; + spec.field_width--; + } + } + if (need_pfx) { + spec.field_width--; + if (spec.base == 16) + spec.field_width--; + } + + /* generate full string in tmp[], in reverse order */ + i = 0; + if (num == 0) + tmp[i++] = '0'; + /* Generic code, for any base: + else do { + tmp[i++] = (digits[do_div(num,base)] | locase); + } while (num != 0); + */ + else if (spec.base != 10) { /* 8 or 16 */ + int mask = spec.base - 1; + int shift = 3; + if (spec.base == 16) shift = 4; + do { + tmp[i++] = (digits[((unsigned char)num) & mask] | locase); + num >>= shift; + } while (num); + } else { /* base 10 */ + i = put_dec(tmp, num) - tmp; + } + + /* printing 100 using %2d gives "100", not "00" */ + if (i > spec.precision) + spec.precision = i; + /* leading space padding */ + spec.field_width -= spec.precision; + if (!(spec.flags & (ZEROPAD+LEFT))) { + while(--spec.field_width >= 0) { + if (buf < end) + *buf = ' '; + ++buf; + } + } + /* sign */ + if (sign) { + if (buf < end) + *buf = sign; + ++buf; + } + /* "0x" / "0" prefix */ + if (need_pfx) { + if (buf < end) + *buf = '0'; + ++buf; + if (spec.base == 16) { + if (buf < end) + *buf = ('X' | locase); + ++buf; + } + } + /* zero or space padding */ + if (!(spec.flags & LEFT)) { + char c = (spec.flags & ZEROPAD) ? '0' : ' '; + while (--spec.field_width >= 0) { + if (buf < end) + *buf = c; + ++buf; + } + } + /* hmm even more zero padding? */ + while (i <= --spec.precision) { + if (buf < end) + *buf = '0'; + ++buf; + } + /* actual digits of result */ + while (--i >= 0) { + if (buf < end) + *buf = tmp[i]; + ++buf; + } + /* trailing space padding */ + while (--spec.field_width >= 0) { + if (buf < end) + *buf = ' '; + ++buf; + } + return buf; +} + +static char *string(char *buf, char *end, char *s, struct printf_spec spec) +{ + int len, i; + + if ((unsigned long)s < PAGE_SIZE) + s = ""; + + len = strnlen(s, spec.precision); + + if (!(spec.flags & LEFT)) { + while (len < spec.field_width--) { + if (buf < end) + *buf = ' '; + ++buf; + } + } + for (i = 0; i < len; ++i) { + if (buf < end) + *buf = *s; + ++buf; ++s; + } + while (len < spec.field_width--) { + if (buf < end) + *buf = ' '; + ++buf; + } + return buf; +} + +static char *symbol_string(char *buf, char *end, void *ptr, + struct printf_spec spec, char ext) +{ + unsigned long value = (unsigned long) ptr; +#ifdef CONFIG_KALLSYMS + char sym[KSYM_SYMBOL_LEN]; + if (ext != 'f') + sprint_symbol(sym, value); + else + kallsyms_lookup(value, NULL, NULL, NULL, sym); + return string(buf, end, sym, spec); +#else + spec.field_width = 2*sizeof(void *); + spec.flags |= SPECIAL | SMALL | ZEROPAD; + spec.base = 16; + return number(buf, end, value, spec); +#endif +} + + + +static char *ip4_addr_string(char *buf, char *end, uint8_t *addr, + struct printf_spec spec) +{ + char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */ + char temp[3]; /* hold each IP quad in reverse order */ + char *p = ip4_addr; + int i, digits; + + for (i = 0; i < 4; i++) { + digits = put_dec_trunc(temp, addr[i]) - temp; + /* reverse the digits in the quad */ + while (digits--) + *p++ = temp[digits]; + if (i != 3) + *p++ = '.'; + } + *p = '\0'; + spec.flags &= ~SPECIAL; + + return string(buf, end, ip4_addr, spec); +} + +/* + * Show a '%p' thing. A kernel extension is that the '%p' is followed + * by an extra set of alphanumeric characters that are extended format + * specifiers. + * + * Right now we handle: + * + * - 'F' For symbolic function descriptor pointers with offset + * - 'f' For simple symbolic function names without offset + * - 'S' For symbolic direct pointers + * - 'R' For a struct resource pointer, it prints the range of + * addresses (not the name nor the flags) + * - 'M' For a 6-byte MAC address, it prints the address in the + * usual colon-separated hex notation + * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated + * decimal for v4 and colon separated network-order 16 bit hex for v6) + * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is + * currently the same + * + * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 + * function pointers are really function descriptors, which contain a + * pointer to the real address. + */ +static char *pointer(const char *fmt, char *buf, char *end, void *ptr, + struct printf_spec spec) +{ + if (!ptr) + return string(buf, end, "(null)", spec); + + switch (*fmt) { + case 'S': + return symbol_string(buf, end, ptr, spec, *fmt); + case 'm': + spec.flags |= SPECIAL; + /* Fallthrough */ + case 'i': + spec.flags |= SPECIAL; + /* Fallthrough */ + case 'I': + if (fmt[1] == '4') + return ip4_addr_string(buf, end, ptr, spec); + spec.flags &= ~SPECIAL; + break; + } + spec.flags |= SMALL; + if (spec.field_width == -1) { + spec.field_width = 2*sizeof(void *); + spec.flags |= ZEROPAD; + } + spec.base = 16; + + return number(buf, end, (unsigned long) ptr, spec); +} + +/* + * Helper function to decode printf style format. + * Each call decode a token from the format and return the + * number of characters read (or likely the delta where it wants + * to go on the next call). + * The decoded token is returned through the parameters + * + * 'h', 'l', or 'L' for integer fields + * 'z' support added 23/7/1999 S.H. + * 'z' changed to 'Z' --davidm 1/25/99 + * 't' added for ptrdiff_t + * + * @fmt: the format string + * @type of the token returned + * @flags: various flags such as +, -, # tokens.. + * @field_width: overwritten width + * @base: base of the number (octal, hex, ...) + * @precision: precision of a number + * @qualifier: qualifier of a number (long, size_t, ...) + */ +static int format_decode(const char *fmt, struct printf_spec *spec) +{ + const char *start = fmt; + + /* we finished early by reading the field width */ + if (spec->type == FORMAT_TYPE_WIDTH) { + if (spec->field_width < 0) { + spec->field_width = -spec->field_width; + spec->flags |= LEFT; + } + spec->type = FORMAT_TYPE_NONE; + goto precision; + } + + /* we finished early by reading the precision */ + if (spec->type == FORMAT_TYPE_PRECISION) { + if (spec->precision < 0) + spec->precision = 0; + + spec->type = FORMAT_TYPE_NONE; + goto qualifier; + } + + /* By default */ + spec->type = FORMAT_TYPE_NONE; + + for (; *fmt ; ++fmt) { + if (*fmt == '%') + break; + } + + /* Return the current non-format string */ + if (fmt != start || !*fmt) + return fmt - start; + + /* Process flags */ + spec->flags = 0; + + while (1) { /* this also skips first '%' */ + int found = 1; + + ++fmt; + + switch (*fmt) { + case '-': spec->flags |= LEFT; break; + case '+': spec->flags |= PLUS; break; + case ' ': spec->flags |= SPACE; break; + case '#': spec->flags |= SPECIAL; break; + case '0': spec->flags |= ZEROPAD; break; + default: found = 0; + } + + if (!found) + break; + } + + /* get field width */ + spec->field_width = -1; + + if (isdigit(*fmt)) + spec->field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + spec->type = FORMAT_TYPE_WIDTH; + return ++fmt - start; + } + +precision: + /* get the precision */ + spec->precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) { + spec->precision = skip_atoi(&fmt); + if (spec->precision < 0) + spec->precision = 0; + } else if (*fmt == '*') { + /* it's the next argument */ + spec->type = FORMAT_TYPE_PRECISION; + return ++fmt - start; + } + } + +qualifier: + /* get the conversion qualifier */ + spec->qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { + spec->qualifier = *fmt++; + if (unlikely(spec->qualifier == *fmt)) { + if (spec->qualifier == 'l') { + spec->qualifier = 'L'; + ++fmt; + } else if (spec->qualifier == 'h') { + spec->qualifier = 'H'; + ++fmt; + } + } + } + + /* default base */ + spec->base = 10; + switch (*fmt) { + case 'c': + spec->type = FORMAT_TYPE_CHAR; + return ++fmt - start; + + case 's': + spec->type = FORMAT_TYPE_STR; + return ++fmt - start; + + case 'p': + spec->type = FORMAT_TYPE_PTR; + return fmt - start; + /* skip alnum */ + + case 'n': + spec->type = FORMAT_TYPE_NRCHARS; + return ++fmt - start; + + case '%': + spec->type = FORMAT_TYPE_PERCENT_CHAR; + return ++fmt - start; + + /* integer number formats - set up the flags and "break" */ + case 'o': + spec->base = 8; + break; + + case 'x': + spec->flags |= SMALL; + + case 'X': + spec->base = 16; + break; + + case 'd': + case 'i': + spec->flags |= SIGN; + case 'u': + break; + + default: + spec->type = FORMAT_TYPE_INVALID; + return fmt - start; + } + + if (spec->qualifier == 'L') + spec->type = FORMAT_TYPE_LONG_LONG; + else if (spec->qualifier == 'l') { + if (spec->flags & SIGN) + spec->type = FORMAT_TYPE_LONG; + else + spec->type = FORMAT_TYPE_ULONG; + } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') { + spec->type = FORMAT_TYPE_SIZE_T; + } else if (spec->qualifier == 't') { + spec->type = FORMAT_TYPE_PTRDIFF; + } else if (spec->qualifier == 'H') { + if (spec->flags & SIGN) + spec->type = FORMAT_TYPE_BYTE; + else + spec->type = FORMAT_TYPE_UBYTE; + } else if (spec->qualifier == 'h') { + if (spec->flags & SIGN) + spec->type = FORMAT_TYPE_SHORT; + else + spec->type = FORMAT_TYPE_USHORT; + } else { + if (spec->flags & SIGN) + spec->type = FORMAT_TYPE_INT; + else + spec->type = FORMAT_TYPE_UINT; + } + + return ++fmt - start; +} + +/** + * vsnprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @args: Arguments for the format string + * + * This function follows C99 vsnprintf, but has some extensions: + * %pS output the name of a text symbol + * %pF output the name of a function pointer with its offset + * %pf output the name of a function pointer without its offset + * %pR output the address range in a struct resource + * + * The return value is the number of characters which would + * be generated for the given input, excluding the trailing + * '\0', as per ISO C99. If you want to have the exact + * number of characters written into @buf as return value + * (not including the trailing '\0'), use vscnprintf(). If the + * return is greater than or equal to @size, the resulting + * string is truncated. + * + * Call this function if you are already dealing with a va_list. + * You probably want snprintf() instead. + */ +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + unsigned long long num; + char *str, *end, c; + int read; + struct printf_spec spec = {0}; + + /* Reject out-of-range values early. Large positive sizes are + used for unknown buffer sizes. */ + if (unlikely((int) size < 0)) { + /* There can be only one.. */ + static char warn = 1; + WARN_ON(warn); + warn = 0; + return 0; + } + + str = buf; + end = buf + size; + + /* Make sure end is always >= buf */ + if (end < buf) { + end = ((void *)-1); + size = end - buf; + } + + while (*fmt) { + const char *old_fmt = fmt; + + read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case FORMAT_TYPE_NONE: { + int copy = read; + if (str < end) { + if (copy > end - str) + copy = end - str; + memcpy(str, old_fmt, copy); + } + str += read; + break; + } + + case FORMAT_TYPE_WIDTH: + spec.field_width = va_arg(args, int); + break; + + case FORMAT_TYPE_PRECISION: + spec.precision = va_arg(args, int); + break; + + case FORMAT_TYPE_CHAR: + if (!(spec.flags & LEFT)) { + while (--spec.field_width > 0) { + if (str < end) + *str = ' '; + ++str; + + } + } + c = (unsigned char) va_arg(args, int); + if (str < end) + *str = c; + ++str; + while (--spec.field_width > 0) { + if (str < end) + *str = ' '; + ++str; + } + break; + + case FORMAT_TYPE_STR: + str = string(str, end, va_arg(args, char *), spec); + break; + + case FORMAT_TYPE_PTR: + str = pointer(fmt+1, str, end, va_arg(args, void *), + spec); + while (isalnum(*fmt)) + fmt++; + break; + + case FORMAT_TYPE_PERCENT_CHAR: + if (str < end) + *str = '%'; + ++str; + break; + + case FORMAT_TYPE_INVALID: + if (str < end) + *str = '%'; + ++str; + break; + + case FORMAT_TYPE_NRCHARS: { + int qualifier = spec.qualifier; + + if (qualifier == 'l') { + long *ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z' || + qualifier == 'z') { + size_t *ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int *ip = va_arg(args, int *); + *ip = (str - buf); + } + break; + } + + default: + switch (spec.type) { + case FORMAT_TYPE_LONG_LONG: + num = va_arg(args, long long); + break; + case FORMAT_TYPE_ULONG: + num = va_arg(args, unsigned long); + break; + case FORMAT_TYPE_LONG: + num = va_arg(args, long); + break; + case FORMAT_TYPE_SIZE_T: + num = va_arg(args, size_t); + break; + case FORMAT_TYPE_PTRDIFF: + num = va_arg(args, unsigned long); + break; + case FORMAT_TYPE_UBYTE: + num = (unsigned char) va_arg(args, int); + break; + case FORMAT_TYPE_BYTE: + num = (signed char) va_arg(args, int); + break; + case FORMAT_TYPE_USHORT: + num = (unsigned short) va_arg(args, int); + break; + case FORMAT_TYPE_SHORT: + num = (short) va_arg(args, int); + break; + case FORMAT_TYPE_INT: + num = (int) va_arg(args, int); + break; + default: + num = va_arg(args, unsigned int); + } + + str = number(str, end, num, spec); + } + } + + if (size > 0) { + if (str < end) + *str = '\0'; + else + end[-1] = '\0'; + } + + /* the trailing null byte doesn't count towards the total */ + return str-buf; + +} +EXPORT_SYMBOL(vsnprintf); + +/** + * vscnprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @args: Arguments for the format string + * + * The return value is the number of characters which have been written into + * the @buf not including the trailing '\0'. If @size is <= 0 the function + * returns 0. + * + * Call this function if you are already dealing with a va_list. + * You probably want scnprintf() instead. + * + * See the vsnprintf() documentation for format string extensions over C99. + */ +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + int i; + + i=vsnprintf(buf,size,fmt,args); + return (i >= size) ? (size - 1) : i; +} +EXPORT_SYMBOL(vscnprintf); + +/** + * snprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @...: Arguments for the format string + * + * The return value is the number of characters which would be + * generated for the given input, excluding the trailing null, + * as per ISO C99. If the return is greater than or equal to + * @size, the resulting string is truncated. + * + * See the vsnprintf() documentation for format string extensions over C99. + */ +int snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsnprintf(buf,size,fmt,args); + va_end(args); + return i; +} +EXPORT_SYMBOL(snprintf); + +/** + * scnprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @...: Arguments for the format string + * + * The return value is the number of characters written into @buf not including + * the trailing '\0'. If @size is <= 0 the function returns 0. + */ + +int scnprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vsnprintf(buf, size, fmt, args); + va_end(args); + return (i >= size) ? (size - 1) : i; +} +EXPORT_SYMBOL(scnprintf); + +/** + * vsprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @fmt: The format string to use + * @args: Arguments for the format string + * + * The function returns the number of characters written + * into @buf. Use vsnprintf() or vscnprintf() in order to avoid + * buffer overflows. + * + * Call this function if you are already dealing with a va_list. + * You probably want sprintf() instead. + * + * See the vsnprintf() documentation for format string extensions over C99. + */ +int vsprintf(char *buf, const char *fmt, va_list args) +{ + return vsnprintf(buf, INT_MAX, fmt, args); +} +EXPORT_SYMBOL(vsprintf); + +/** + * sprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @fmt: The format string to use + * @...: Arguments for the format string + * + * The function returns the number of characters written + * into @buf. Use snprintf() or scnprintf() in order to avoid + * buffer overflows. + * + * See the vsnprintf() documentation for format string extensions over C99. + */ +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsnprintf(buf, INT_MAX, fmt, args); + va_end(args); + return i; +} +EXPORT_SYMBOL(sprintf); + +#ifdef CONFIG_BINARY_PRINTF +/* + * bprintf service: + * vbin_printf() - VA arguments to binary data + * bstr_printf() - Binary data to text string + */ + +/** + * vbin_printf - Parse a format string and place args' binary value in a buffer + * @bin_buf: The buffer to place args' binary value + * @size: The size of the buffer(by words(32bits), not characters) + * @fmt: The format string to use + * @args: Arguments for the format string + * + * The format follows C99 vsnprintf, except %n is ignored, and its argument + * is skiped. + * + * The return value is the number of words(32bits) which would be generated for + * the given input. + * + * NOTE: + * If the return value is greater than @size, the resulting bin_buf is NOT + * valid for bstr_printf(). + */ +int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) +{ + struct printf_spec spec = {0}; + char *str, *end; + int read; + + str = (char *)bin_buf; + end = (char *)(bin_buf + size); + +#define save_arg(type) \ +do { \ + if (sizeof(type) == 8) { \ + unsigned long long value; \ + str = PTR_ALIGN(str, sizeof(u32)); \ + value = va_arg(args, unsigned long long); \ + if (str + sizeof(type) <= end) { \ + *(u32 *)str = *(u32 *)&value; \ + *(u32 *)(str + 4) = *((u32 *)&value + 1); \ + } \ + } else { \ + unsigned long value; \ + str = PTR_ALIGN(str, sizeof(type)); \ + value = va_arg(args, int); \ + if (str + sizeof(type) <= end) \ + *(typeof(type) *)str = (type)value; \ + } \ + str += sizeof(type); \ +} while (0) + + + while (*fmt) { + read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case FORMAT_TYPE_NONE: + break; + + case FORMAT_TYPE_WIDTH: + case FORMAT_TYPE_PRECISION: + save_arg(int); + break; + + case FORMAT_TYPE_CHAR: + save_arg(char); + break; + + case FORMAT_TYPE_STR: { + const char *save_str = va_arg(args, char *); + size_t len; + if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE + || (unsigned long)save_str < PAGE_SIZE) + save_str = ""; + len = strlen(save_str); + if (str + len + 1 < end) + memcpy(str, save_str, len + 1); + str += len + 1; + break; + } + + case FORMAT_TYPE_PTR: + save_arg(void *); + /* skip all alphanumeric pointer suffixes */ + while (isalnum(*fmt)) + fmt++; + break; + + case FORMAT_TYPE_PERCENT_CHAR: + break; + + case FORMAT_TYPE_INVALID: + break; + + case FORMAT_TYPE_NRCHARS: { + /* skip %n 's argument */ + int qualifier = spec.qualifier; + void *skip_arg; + if (qualifier == 'l') + skip_arg = va_arg(args, long *); + else if (qualifier == 'Z' || qualifier == 'z') + skip_arg = va_arg(args, size_t *); + else + skip_arg = va_arg(args, int *); + break; + } + + default: + switch (spec.type) { + + case FORMAT_TYPE_LONG_LONG: + save_arg(long long); + break; + case FORMAT_TYPE_ULONG: + case FORMAT_TYPE_LONG: + save_arg(unsigned long); + break; + case FORMAT_TYPE_SIZE_T: + save_arg(size_t); + break; + case FORMAT_TYPE_PTRDIFF: + save_arg(ptrdiff_t); + break; + case FORMAT_TYPE_UBYTE: + case FORMAT_TYPE_BYTE: + save_arg(char); + break; + case FORMAT_TYPE_USHORT: + case FORMAT_TYPE_SHORT: + save_arg(short); + break; + default: + save_arg(int); + } + } + } + return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; + +#undef save_arg +} +EXPORT_SYMBOL_GPL(vbin_printf); + +/** + * bstr_printf - Format a string from binary arguments and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @bin_buf: Binary arguments for the format string + * + * This function like C99 vsnprintf, but the difference is that vsnprintf gets + * arguments from stack, and bstr_printf gets arguments from @bin_buf which is + * a binary buffer that generated by vbin_printf. + * + * The format follows C99 vsnprintf, but has some extensions: + * %pS output the name of a text symbol + * %pF output the name of a function pointer with its offset + * %pf output the name of a function pointer without its offset + * %pR output the address range in a struct resource + * %n is ignored + * + * The return value is the number of characters which would + * be generated for the given input, excluding the trailing + * '\0', as per ISO C99. If you want to have the exact + * number of characters written into @buf as return value + * (not including the trailing '\0'), use vscnprintf(). If the + * return is greater than or equal to @size, the resulting + * string is truncated. + */ +int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) +{ + unsigned long long num; + char *str, *end, c; + const char *args = (const char *)bin_buf; + + struct printf_spec spec = {0}; + + if (unlikely((int) size < 0)) { + /* There can be only one.. */ + static char warn = 1; + WARN_ON(warn); + warn = 0; + return 0; + } + + str = buf; + end = buf + size; + +#define get_arg(type) \ +({ \ + typeof(type) value; \ + if (sizeof(type) == 8) { \ + args = PTR_ALIGN(args, sizeof(u32)); \ + *(u32 *)&value = *(u32 *)args; \ + *((u32 *)&value + 1) = *(u32 *)(args + 4); \ + } else { \ + args = PTR_ALIGN(args, sizeof(type)); \ + value = *(typeof(type) *)args; \ + } \ + args += sizeof(type); \ + value; \ +}) + + /* Make sure end is always >= buf */ + if (end < buf) { + end = ((void *)-1); + size = end - buf; + } + + while (*fmt) { + int read; + const char *old_fmt = fmt; + + read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case FORMAT_TYPE_NONE: { + int copy = read; + if (str < end) { + if (copy > end - str) + copy = end - str; + memcpy(str, old_fmt, copy); + } + str += read; + break; + } + + case FORMAT_TYPE_WIDTH: + spec.field_width = get_arg(int); + break; + + case FORMAT_TYPE_PRECISION: + spec.precision = get_arg(int); + break; + + case FORMAT_TYPE_CHAR: + if (!(spec.flags & LEFT)) { + while (--spec.field_width > 0) { + if (str < end) + *str = ' '; + ++str; + } + } + c = (unsigned char) get_arg(char); + if (str < end) + *str = c; + ++str; + while (--spec.field_width > 0) { + if (str < end) + *str = ' '; + ++str; + } + break; + + case FORMAT_TYPE_STR: { + const char *str_arg = args; + size_t len = strlen(str_arg); + args += len + 1; + str = string(str, end, (char *)str_arg, spec); + break; + } + + case FORMAT_TYPE_PTR: + str = pointer(fmt+1, str, end, get_arg(void *), spec); + while (isalnum(*fmt)) + fmt++; + break; + + case FORMAT_TYPE_PERCENT_CHAR: + if (str < end) + *str = '%'; + ++str; + break; + + case FORMAT_TYPE_INVALID: + if (str < end) + *str = '%'; + ++str; + break; + + case FORMAT_TYPE_NRCHARS: + /* skip */ + break; + + default: + switch (spec.type) { + + case FORMAT_TYPE_LONG_LONG: + num = get_arg(long long); + break; + case FORMAT_TYPE_ULONG: + num = get_arg(unsigned long); + break; + case FORMAT_TYPE_LONG: + num = get_arg(unsigned long); + break; + case FORMAT_TYPE_SIZE_T: + num = get_arg(size_t); + break; + case FORMAT_TYPE_PTRDIFF: + num = get_arg(ptrdiff_t); + break; + case FORMAT_TYPE_UBYTE: + num = get_arg(unsigned char); + break; + case FORMAT_TYPE_BYTE: + num = get_arg(signed char); + break; + case FORMAT_TYPE_USHORT: + num = get_arg(unsigned short); + break; + case FORMAT_TYPE_SHORT: + num = get_arg(short); + break; + case FORMAT_TYPE_UINT: + num = get_arg(unsigned int); + break; + default: + num = get_arg(int); + } + + str = number(str, end, num, spec); + } + } + + if (size > 0) { + if (str < end) + *str = '\0'; + else + end[-1] = '\0'; + } + +#undef get_arg + + /* the trailing null byte doesn't count towards the total */ + return str - buf; +} +EXPORT_SYMBOL_GPL(bstr_printf); + +/** + * bprintf - Parse a format string and place args' binary value in a buffer + * @bin_buf: The buffer to place args' binary value + * @size: The size of the buffer(by words(32bits), not characters) + * @fmt: The format string to use + * @...: Arguments for the format string + * + * The function returns the number of words(u32) written + * into @bin_buf. + */ +int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vbin_printf(bin_buf, size, fmt, args); + va_end(args); + return ret; +} +EXPORT_SYMBOL_GPL(bprintf); + +#endif /* CONFIG_BINARY_PRINTF */ + +/** + * vsscanf - Unformat a buffer into a list of arguments + * @buf: input buffer + * @fmt: format of buffer + * @args: arguments + */ +int vsscanf(const char * buf, const char * fmt, va_list args) +{ + const char *str = buf; + char *next; + char digit; + int num = 0; + int qualifier; + int base; + int field_width; + int is_sign = 0; + + while(*fmt && *str) { + /* skip any white space in format */ + /* white space in format matchs any amount of + * white space, including none, in the input. + */ + if (isspace(*fmt)) { + while (isspace(*fmt)) + ++fmt; + while (isspace(*str)) + ++str; + } + + /* anything that is not a conversion must match exactly */ + if (*fmt != '%' && *fmt) { + if (*fmt++ != *str++) + break; + continue; + } + + if (!*fmt) + break; + ++fmt; + + /* skip this conversion. + * advance both strings to next white space + */ + if (*fmt == '*') { + while (!isspace(*fmt) && *fmt) + fmt++; + while (!isspace(*str) && *str) + str++; + continue; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + + /* get conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || + *fmt == 'Z' || *fmt == 'z') { + qualifier = *fmt++; + if (unlikely(qualifier == *fmt)) { + if (qualifier == 'h') { + qualifier = 'H'; + fmt++; + } else if (qualifier == 'l') { + qualifier = 'L'; + fmt++; + } + } + } + base = 10; + is_sign = 0; + + if (!*fmt || !*str) + break; + + switch(*fmt++) { + case 'c': + { + char *s = (char *) va_arg(args,char*); + if (field_width == -1) + field_width = 1; + do { + *s++ = *str++; + } while (--field_width > 0 && *str); + num++; + } + continue; + case 's': + { + char *s = (char *) va_arg(args, char *); + if(field_width == -1) + field_width = INT_MAX; + /* first, skip leading white space in buffer */ + while (isspace(*str)) + str++; + + /* now copy until next white space */ + while (*str && !isspace(*str) && field_width--) { + *s++ = *str++; + } + *s = '\0'; + num++; + } + continue; + case 'n': + /* return number of characters read so far */ + { + int *i = (int *)va_arg(args,int*); + *i = str - buf; + } + continue; + case 'o': + base = 8; + break; + case 'x': + case 'X': + base = 16; + break; + case 'i': + base = 0; + case 'd': + is_sign = 1; + case 'u': + break; + case '%': + /* looking for '%' in str */ + if (*str++ != '%') + return num; + continue; + default: + /* invalid format; stop here */ + return num; + } + + /* have some sort of integer conversion. + * first, skip white space in buffer. + */ + while (isspace(*str)) + str++; + + digit = *str; + if (is_sign && digit == '-') + digit = *(str + 1); + + if (!digit + || (base == 16 && !isxdigit(digit)) + || (base == 10 && !isdigit(digit)) + || (base == 8 && (!isdigit(digit) || digit > '7')) + || (base == 0 && !isdigit(digit))) + break; + + switch(qualifier) { + case 'H': /* that's 'hh' in format */ + if (is_sign) { + signed char *s = (signed char *) va_arg(args,signed char *); + *s = (signed char) simple_strtol(str,&next,base); + } else { + unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); + *s = (unsigned char) simple_strtoul(str, &next, base); + } + break; + case 'h': + if (is_sign) { + short *s = (short *) va_arg(args,short *); + *s = (short) simple_strtol(str,&next,base); + } else { + unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); + *s = (unsigned short) simple_strtoul(str, &next, base); + } + break; + case 'l': + if (is_sign) { + long *l = (long *) va_arg(args,long *); + *l = simple_strtol(str,&next,base); + } else { + unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); + *l = simple_strtoul(str,&next,base); + } + break; + case 'L': + if (is_sign) { + long long *l = (long long*) va_arg(args,long long *); + *l = simple_strtoll(str,&next,base); + } else { + unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); + *l = simple_strtoull(str,&next,base); + } + break; + case 'Z': + case 'z': + { + size_t *s = (size_t*) va_arg(args,size_t*); + *s = (size_t) simple_strtoul(str,&next,base); + } + break; + default: + if (is_sign) { + int *i = (int *) va_arg(args, int*); + *i = (int) simple_strtol(str,&next,base); + } else { + unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); + *i = (unsigned int) simple_strtoul(str,&next,base); + } + break; + } + num++; + + if (!next) + break; + str = next; + } + + /* + * Now we've come all the way through so either the input string or the + * format ended. In the former case, there can be a %n at the current + * position in the format that needs to be filled. + */ + if (*fmt == '%' && *(fmt + 1) == 'n') { + int *p = (int *)va_arg(args, int *); + *p = str - buf; + } + + return num; +} +EXPORT_SYMBOL(vsscanf); + +/** + * sscanf - Unformat a buffer into a list of arguments + * @buf: input buffer + * @fmt: formatting of buffer + * @...: resulting arguments + */ +int sscanf(const char * buf, const char * fmt, ...) +{ + va_list args; + int i; + + va_start(args,fmt); + i = vsscanf(buf,fmt,args); + va_end(args); + return i; +} +EXPORT_SYMBOL(sscanf); diff --git a/lib/am18x-lib/prj/abt_handler.S b/lib/am18x-lib/prj/abt_handler.S new file mode 100644 index 000000000..97bbc24bb --- /dev/null +++ b/lib/am18x-lib/prj/abt_handler.S @@ -0,0 +1,133 @@ +// tary, 18:51 2011/8/6 +#include "arm920t.h" + + .text + .arm + +.global HandlePrefetchAbort + @ LR_abt = PC + 4 (arm or thumb) + @ PC is address of instruction + @ that had the Prefetch Abort + @ return instruction SUBS PC, R14_abt, #4 + @ + @ now in Abort Mode + @ R13 = SP = SP_abt + @ R14 = LR = LR_abt + @ SPSR = SPSR_abt = CPSR(saved) + .func pabt +HandlePrefetchAbort: + PUSH {R0, R1, V1-V3, LR} + + MRS V1, SPSR + ANDS V3, V1, #XPSR_F_Thumb + LDREQ R1, =__arm_mode_fmt + SUBEQ V2, LR, #4 + LDRNE R1, =__thumb_mode_fmt + SUBNE V2, LR, #4 + + LDR V1, =printk + + LDR R0, =__pabt_fmt + MOV LR, PC + BX V1 + + LDR R0, =__abt_pc_fmt + MOV R1, V2 + MOV LR, PC + BX V1 + + LDR R0, =__new_line__ +2: + MOV LR, PC + BX V1 + POP {R0, R1, V1-V3, LR} + @SUBS PC, LR, #4 +__pabt_loop: + B __pabt_loop + .endfunc + +@.global HandleDataAbort +.weak HandleDataAbort + @ LR_abt = PC + 8 (arm or thumb) + @ PC is address of instruction + @ that had the Data Abort + @ return instruction SUBS PC, R14_abt, #8 + @ + @ now in Abort Mode + @ R13 = SP = SP_abt + @ R14 = LR = LR_abt + @ SPSR = SPSR_abt = CPSR(saved) + .func dabt +HandleDataAbort: + PUSH {R0, R1, V1-V3, LR} + + MRS V1, SPSR + ANDS V3, V1, #XPSR_F_Thumb + LDREQ R1, =__arm_mode_fmt + SUBEQ V2, LR, #8 + LDRNE R1, =__thumb_mode_fmt + SUBNE V2, LR, #8 + + LDR V1, =printk + + ADR R0, __dabt_fmt + MOV LR, PC + BX V1 + + ADR R0, __abt_pc_fmt + MOV R1, V2 + MOV LR, PC + BX V1 + + MOVS V3, V3 + BNE 1f +0: + ADR R0, __abt_arm_instruction + LDR R1, [V2, #0] + B 2f +1: + ADR R0, __abt_thumb_instruction + LDRH R1, [V2, #0] + B 2f +2: + MOV LR, PC + BX V1 + + BL arm_read_cp15_fault_address + MOV R1, R0 + ADR R0, __dabt_addr_fmt + MOV LR, PC + BX V1 + + POP {R0, R1, V1-V3, LR} + @SUBS PC, LR, #8 + SUBS PC, LR, #4 +__dabt_loop: + B __dabt_loop + + .align 4 + .ltorg + +__pabt_fmt: + .string "\n****** Prefetch Abort --- %s mode ******\n" +__dabt_fmt: + .string "\n****** Data Abort --- %s mode ******\n" +__dabt_addr_fmt: + .string "\tAbort address = 0x%.8X\n" +__arm_mode_fmt: + .string "arm" +__thumb_mode_fmt: + .string "thumb" +__abt_pc_fmt: + .string "\tPC = 0x%.8X" +__abt_arm_instruction: + .string " \t[PC] = 0x%.8X\n" +__abt_thumb_instruction: + .string " \t[PC] = 0x%.4X\n" +__new_line__: + .string "\n" + + .align 4 + .endfunc + + .end diff --git a/lib/am18x-lib/prj/am1808exp.c b/lib/am18x-lib/prj/am1808exp.c new file mode 100644 index 000000000..0f9b4856b --- /dev/null +++ b/lib/am18x-lib/prj/am1808exp.c @@ -0,0 +1,95 @@ +// tary, 1:03 2012/12/23 +#include "am18x_lib.h" +#include "systick.h" +#include "_uart.h" +#include "auxlib.h" +#include "tps6507x.h" +#include "am1808exp.h" + +#define SYSTICK_PERIOD 10/* milli seconds */ + + +static const ddr_conf_t mt46h64m16_6 = { + .ddr2_not_mddr = AM18X_FALSE, + .page_size = 10, + .row_size = 9, + .bank_cnt = 4, + + .freq_ck = 166000000, + .trefi = 7812, // ns + + .cl = 3, + .trfc = 100, + .trp = 18, + .trcd = 18, + + .twr = 15, + .tras = 42, + .trc = 60, + .trrd = 12, + + .twtr = 6, + .todt = 0, + .txsnr = 132, + .trtp = 18, + + .txp = 2, + .txsrd = 22, + .tcke = 1, + + .trasmax = 70000, + .pasr = 0, +}; + +static int sata_100m_clk_enable(am18x_bool on_noff) { + uint32_t v = on_noff? GPIO_LOW: GPIO_HIGH; + + psc_state_transition(PSC_GPIO, PSC_STATE_ENABLE); + + gpio_set_mux(SATA_100M_CLK_OEn, GPIO_DIR_OUTPUT); + gpio_set_output1(SATA_100M_CLK_OEn, v); + + // gpio_set_mux(SATA_100M_CLK_OEn, GPIO_DIR_INPUT); + // printk("SATA_100M_CLK_OEn = %d\n", gpio_get_output1(SATA_100M_CLK_OEn)); + return 0; +} + +int low_level_init(void) { + extern int isr_init(void); + extern int output_a_char(int); + int r; + + // output_a_char('S'); + + syscfg_kick(AM18X_FALSE); + + isr_init(); + + clk_node_init(); + uart_init(); + + // ddr_initialize(DDR0, &mt46h64m16_6); + + if (AM18X_OK != (r = systick_init(SYSTICK_PERIOD))) { + printk("systick_init() error\n"); + return r; + } + +/* if (AM18X_OK != (r = systick_start())) { + printk("systick_start() error\n"); + return r; + } +*/ + // invalid operation ? + sata_100m_clk_enable(AM18X_FALSE); + +#ifdef _M_BOOT_DELAY + delay(284091 * 3); +#endif + + // tps6507x_conf(); + + printk("ARM CLK: %9d Hz\n", dev_get_freq(DCLK_ID_ARM)); + + return AM18X_OK; +} diff --git a/lib/am18x-lib/prj/am1808exp.h b/lib/am18x-lib/prj/am1808exp.h new file mode 100644 index 000000000..e7c5cfe95 --- /dev/null +++ b/lib/am18x-lib/prj/am1808exp.h @@ -0,0 +1,85 @@ +// tary, 12:16 2015/10/24 +#ifndef __AM1808EXP_H__ +#define __AM1808EXP_H__ + +#include "am18x_lib.h" +#include "tps6507x.h" + +/* +// 1015640A_AM1808_SOM-M1_Schematic.pdf +#define TPS65070_POWER_ON GPIO_BANK2, GPIO_PIN_2 +#define TPS65070_PB_OUT GPIO_BANK2, GPIO_PIN_5 +#define M25P64_BUFF_OEn GPIO_BANK2, GPIO_PIN_6 +switch to +*/ +// 1015115C_AM1808_SOM-M1_Schematic.pdf +#define TPS65070_POWER_ONn GPIO_BANK2, GPIO_PIN_2 +#define TPS65070_INTn GPIO_BANK2, GPIO_PIN_3 +#define TPS65070_PB_OUT GPIO_BANK2, GPIO_PIN_5 +#define SATA_100M_CLK_OEn GPIO_BANK2, GPIO_PIN_6 + +#define MAX_RECEIVER_CNT 0x100 +// am1808.pdf +// Page 58, 2.7.27 Supply and Ground +typedef enum { + PRCV_AC_DUMMY = PWR_TYPE_AC * MAX_RECEIVER_CNT, + + + PRCV_USB_DUMMY = PWR_TYPE_USB * MAX_RECEIVER_CNT, + + + PRCV_SYS_DUMMY = PWR_TYPE_SYS * MAX_RECEIVER_CNT, + + + // 3.3V (power up step 5) + PRCV_DCDC1_DUMMY = PWR_TYPE_DCDC1 * MAX_RECEIVER_CNT, + PRCV_CPU_USB0_VDDA33, // USB0 PHY 3.3-V supply + PRCV_CPU_USB1_VDDA33, // USB1 PHY 3.3-V supply + PRCV_PCA9306_2, + PRCV_M25P64, + PRCV_SPI1_TRANS_U4_2, + PRCV_SATA_CLK_U20, + PRCV_LAN8710A_VDDxA, + + + // 3.3V_or_1.8V (power up step 4 or 5) + PRCV_DCDC2_DUMMY = PWR_TYPE_DCDC2 * MAX_RECEIVER_CNT, + PRCV_CPU_DVDD3318_A, // 1.8V or 3.3-V dual-voltage LVCMOS I/O supply voltage pins, Group A + PRCV_CPU_DVDD3318_B, // 1.8V or 3.3-V dual-voltage LVCMOS I/O supply voltage pins, Group B + PRCV_CPU_DVDD3318_C, // 1.8V or 3.3-V dual-voltage LVCMOS I/O supply voltage pins, Group C + PRCV_PCA9306_1, + PRCV_TCA6416_1, // Baseboard, IO EXPANDER + PRCV_SPI1_TRANS_U4_1, + PRCV_LAN8710A_VDDIO, + + + // 1.2V (power up step 2) + PRCV_DCDC3_DUMMY = PWR_TYPE_DCDC3 * MAX_RECEIVER_CNT, + PRCV_CPU_CVDD, // Variable (1.2V - 1.0V) core supply voltage pins + + + // 1.8V_LDO (power up step 4) + PRCV_LDO1_DUMMY = PWR_TYPE_LDO1 * MAX_RECEIVER_CNT, + PRCV_CPU_SATA_VDDR, // SATA PHY 1.8V internal regulator supply + PRCV_CPU_USB0_VDDA18, // USB0 PHY 1.8-V supply input + PRCV_CPU_USB1_VDDA18, // USB1 PHY 1.8-V supply input + PRCV_CPU_DVDD18, // 1.8V I/O supply voltage pins. + // DVDD18 must be powered even if all of + // the DVDD3318_x supplies are operated at 3.3V. + PRCV_CPU_DDR_DVDD18, // DDR PHY 1.8V power supply pins + PRCV_mDDR_VDD, + PRCV_mDDR_VDDQ, + + + // 1.2V_LDO (power up step 3) + PRCV_LDO2_DUMMY = PWR_TYPE_LDO2 * MAX_RECEIVER_CNT, + PRCV_CPU_PLL0_VDDA, // PLL analog Vdd(1.2-V filtered supply) + PRCV_CPU_PLL1_VDDA, // PLL analog Vdd(1.2-V filtered supply) + PRCV_CPU_RVDD, // 1.2 V internal ram supply voltage pins. + PRCV_CPU_SATA_VDD, // SATA PHY 1.2V logic supply + PRCV_CPU_USB_CVDD, // USB0 and USB1 core logic 1.2-V supply input + PRCV_LAN8710A_VDDCR, + +} power_receiver_t; + +#endif//__AM1808EXP_H__ diff --git a/lib/am18x-lib/prj/am18x.ld b/lib/am18x-lib/prj/am18x.ld new file mode 100644 index 000000000..73e6fb943 --- /dev/null +++ b/lib/am18x-lib/prj/am18x.ld @@ -0,0 +1,78 @@ +/* tary, 1:09 2012/12/23 */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SEARCH_DIR("=/usr/local/lib"); +SEARCH_DIR("=/lib"); +SEARCH_DIR("=/usr/lib"); +SECTIONS { + . = 0xc0008000; + . = ALIGN(0x4); + PROVIDE (__text_start = .); + .text : { + *(.init); + *(.text); + . = ALIGN(0x10); + + *(.rodata .rodata.*); + . = ALIGN(0x10); + + PROVIDE (__lds_got_start = .); + *(.got.plt); + *(.got); + . = ALIGN(0x10); + PROVIDE (__lds_got_end = .); + PROVIDE (__lds_got_size = __lds_got_end - __lds_got_start); + . = ALIGN(0x10); + } = 0 + PROVIDE (__text_end = .); + + PROVIDE (__data_start = .); + .data : { + *(.data); + . = ALIGN(0x10); + + *(.data.rel .data.rel.*); + . = ALIGN(0x10); + + PROVIDE (__lds_rel_start = .); + *(.rel.*); + . = ALIGN(0x10); + PROVIDE (__lds_rel_end = .); + PROVIDE (__lds_rel_size = __lds_rel_end - __lds_rel_start); + } = 0 + . = ALIGN(0x10); + PROVIDE (__data_end = .); + + /* + .rel __data_end : { + } = 0 + */ + + .bss __lds_rel_start (NOLOAD): { + PROVIDE (__lds_bss_start = .); + *(.bss) + *(COMMON) + . = ALIGN(0x10); + PROVIDE (__lds_bss_end = .); + } = 0 + + . = ALIGN(0x10); + .stack : { + *(.stack) + . = ALIGN(0x10); + } + PROVIDE (end = .); + + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.gnu.lto_*) + /*(.debug*)*/ + *(.ARM.attributes) + *(.comment) + *(.interp) + *(.dyn*) + *(.hash) + } +} diff --git a/lib/am18x-lib/prj/am18x_conf.c b/lib/am18x-lib/prj/am18x_conf.c new file mode 100644 index 000000000..954891810 --- /dev/null +++ b/lib/am18x-lib/prj/am18x_conf.c @@ -0,0 +1,167 @@ +// tary, 1:04 2012/12/23 +#include "am18x_lib.h" +#include "auxlib.h" + +extern int output_a_char(int); + +static none_arg_handler_t isr_vector[] = { + // 0 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 10 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 20 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 30 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 40 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 50 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 60 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 70 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 80 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 90 + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + // 100 + NULL, +}; + +int isr_set_handler(int intr_nr, none_arg_handler_t handle) { + if (intr_nr >= countof(isr_vector)) { + return -1; + } + isr_vector[intr_nr] = handle; + return 0; +} + +int c_irq_handler(void) { + int32_t irq_nr = aintc_get_active(); + + if (irq_nr == AINTC_INVALID_ACTIVE) { + return -1; + } + if (isr_vector[irq_nr] != NULL) { + (*isr_vector[irq_nr])(); + } + + aintc_clear(irq_nr); + + return 0; +} + +int isr_init(void) { + aintc_conf_t aconf[1]; + + aconf->isr_addr = (uint32_t)isr_vector; + aconf->isr_size = sizeof isr_vector; + + aintc_conf(aconf); + + aintc_enable(AINTC_GLOBAL); + aintc_enable(AINTC_HOST_IRQ); + + return 0; +} diff --git a/lib/am18x-lib/prj/am18x_conf.h b/lib/am18x-lib/prj/am18x_conf.h new file mode 100644 index 000000000..389ae8be8 --- /dev/null +++ b/lib/am18x-lib/prj/am18x_conf.h @@ -0,0 +1,87 @@ +// tary, 1:05 2012/12/23 +#ifndef __AM18X_CONF_H__ +#define __AM18X_CONF_H__ + +#define __USE_STDINT_H + +#include + +#define F_OSCIN 24000000UL //Hz +extern const uint32_t f_osc; + +#define _MPU +#define _MPU1 +#define _MPU2 + +#define _DCLK + +#define _PLL +#define _PLL0 +#define _PLL1 + +#define _PSC +#define _PSC0 +#define _PSC1 + +#define _SYSCFG +#define _SYSCFG0 +#define _SYSCFG1 + +#define _AINTC + +#define _PRU +#define _PRU0 +#define _PRU1 + +#define _DDR +#define _DDR0 + +#define _EDMA +#define _EDMA0 +#define _EDMA1 + +#define _GPIO + +#define _I2C +#define _I2C0 +#define _I2C1 + +#define _LCD +#define _LCD0 + +#define _MMCSD +#define _MMCSD0 +#define _MMCSD1 + +#define _TIMER +#define _TIMER0 +#define _TIMER1 +#define _TIMER2 +#define _TIMER3 + +#define _UART +#define _UART0 +#define _UART1 +#define _UART2 + +#define _USB +#define _USB0 + +#define _RTC + +#define _ECAP +#define _ECAP2 + +#ifdef DEBUG +#define assert(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +void assert_failed(uint8_t* file, uint32_t line); +#else +#define assert(expr) ((void)0) +#endif // DEBUG + +typedef void (*none_arg_handler_t)(void); + +int isr_set_handler(int intr_nr, none_arg_handler_t handle); + + +#endif//__AM18X_CONF_H__ diff --git a/lib/am18x-lib/prj/start.S b/lib/am18x-lib/prj/start.S new file mode 100644 index 000000000..5cc1db3ac --- /dev/null +++ b/lib/am18x-lib/prj/start.S @@ -0,0 +1,220 @@ +@tary, 22:42 2012/11/27 +@******************************************************************************* +@* the startup code for am18x_lib * +@******************************************************************************* + +#include "linkage.h" +#include "arm920t.h" +#include "am18x_map_s.h" + +.equ usr_stack_size, 0x00001000 +.equ isr_stack_size, 0x00000200 +.equ und_stack_size, 0x00000200 +.equ und_stack_size, 0x00000200 + + .section .init, "ax" + .arm + + .macro ldr_fix, Rx, symbol + LDR \Rx, = \symbol + ADD \Rx, \Rx, R9 + .endm + + .global _start +_start: +__load_addr: +__vector_start: + B HandleReset + LDR PC, undef_addr + LDR PC, swi_addr + LDR PC, pabt_addr + LDR PC, dabt_addr + LDR PC, notused_addr + LDR PC, irq_addr + LDR PC, fiq_addr +__vector_jump: .long HandleReset +undef_addr: .long HandleUndef +swi_addr: .long HandleSWI +pabt_addr: .long HandlePrefetchAbort +dabt_addr: .long HandleDataAbort +notused_addr: .long HandleNotUsed +irq_addr: .long HandleIRQ +fiq_addr: .long HandleFIQ +__vector_end: + +HandleSWI: +HandleNotUsed: +HandleFIQ: +__dummy_handler: + B __dummy_handler + + +HandleIRQ: + .extern c_irq_handler + SUB LR, LR, #4 + STMDB SP!, {R0-R12, LR} + + BL c_irq_handler + + LDMIA SP!, {R0-R12, PC}^ + +HandleReset: + @ retrive image offset (load address - link address) + LDR R0, __link_addr + ADR R9, __load_addr + SUB R9, R9, R0 + + @ enter user mode and set its stack pointer + MSR CPSR_c, #XPSR_Mode_System | XPSR_F_FIQ | XPSR_F_IRQ + ldr_fix R0, stack_usr + MOV SP, R0 + + MSR CPSR_c, #XPSR_Mode_IRQ | XPSR_F_FIQ | XPSR_F_IRQ + ldr_fix R0, stack_isr + MOV SP, R0 + + MSR CPSR_c, #XPSR_Mode_Abort | XPSR_F_FIQ | XPSR_F_IRQ + ldr_fix R0, stack_abt + MOV SP, R0 + + MSR CPSR_c, #XPSR_Mode_Undefined | XPSR_F_FIQ | XPSR_F_IRQ + ldr_fix R0, stack_und + MOV SP, R0 + + MSR CPSR_c, #XPSR_Mode_System | XPSR_F_FIQ | XPSR_F_IRQ + + .extern arm_intr_disable + BL arm_intr_disable + + @ fix vector jump address + MOV R0, R9 + ldr_fix R1, __vector_jump + ldr_fix R2, __vector_end + BL __reloc_got + + @ copy vectors to high memory + LDR R0, =ARMLocalRAM_BASE + ldr_fix R1, __vector_start + ldr_fix R2, __vector_end + BL __copy_mem + + @ Set the IVT to high memory, leave MMU & caches disabled + MRC P15, #0, R0, C1, C0, #0 + BIC R0, R0, #0x00003300 + BIC R0, R0, #0x00000087 + ORR R0, R0, #0x00000002 + ORR R0, R0, #0x00002000 + MCR P15, #0, R0, C1, C0, #0 + NOP + + ldr_fix SL, __load_addr + + #if 0 + @ got relocation by __reloc_dyn() instead + @ relocate got to current address + .global __lds_got_start + .global __lds_got_end + MOV R0, SL + ldr_fix R1, __lds_got_start + ldr_fix R2, __lds_got_end + BL __reloc_got + #endif + + @ relocate dyn to current address + .global __lds_rel_start + .global __lds_rel_end + MOV R0, SL + ldr_fix R1, __lds_rel_start + ldr_fix R2, __lds_rel_end + BL __reloc_dyn + + @ clear BSS area + .extern __lds_bss_start + .extern __lds_bss_end + MOV R0, #0 + @ do not use ldr_fix after __reloc_dyn() + LDR R1, =__lds_bss_start + LDR R2, =__lds_bss_end +1: + STR R0, [R1], #4 + CMP R1, R2 + BLO 1b + + .extern low_level_init + BL low_level_init + + @ call to main entry point + .extern main + bl main + +_loop: + B _loop + + .global get_exec_base +get_exec_base: + MOV R0, SL + MOV PC, LR + + @ Add every element in [r1,r2) with r0 + .global __reloc_got +__reloc_got: + CMP R1, R2 + MOVHS PC, LR +1: + LDR R4, [R1] + ADD R4, R4, R0 + STR R4, [R1], #4 + CMP R1, R2 + BLO 1b + MOV PC, LR + + @ Add word pointed by odd element in [r1,r2) with r0 + .global __reloc_dyn +__reloc_dyn: + CMP R1, R2 + MOVHS PC, LR +1: + LDM R1!, {R3, R4} + CMP R4, #0x17 + BNE 2f + ADD R3, R3, R0 + LDR R4, [R3] + ADD R4, R4, R0 + STR R4, [R3] +2: + CMP R1, R2 + BLO 1b + MOV PC, LR + + @ copy memory from [r1, r2) to [R0, r0 + r2 - r1) + .global __copy_mem +__copy_mem: + CMP R1, R2 + MOVHS PC, LR +1: + LDR R3, [R1], #4 + STR R3, [R0], #4 + CMP R1, R2 + BLO 1b + MOV PC, LR + + +__link_addr: + .long __load_addr + .extern __lds_got_size + .func __lds_got_size + .long __lds_got_size + .ltorg + + .section .stack, "w" + .balign 0x10 +stack_mem: + .space usr_stack_size +stack_usr: + .space isr_stack_size +stack_isr: + .space und_stack_size +stack_abt: + .space und_stack_size +stack_und: + .end diff --git a/lib/am18x-lib/prj/tca6416.c b/lib/am18x-lib/prj/tca6416.c new file mode 100644 index 000000000..b61655721 --- /dev/null +++ b/lib/am18x-lib/prj/tca6416.c @@ -0,0 +1,91 @@ +// tary, 23:04 2013/3/25 +#include "am18x_lib.h" +#include "tca6416.h" +#include "auxlib.h" +#include "i2c_inf.h" + +// 1015526A_AM1808_Baseboard_Schematic.pdf +// Page 14, IO EXPANDER +#define TCA6416_BUS I2C0 + +// tca6416.pdf +// Device Address +#define TCA6416_ADDR 0x21 // 0x20 + +#define TCA6416_SPEED 350000 // 400K + +// Control Register and Command Byte +// Once a new command has been sent, the register that +// was addressed continues to be accessed by reads until +// a new command byte has been sent. +typedef enum { + // reflect the incomming logic of the pins, + // regardless of whether the pin is defined as + // an input or an output by the Configuration register + INPUT_PORT_0, + INPUT_PORT_1, + // value that is in the flip-flop controlling + // the output selection, NOT the actual pin value + OUTPUT_PORT_0, + OUTPUT_PORT_1, + // allow polarity inversion of pins defined as inputs + // by the Configuration register. + POLARITY_INVERSION_PORT_0, + POLARITY_INVERSION_PORT_1, + // configure the direction of the I/O pins. + // If a bit in these register is set to 1, + // the corresponding port pin is enabled as + // an input with a high-impedance output driver. + CONFIGURATION_PORT_0, + CONFIGURATION_PORT_1, +} TCA6416_reg_t; + +static inline int tca6416_reg_write(uint8_t reg, uint16_t val) { + uint8_t bytes[3]; + + bytes[0] = reg; + bytes[1] = FIELD_XGET(val, 0x00FFUL); + bytes[2] = FIELD_XGET(val, 0xFF00UL); + + i2c_write(TCA6416_BUS, TCA6416_ADDR, bytes, sizeof bytes); + + return 0; +} + +static inline int tca6416_reg_read(uint8_t reg) { + uint8_t bytes[2]; + uint16_t val = 0; + + bytes[0] = reg; + i2c_write(TCA6416_BUS, TCA6416_ADDR, bytes, 1); + i2c_read(TCA6416_BUS, TCA6416_ADDR, bytes, sizeof bytes); + + val = FIELD_XSET(val, 0x00FFUL, bytes[0]); + val = FIELD_XSET(val, 0xFF00UL, bytes[1]); + return val; +} + +int tca6416_conf(uint16_t dir) { + int i; + + i2c_init(TCA6416_BUS, TCA6416_SPEED); + + for (i = 0; i < 8 ; i += 2) { + printk("[0x%.2X] = 0x%.4X\n", i, tca6416_reg_read(i)); + } + tca6416_reg_write(POLARITY_INVERSION_PORT_0, 0x0000UL); + tca6416_reg_write(CONFIGURATION_PORT_0, dir); + return 0; +} + +int tca6416_read(void) { + uint16_t v; + + v = tca6416_reg_read(INPUT_PORT_0); + return v; +} + +int tca6416_write(uint16_t val) { + tca6416_reg_write(OUTPUT_PORT_0, val); + return 0; +} diff --git a/lib/am18x-lib/prj/tca6416.h b/lib/am18x-lib/prj/tca6416.h new file mode 100644 index 000000000..c67e7b97a --- /dev/null +++ b/lib/am18x-lib/prj/tca6416.h @@ -0,0 +1,19 @@ +// tary, 23:10 2013/3/25 +#ifndef __TCA6416_H__ +#define __TCA6416_H__ + +#include "am18x_lib.h" + +// low byte as Port 0, high byte as Port 1 +// Port0.Pin1 as bit 1, Port1.Pin4 as bit 12, etc + +// bit set as input, bit clear as output +// -1 as error, 0 as success +int tca6416_conf(uint16_t dir); +// bit set as high level, bit clear as low level +// -1 as error, the port value otherwise +int tca6416_read(void); +// -1 as error, 0 as success +int tca6416_write(uint16_t val); + +#endif//__TCA6416_H__ diff --git a/lib/am18x-lib/prj/tps6507x.c b/lib/am18x-lib/prj/tps6507x.c new file mode 100644 index 000000000..a54393c38 --- /dev/null +++ b/lib/am18x-lib/prj/tps6507x.c @@ -0,0 +1,297 @@ +// tary, 1:49 2013/4/28 +#include "am18x_lib.h" +#include "tps6507x.h" +#include "auxlib.h" +#include "i2c_inf.h" + +// 1015640A_AM1808_SOM-M1_Schematic.pdf +// Page 7, PMIC +#define TPS6507X_BUS I2C0 + +// slvs950f.pdf +// Device Address +#define TPS6507X_ADDR 0x48 + +#define TPS6507X_SPEED 350000 // 400K + +// REGISTERS +typedef enum { + TPS6507X_REG_NULL, // 0x00 + TPS6507X_REG_PPATH1, + TPS6507X_REG_INT, + TPS6507X_REG_CHGCONFIG0, + + TPS6507X_REG_CHGCONFIG1, // 0x04 + TPS6507X_REG_CHGCONFIG2, + TPS6507X_REG_CHGCONFIG3, +#define ADCONFIG_SELECT_MASK 0x0FUL +#define ADCONFIG_SELECT_ac 0x06UL +#define ADCONFIG_SELECT_sys 0x07UL + TPS6507X_REG_ADCONFIG, + + TPS6507X_REG_TSCMODE, // 0x08 + TPS6507X_REG_ADRESULT_1, + TPS6507X_REG_ADRESULT_2, + TPS6507X_REG_PGOOD, + + TPS6507X_REG_PGOODMASK, // 0x0C + TPS6507X_REG_CON_CTRL1, + TPS6507X_REG_CON_CTRL2, + TPS6507X_REG_CON_CTRL3, + +// apply to DEFDCDC1, DEFDCDC2_LOW, DEFDCDC2_HIGH +// DEFDCDC3_LOW, DEFDCDC3_HIGH, DEFLDO2 +#define DEFDCDCX_OUTVOLT_MASK 0x3FUL + TPS6507X_REG_DEFDCDC1, // 0x10 + TPS6507X_REG_DEFDCDC2_LOW, + TPS6507X_REG_DEFDCDC2_HIGH, + TPS6507X_REG_DEFDCDC3_LOW, + + TPS6507X_REG_DEFDCDC3_HIGH, // 0x14 + TPS6507X_REG_DEFSLEW, +#define LDO_CTRL1_OUTVOLT_MASK 0x0FUL + TPS6507X_REG_LDO_CTRL1, + TPS6507X_REG_DEFLDO2, + + TPS6507X_REG_WLED_CTRL1, // 0x18 + TPS6507X_REG_WLED_CTRL2, + TPS6507X_REG_CNT, +} TPS6507X_reg_t; + +enum { + BIT_DEF(PPATH1,7,USBPresent,no,yes), + BIT_DEF(PPATH1,6,ACPresent,no,yes), + BIT_DEF(PPATH1,5,USBPower,enable,disable), + BIT_DEF(PPATH1,4,ACPower,enable,disable), + BIT_DEF(ADCONFIG,7,Enable,no,yes), + BIT_DEF(ADCONFIG,6,Start,no,yes), + BIT_DEF(ADCONFIG,5,End,no,yes), + BIT_DEF(ADCONFIG,4,Vref,disable,enable), + BIT_DEF(CON_CTRL1,4,DCDC1,disable,enable), + BIT_DEF(CON_CTRL1,3,DCDC2,disable,enable), + BIT_DEF(CON_CTRL1,2,DCDC3,disable,enable), + BIT_DEF(CON_CTRL1,1,LDO1,disable,enable), + BIT_DEF(CON_CTRL1,0,LDO2,disable,enable), +}; + +static const uint16_t dcdcx_voltage[] = { + 725, 750, 775, 800, // 725 + 25 * i + 825, 850, 875, 900, + 925, 950, 975, 1000, + 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, + 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, + 1425, 1450, 1475, 1500, + + 1550, 1600, 1650, 1700, // 1550 + 50 * (i - 16) + 1750, 1800, 1850, 1900, + 1950, 2000, 2050, 2100, + 2150, 2200, 2250, 2300, + 2350, 2400, 2450, 2500, + 2550, 2600, 2650, 2700, + 2750, 2800, 2850, 2900, + 3000, 3100, 3200, 3300, // 3000 + 100 * (i - 28) + 0, 0, +}; + +static const uint16_t ldo1_voltage[] = { + 1000, 1100, 1200, 1250, + 1300, 1350, 1400, 1500, + 1600, 1800, 2500, 2750, + 2800, 3000, 3100, 3200, + 0, 0, +}; + +static inline int tps6507x_reg_write(uint8_t reg, uint8_t val) { + uint8_t bytes[2]; + + bytes[0] = reg; + bytes[1] = val; + + i2c_write(TPS6507X_BUS, TPS6507X_ADDR, bytes, sizeof bytes); + + return 0; +} + +static inline int tps6507x_reg_read(uint8_t reg) { + uint8_t bytes[1]; + + bytes[0] = reg; + i2c_write(TPS6507X_BUS, TPS6507X_ADDR, bytes, 1); + i2c_read(TPS6507X_BUS, TPS6507X_ADDR, bytes, sizeof bytes); + + return bytes[0]; +} + +int tps6507x_dump_regs(void) { + int i; + + for (i = 1; i < TPS6507X_REG_CNT ; i++) { + printk("[0x%.2X] = 0x%.2X\n", i, tps6507x_reg_read(i)); + } + return 0; +} + +int tps6507x_conf(void) { + i2c_init(TPS6507X_BUS, TPS6507X_SPEED); + return 0; +} + +int tps6507x_get_adc(pwr_type_t pt) { + uint32_t msk; + uint16_t r; + uint8_t v; + + if (pt != PWR_TYPE_AC + && pt != PWR_TYPE_SYS + ) { + return -1; + } + + // Set Bit AD ENABLE = 1 to provide power to the ADC + msk = ADCONFIG_Enable_MASK; + v = tps6507x_reg_read(TPS6507X_REG_ADCONFIG); + v = FIELD_SET(v, msk, ADCONFIG_Enable_yes); + tps6507x_reg_write(TPS6507X_REG_ADCONFIG, v); + + // Set input select for the ADC in register ADCONFIG to 011X + v = tps6507x_reg_read(TPS6507X_REG_ADCONFIG); + msk = ADCONFIG_SELECT_MASK; + if (pt == PWR_TYPE_AC) { + v = FIELD_SET(v, msk, ADCONFIG_SELECT_ac); + } else { + v = FIELD_SET(v, msk, ADCONFIG_SELECT_sys); + } + tps6507x_reg_write(TPS6507X_REG_ADCONFIG, v); + + // Start a conversion by setting CONVERSION START = 1; + // wait until END OF CONVERSION = 1 + msk = ADCONFIG_Start_MASK; + v = tps6507x_reg_read(TPS6507X_REG_ADCONFIG); + v = FIELD_SET(v, msk, ADCONFIG_Start_yes); + tps6507x_reg_write(TPS6507X_REG_ADCONFIG, v); + + msk = ADCONFIG_End_MASK; + do { + v = tps6507x_reg_read(TPS6507X_REG_ADCONFIG); + } while (FIELD_GET(v, msk) != ADCONFIG_End_yes); + + // Read register ADRESULT_1 and ADRESULT_2 + r = tps6507x_reg_read(TPS6507X_REG_ADRESULT_1); + v = tps6507x_reg_read(TPS6507X_REG_ADRESULT_2); + r = __field_xset(r, 0x0300UL, v); + + return r; +} + +static const uint16_t* pwrtyp2voltages(pwr_type_t pt, int* pr, uint8_t* pm) { + const uint16_t* voltages; + uint8_t msk; + int reg; + + msk = DEFDCDCX_OUTVOLT_MASK; + voltages = dcdcx_voltage; + switch (pt) { + case PWR_TYPE_DCDC1: + reg = TPS6507X_REG_DEFDCDC1; + break; + case PWR_TYPE_DCDC2: + reg = TPS6507X_REG_DEFDCDC2_HIGH; + break; + case PWR_TYPE_DCDC3: + reg = TPS6507X_REG_DEFDCDC3_HIGH; + break; + case PWR_TYPE_LDO1: + reg = TPS6507X_REG_LDO_CTRL1; + msk = LDO_CTRL1_OUTVOLT_MASK; + voltages = ldo1_voltage; + break; + case PWR_TYPE_LDO2: + reg = TPS6507X_REG_DEFLDO2; + break; + default: + return NULL; + } + if (pr != NULL) { + *pr = reg; + } + if (pm != NULL) { + *pm = msk; + } + return voltages; +} + +int tps6507x_get_output(pwr_type_t pt) { + const uint16_t* voltages; + uint8_t msk; + int reg, v; + + if ((voltages = pwrtyp2voltages(pt, ®, &msk)) == NULL) { + return 0; + } + + v = tps6507x_reg_read(reg); + v = __field_xget(v, msk); + return voltages[v]; +} + +int tps6507x_set_output(pwr_type_t pt, uint16_t voltage) { + const uint16_t* voltages; + uint8_t msk; + int i, reg, v; + + if ((voltages = pwrtyp2voltages(pt, ®, &msk)) == NULL) { + return -1; + } + + for (i = 0; voltages[i] != 0 && voltages[i] <= voltage; i++) { + } + if (--i < 0) i = 0; + + v = tps6507x_reg_read(reg); + v = __field_xset(v, msk, i); + tps6507x_reg_write(reg, v); + return 0; +} + +int tps6507x_power_switch(pwr_type_t pt, am18x_bool on_noff) { + uint32_t msk; + uint8_t reg, v, f; + + if (pt == PWR_TYPE_AC) { + reg = TPS6507X_REG_PPATH1; + msk = PPATH1_ACPower_MASK; + f = on_noff? PPATH1_ACPower_enable: PPATH1_ACPower_disable; + } else if (pt == PWR_TYPE_USB) { + reg = TPS6507X_REG_PPATH1; + msk = PPATH1_USBPower_MASK; + f = on_noff? PPATH1_USBPower_enable: PPATH1_USBPower_disable; + } else if (pt == PWR_TYPE_DCDC1) { + reg = TPS6507X_REG_CON_CTRL1; + msk = CON_CTRL1_DCDC1_MASK; + f = on_noff? CON_CTRL1_DCDC1_enable: CON_CTRL1_DCDC1_disable; + } else if (pt == PWR_TYPE_LDO1) { + reg = TPS6507X_REG_CON_CTRL1; + msk = CON_CTRL1_LDO1_MASK; + f = on_noff? CON_CTRL1_LDO1_enable: CON_CTRL1_LDO1_disable; + } else if (pt == PWR_TYPE_LDO2 + || pt == PWR_TYPE_DCDC2 + || pt == PWR_TYPE_DCDC3 + ) { + reg = TPS6507X_REG_CON_CTRL1; + msk = CON_CTRL1_LDO2_MASK; + msk |= CON_CTRL1_DCDC2_MASK; + msk |= CON_CTRL1_DCDC3_MASK; + f = on_noff? CON_CTRL1_LDO2_enable: CON_CTRL1_LDO2_disable; + f |= on_noff? CON_CTRL1_DCDC2_enable: CON_CTRL1_DCDC2_disable; + f |= on_noff? CON_CTRL1_DCDC3_enable: CON_CTRL1_DCDC3_disable; + } else { + return -1; + } + v = tps6507x_reg_read(reg); + v = FIELD_SET(v, msk, f); + tps6507x_reg_write(reg, v); + + return 0; +} diff --git a/lib/am18x-lib/prj/tps6507x.h b/lib/am18x-lib/prj/tps6507x.h new file mode 100644 index 000000000..905ac9b90 --- /dev/null +++ b/lib/am18x-lib/prj/tps6507x.h @@ -0,0 +1,35 @@ +// tary, 2:11 2013/4/28 +#ifndef __TPS6507X_H__ +#define __TPS6507X_H__ + +#include "am18x_lib.h" + +typedef enum { + // adc && switch + PWR_TYPE_AC, + + // switch + PWR_TYPE_USB, + + // adc + PWR_TYPE_SYS, + + // output && switch + PWR_TYPE_DCDC1, + PWR_TYPE_DCDC2, + PWR_TYPE_DCDC3, + PWR_TYPE_LDO1, + PWR_TYPE_LDO2, + + PWR_TYPE_CNT, +} pwr_type_t; + +int tps6507x_conf(void); +int tps6507x_dump_regs(void); +int tps6507x_get_adc(pwr_type_t pt); +// return unit: milli volt +int tps6507x_get_output(pwr_type_t pt); +int tps6507x_set_output(pwr_type_t pt, uint16_t voltage); +int tps6507x_power_switch(pwr_type_t pt, am18x_bool on_noff); + +#endif//__TPS6507X_H__ diff --git a/lib/am18x-lib/prj/uart_dbg.S b/lib/am18x-lib/prj/uart_dbg.S new file mode 100644 index 000000000..fe25762a7 --- /dev/null +++ b/lib/am18x-lib/prj/uart_dbg.S @@ -0,0 +1,113 @@ +@ tary, 12:58 2013/3/3 +#include "am18x_map_s.h" + +#define UART2_PSC_NR 0x0D + + .section .text + .arm + .global output_a_char +output_a_char: + MOV R12, R0 + + @ kick off + LDR R0, =SYSCFG0_BASE + LDR R1, =KICK0R_UNLOCK + LDR R2, =KICK1R_UNLOCK + STR R1, [R0, #0x38] + STR R2, [R0, #0x3C] + + @ uart module state transition + LDR R0, =PSC1_BASE + LDR R1, =MDCTLx_STATE_Enable + +1: // Wait until PTSTAT == 0 + LDR R3, [R0, #0x128] + TST R3, #1 + BNE 1b + + // if MDSTATx[UART2] != MDCTLx_STATE_Enable + MOV R3, #UART2_PSC_NR + ADD R3, R3, #0x200 + LDR R2, [R0, R3, LSL #2] + AND R2, R2, #0x1F + SUBS R2, R2, R1 + BEQ __skip_psc + + // R2 = MDCTLx[UART2] + MOV R3, #UART2_PSC_NR + ADD R3, R3, #0x280 + LDR R2, [R0, R3, LSL #2] + + // MDCTLx[UART2] |= R1 + BIC R2, R2, #0x7 + ORR R2, R2, R1 + STR R2, [R0, R3, LSL #2] + + // PTCMD = 1 + LDR R3, [R0, #0x120] + ORR R3, R3, #1 + STR R3, [R0, #0x120] + +2: // Wait until PTSTAT == 0 + LDR R3, [R0, #0x128] + TST R3, #1 + BNE 2b + +3: // Wait until MDSTATx[UART2] == MDCTLx_STATE_Enable + MOV R3, #UART2_PSC_NR + ADD R3, R3, #0x200 + LDR R2, [R0, R3, LSL #2] + AND R2, R2, #0x1F + SUBS R2, R2, R1 + BNE 3b +__skip_psc: + + @ AM1808 UART2 pinmux setting + // R2 = PINMUXx[4] + LDR R0, =SYSCFG0_BASE + LDR R3, =4 + ADD R3, R3, #0x48 + LDR R2, [R0, R3, LSL #2] + + // PINMUXx[4] = XX22XXXX + BIC R2, R2, #0x00FF0000 + ORR R2, R2, #0x00220000 + STR R2, [R0, R3, LSL #2] + + @ AM1808 UART setting + LDR R0, =UART2_BASE + + LDR R1, =0x6003 + STR R1, [R0, #0x30] + + LDR R1, =0x03 + STR R1, [R0, #0x0C] + + // DLH:DLL = 0x0008 + // oscin = 24000000 Hz + // UART working clock (PLLx_SYSCLK2) = oscin / 2 = 12000000 Hz + // UART bit clock = PLLx_SYSCLK2 / 13 Hz + // DLH:DLL = UART bit clock / ( 115200 Hz ) + LDR R1, =0x08 + STR R1, [R0, #0x20] + MOV R1, #0x00 + STR R1, [R0, #0x24] + + LDR R1, =0x01 + STR R1, [R0, #0x34] + + @ wait buffer empty + LDR R0, =UART2_BASE +4: + LDR R1, [R0, #0x14] + TST R1, #(0x1 << 5) + BEQ 4b + + @ output a char to uart + @LDR R1, ='X' + MOV R1, R12 + STR R1, [R0, #0x00] + + MOV PC, LR + .ltorg + .end diff --git a/lib/am18x-lib/prj/undef_handler.S b/lib/am18x-lib/prj/undef_handler.S new file mode 100644 index 000000000..f1bd7a9b1 --- /dev/null +++ b/lib/am18x-lib/prj/undef_handler.S @@ -0,0 +1,75 @@ +// tary, 18:53 2011/8/6 +#include "arm920t.h" + + .text + .arm + +.global HandleUndef + @ LR_und = PC + 4 (arm) + @ LR_und = PC + 2 (thumb) + @ PC is address of undefined instruction fetch + @ return instruction MOVS PC, R14_und + @ + @ now in Undefined Instruction Mode + @ R13 = SP = SP_und + @ R14 = LR = LR_und + @ SPSR = SPSR_und = CPSR(saved) + .func HandleUndef +HandleUndef: + PUSH {R0, R1, V1-V3, LR} + + MRS V1, SPSR + ANDS V3, V1, #XPSR_F_Thumb + LDREQ R1, =__arm_mode_fmt + SUBEQ V2, LR, #4 + LDRNE R1, =__thumb_mode_fmt + SUBNE V2, LR, #2 + ADR R0, __undef_fmt + LDR V1, =printk + MOV LR, PC + BX V1 + + ADR R0, __undef_pc_fmt + MOV R1, V2 + MOV LR, PC + BX V1 + + MOVS V3, V3 + BNE 1f +0: + ADR R0, __undef_arm_instruction + LDR R1, [V2, #0] + B 2f +1: + ADR R0, __undef_thumb_instruction + LDRH R1, [V2, #0] + B 2f +2: + MOV LR, PC + BX V1 + + POP {R0, R1, V1-V3, LR} + MOVS PC, LR +__undef_loop: + B __undef_loop + + .align 4 + .ltorg + +__undef_fmt: + .string "\n****** Undefined Instruction --- %s mode ******\n" +__arm_mode_fmt: + .string "arm" +__thumb_mode_fmt: + .string "thumb" +__undef_pc_fmt: + .string "\tPC = 0x%.8X " +__undef_arm_instruction: + .string "\t[PC] = 0x%.8X\n" +__undef_thumb_instruction: + .string "\t[PC] = 0x%.4X\n" + + .balign 4 + .endfunc + + .end diff --git a/lib/am18x-lib/src/am18x_aintc.c b/lib/am18x-lib/src/am18x_aintc.c new file mode 100644 index 000000000..692ad33ff --- /dev/null +++ b/lib/am18x-lib/src/am18x_aintc.c @@ -0,0 +1,137 @@ +// tary, 0:48 2013/3/9 +#include "am18x_aintc.h" + +#define acon AINTC + +static void null_operation(void) { + return; +} + +am18x_rt aintc_conf(const aintc_conf_t* conf) { + uint32_t reg, msk; + int i; + + // all system interrupt for IRQ + for (i = 0; i < AINTC_ASSIGN_CNT; i++) { + reg = acon->CMRx[CMRx_X(i)]; + msk = CMRx_MASK(i); + acon->CMRx[CMRx_X(i)] = __field_xset(reg, msk, 2); + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(i)); + acon->EIxR[AINTC_IDX_CLR] = reg; + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(i)); + acon->SIxR[AINTC_IDX_CLR] = reg; + } + acon->VBR = conf->isr_addr; + acon->VSR = VSR_SIZE_VAL(conf->isr_size); + acon->VNR = (uint32_t)&null_operation; + + msk = GER_ENABLE_MASK; + acon->GER = FIELD_SET(acon->GER, msk, GER_ENABLE_no); + + return AM18X_OK; +} + +am18x_rt aintc_enable(aintc_host_t host) { + uint32_t msk; + + switch (host) { + case AINTC_GLOBAL: + msk = GER_ENABLE_MASK; + acon->GER = FIELD_SET(acon->GER, msk, GER_ENABLE_yes); + break; + case AINTC_HOST_IRQ: + msk = HIER_IRQ_MASK; + acon->HIER = FIELD_SET(acon->HIER, msk, HIER_IRQ_enabled); + break; + case AINTC_HOST_FIQ: + msk = HIER_FIQ_MASK; + acon->HIER = FIELD_SET(acon->HIER, msk, HIER_FIQ_enabled); + break; + default: + return AM18X_ERR; + } + return AM18X_OK; +} + +am18x_rt aintc_disable(aintc_host_t host) { + uint32_t msk; + + switch (host) { + case AINTC_GLOBAL: + msk = GER_ENABLE_MASK; + acon->GER = FIELD_SET(acon->GER, msk, GER_ENABLE_no); + break; + case AINTC_HOST_IRQ: + msk = HIER_IRQ_MASK; + acon->HIER = FIELD_SET(acon->HIER, msk, HIER_IRQ_disabled); + break; + case AINTC_HOST_FIQ: + msk = HIER_FIQ_MASK; + acon->HIER = FIELD_SET(acon->HIER, msk, HIER_FIQ_disabled); + break; + default: + return AM18X_ERR; + } + return AM18X_OK; +} + +am18x_rt aintc_sys_enable(AINTC_assign_t assign) { + uint32_t reg; + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(assign)); + acon->EIxR[AINTC_IDX_SET] = reg; + + // also for acon->ESRx + return AM18X_OK; +} + +am18x_rt aintc_sys_disable(AINTC_assign_t assign) { + uint32_t reg; + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(assign)); + acon->EIxR[AINTC_IDX_CLR] = reg; + + // also for acon->ECRx + return AM18X_OK; +} + +am18x_rt aintc_trigger(AINTC_assign_t assign) { + /* + int idx; + + idx = SXXRx_WR_X(assign); + acon->SRSRx[idx] = SXXRx_WR_VAL(assign); + */ + uint32_t reg; + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(assign)); + acon->SIxR[AINTC_IDX_SET] = reg; + + return AM18X_OK; +} + +am18x_rt aintc_clear(AINTC_assign_t assign) { + /* + int idx; + + idx = SXXRx_WR_X(assign); + acon->SECRx[idx] = SXXRx_WR_VAL(assign); + */ + uint32_t reg; + + reg = FIELD_SET(0, XIxR_INDEX_MASK, XIxR_INDEX_VAL(assign)); + acon->SIxR[AINTC_IDX_CLR] = reg; + return AM18X_OK; +} + +int32_t aintc_get_active(void) { + int32_t reg; + + reg = acon->HIPIRx[AINTC_IDX_IRQ]; + if (reg < 0) { + return AINTC_INVALID_ACTIVE; + } + return reg; +} diff --git a/lib/am18x-lib/src/am18x_dclk.c b/lib/am18x-lib/src/am18x_dclk.c new file mode 100644 index 000000000..ce820cfc8 --- /dev/null +++ b/lib/am18x-lib/src/am18x_dclk.c @@ -0,0 +1,540 @@ +// tary, 19:05 2013/4/20 +#include "am18x_dclk.h" +#include "auxlib.h" + +static clk_node_t clk_nodes[]; + +#define cfdc_pllx_sysclk_1_3(pll_nr, s_nr) \ +static uint32_t calc_freq_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_PLL##pll_nr##_SYSCLK##s_nr; \ + uint32_t reg = PLL##pll_nr->PLLDIVxA[PLLDIVxA_IDX_##s_nr]; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + \ + if (FIELD_GET(reg, msk) == XXXDIVx_DxEN_disable) { \ + clk_nodes[id].parent = CLK_NODE_INVALID; \ + } else { \ + clk_nodes[id].parent = CLK_NODE_PLL##pll_nr##_PLLEN; \ + } \ + msk = XXXDIVx_RATIO_MASK; \ + clk_nodes[id].divider = 1UL + __field_xget(reg, msk); \ + return 0; \ +} \ +static uint32_t do_change_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_PLL##pll_nr##_SYSCLK##s_nr; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + uint32_t reg, divider; \ + \ + divider = clk_nodes[id].divider; \ + reg = PLL##pll_nr->PLLDIVxA[PLLDIVxA_IDX_##s_nr]; \ + if (clk_nodes[id].parent == CLK_NODE_PLL##pll_nr##_PLLEN) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); \ + } else if (clk_nodes[id].parent == CLK_NODE_INVALID) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_disable); \ + } \ + PLL##pll_nr->PLLDIVxA[PLLDIVxA_IDX_##s_nr] = reg; \ + return 0; \ +} + +#define cfdc_pllx_sysclk_4_7(pll_nr, s_nr) \ +static uint32_t calc_freq_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_PLL##pll_nr##_SYSCLK##s_nr; \ + uint32_t reg = PLL##pll_nr->PLLDIVxB[PLLDIVxB_IDX_##s_nr]; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + \ + if (FIELD_GET(reg, msk) == XXXDIVx_DxEN_disable) { \ + clk_nodes[id].parent = CLK_NODE_INVALID; \ + } else { \ + clk_nodes[id].parent = CLK_NODE_PLL##pll_nr##_PLLEN; \ + } \ + msk = XXXDIVx_RATIO_MASK; \ + clk_nodes[id].divider = 1UL + __field_xget(reg, msk); \ + return 0; \ +} \ +static uint32_t do_change_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_PLL##pll_nr##_SYSCLK##s_nr; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + uint32_t reg, divider; \ + \ + divider = clk_nodes[id].divider; \ + reg = PLL##pll_nr->PLLDIVxB[PLLDIVxB_IDX_##s_nr]; \ + if (clk_nodes[id].parent == CLK_NODE_PLL##pll_nr##_PLLEN) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); \ + } else if (clk_nodes[id].parent == CLK_NODE_INVALID) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_disable); \ + } \ + PLL##pll_nr->PLLDIVxB[PLLDIVxB_IDX_##s_nr] = reg; \ + return 0; \ +} + +#define cfdc_switch(name, cntrl, r, m, vdis, ven, ndis, nen) \ +static uint32_t calc_freq_##name (uint32_t parent) { \ + uint32_t id = CLK_NODE_##name; \ + if (FIELD_GET(XX##cntrl->XX##r,r##_##m) == r##_##vdis ) { \ + clk_nodes[id].parent = CLK_NODE_##ndis; \ + } else { \ + clk_nodes[id].parent = CLK_NODE_##nen; \ + } \ + return 0; \ +} \ +static uint32_t do_change_##name (uint32_t parent) { \ + uint32_t id = CLK_NODE_##name; \ + uint32_t reg = XX##cntrl->XX##r; \ + uint32_t v; \ + if (clk_nodes[id].parent == CLK_NODE_##ndis) { \ + v = r##_##vdis; \ + } else { \ + v = r##_##ven; \ + } \ + XX##cntrl->XX##r = FIELD_SET(reg, r##_##m, v); \ + return 0; \ +} + +#define cfdc_pllx_mult(r, pll_nr) \ +static uint32_t calc_freq_##r##pll_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_##r##pll_nr; \ + uint32_t msk = XXXDIVx_RATIO_MASK; \ + \ + clk_nodes[id].multiplier = 1UL + __field_xget(PLL##pll_nr->XX##r, msk); \ + return 0; \ +} \ +static uint32_t do_change_##r##pll_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_##r##pll_nr; \ + uint32_t msk = XXXDIVx_RATIO_MASK; \ + uint32_t reg, rate; \ + \ + rate = clk_nodes[id].multiplier; \ + reg = PLL##pll_nr->XX##r; \ + PLL##pll_nr->XX##r = FIELD_SET(reg, msk, XXXDIVx_RATIO_WR(rate)); \ + return 0; \ +} + +#define cfdc_pllx_xxxdiv(r, pll_nr, par) \ +static uint32_t calc_freq_##r##pll_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_##r##pll_nr; \ + uint32_t reg = PLL##pll_nr->XX##r; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + \ + if (FIELD_GET(reg, msk) == XXXDIVx_DxEN_disable) { \ + clk_nodes[id].parent = CLK_NODE_INVALID; \ + } else { \ + clk_nodes[id].parent = CLK_NODE_##par; \ + } \ + msk = XXXDIVx_RATIO_MASK; \ + clk_nodes[id].divider = 1UL + __field_xget(reg, msk); \ + return 0; \ +} \ +static uint32_t do_change_##r##pll_nr (uint32_t parent) { \ + uint32_t id = CLK_NODE_##r##pll_nr; \ + uint32_t msk = XXXDIVx_DxEN_MASK; \ + uint32_t reg, divider; \ + \ + divider = clk_nodes[id].divider; \ + reg = PLL##pll_nr->XX##r; \ + if (clk_nodes[id].parent == CLK_NODE_##par) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); \ + } else if (clk_nodes[id].parent == CLK_NODE_INVALID) { \ + reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_disable); \ + } \ + msk = XXXDIVx_RATIO_MASK; \ + reg = FIELD_SET(reg, msk, XXXDIVx_RATIO_WR(divider)); \ + PLL##pll_nr->XX##r = reg; \ + return 0; \ +} + +cfdc_pllx_sysclk_1_3(0,1) +cfdc_pllx_sysclk_1_3(0,2) +cfdc_pllx_sysclk_1_3(0,3) +cfdc_pllx_sysclk_4_7(0,4) +cfdc_pllx_sysclk_4_7(0,5) +cfdc_pllx_sysclk_4_7(0,6) +cfdc_pllx_sysclk_4_7(0,7) +cfdc_pllx_sysclk_1_3(1,1) +cfdc_pllx_sysclk_1_3(1,2) +cfdc_pllx_sysclk_1_3(1,3) +#define XXPLL0 PLL0 +#define XXPLL1 PLL1 +#define XXCKEN CKEN +#define XXPLLCTL PLLCTL +#define XXPREDIV PREDIV +#define XXPLLM PLLM +#define XXPOSTDIV POSTDIV +#define XXOSCDIV OSCDIV +cfdc_switch(PLL0_AUXCLK,PLL0,CKEN,AUXEN_MASK,AUXEN_disable,AUXEN_enable,INVALID,PLL_CLKMODE) +cfdc_switch(PLL0_OBSCLK,PLL0,CKEN,OBSEN_MASK,OBSEN_disable,OBSEN_enable,INVALID,OSCDIV0) +cfdc_switch(PLL1_OBSCLK,PLL1,CKEN,OBSEN_MASK,OBSEN_disable,OBSEN_enable,INVALID,OSCDIV1) +cfdc_switch(PLL0_PLLEN,PLL0,PLLCTL,PLLEN_MASK,PLLEN_no,PLLEN_yes,PLL_EXTSRC,POSTDIV0) +cfdc_switch(PLL1_PLLEN,PLL1,PLLCTL,PLLEN_MASK,PLLEN_no,PLLEN_yes,PLL_CLKMODE,POSTDIV1) +cfdc_switch(PLL_EXTSRC,PLL0,PLLCTL,EXTCLKSRC_MASK,EXTCLKSRC_oscin,EXTCLKSRC_PLL1sysclk3,PLL_CLKMODE,PLL1_SYSCLK3) +#define XXSYSCFG0 SYSCFG0 +#define XXCFGCHIP3 CFGCHIP3 +cfdc_switch(EMA_CLKSRC,SYSCFG0,CFGCHIP3,EMA_CLKSRC_MASK,EMA_CLKSRC_sysclk3,EMA_CLKSRC_pll_out,PLL0_SYSCLK3,DIV4_5X) +cfdc_switch(ASYNC3,SYSCFG0,CFGCHIP3,ASYNC3_CLKSRC_MASK,ASYNC3_CLKSRC_pll0,ASYNC3_CLKSRC_pll1,PLL0_SYSCLK2,PLL1_SYSCLK2) +cfdc_switch(DIV4_5X,SYSCFG0,CFGCHIP3,DIV45PENA_MASK,DIV45PENA_no,DIV45PENA_yes,INVALID,DIV4_5) +cfdc_pllx_mult(PLLM,0) +cfdc_pllx_mult(PLLM,1) +cfdc_pllx_xxxdiv(PREDIV,0,PLL_CLKMODE) +cfdc_pllx_xxxdiv(POSTDIV,0,PLLM0) +cfdc_pllx_xxxdiv(OSCDIV,0,OCSEL0_OCSRC) +cfdc_pllx_xxxdiv(POSTDIV,1,PLLM1) +cfdc_pllx_xxxdiv(OSCDIV,1,OCSEL1_OCSRC) + +static uint32_t calc_freq_OCSEL0_OCSRC (uint32_t parent) { + uint32_t id = CLK_NODE_OCSEL0_OCSRC; + uint32_t par; + + switch (FIELD_GET(PLL0->OCSEL,OCSEL_OCSRC_MASK)) { + case OCSEL_OCSRC_PLLsysclkx(1): + par = CLK_NODE_PLL0_SYSCLK1; + break; + case OCSEL_OCSRC_PLLsysclkx(2): + par = CLK_NODE_PLL0_SYSCLK2; + break; + case OCSEL_OCSRC_PLLsysclkx(3): + par = CLK_NODE_PLL0_SYSCLK3; + break; + case OCSEL_OCSRC_PLLsysclkx(4): + par = CLK_NODE_PLL0_SYSCLK4; + break; + case OCSEL_OCSRC_PLLsysclkx(5): + par = CLK_NODE_PLL0_SYSCLK5; + break; + case OCSEL_OCSRC_PLLsysclkx(6): + par = CLK_NODE_PLL0_SYSCLK6; + break; + case OCSEL_OCSRC_PLLsysclkx(7): + par = CLK_NODE_PLL0_SYSCLK7; + break; + case OCSEL_OCSRC_PLL1obsclk: + par = CLK_NODE_PLL1_OBSCLK; + break; + case OCSEL_OCSRC_oscin: + par = CLK_NODE_PLL_CLKMODE; + break; + case OCSEL_OCSRC_Disabled: + default: + par = CLK_NODE_INVALID; + break; + } + clk_nodes[id].parent = par; + return 0; +} +static uint32_t do_change_OCSEL0_OCSRC (uint32_t parent) { + uint32_t id = CLK_NODE_OCSEL0_OCSRC; + uint32_t v; + + switch (clk_nodes[id].parent) { + case CLK_NODE_PLL0_SYSCLK1: + v = OCSEL_OCSRC_PLLsysclkx(1); + break; + case CLK_NODE_PLL0_SYSCLK2: + v = OCSEL_OCSRC_PLLsysclkx(2); + break; + case CLK_NODE_PLL0_SYSCLK3: + v = OCSEL_OCSRC_PLLsysclkx(3); + break; + case CLK_NODE_PLL0_SYSCLK4: + v = OCSEL_OCSRC_PLLsysclkx(4); + break; + case CLK_NODE_PLL0_SYSCLK5: + v = OCSEL_OCSRC_PLLsysclkx(5); + break; + case CLK_NODE_PLL0_SYSCLK6: + v = OCSEL_OCSRC_PLLsysclkx(6); + break; + case CLK_NODE_PLL0_SYSCLK7: + v = OCSEL_OCSRC_PLLsysclkx(7); + break; + case CLK_NODE_PLL1_OBSCLK: + v = OCSEL_OCSRC_PLL1obsclk; + break; + case CLK_NODE_PLL_CLKMODE: + v = OCSEL_OCSRC_oscin; + break; + case CLK_NODE_INVALID: + default: + v = OCSEL_OCSRC_Disabled; + } + PLL0->OCSEL = FIELD_SET(PLL0->OCSEL, OCSEL_OCSRC_MASK, v); + return 0; +} + +static uint32_t calc_freq_OCSEL1_OCSRC (uint32_t parent) { + uint32_t id = CLK_NODE_OCSEL1_OCSRC; + uint32_t par; + + switch (FIELD_GET(PLL1->OCSEL,OCSEL_OCSRC_MASK)) { + case OCSEL_OCSRC_PLLsysclkx(1): + par = CLK_NODE_PLL1_SYSCLK1; + break; + case OCSEL_OCSRC_PLLsysclkx(2): + par = CLK_NODE_PLL1_SYSCLK2; + break; + case OCSEL_OCSRC_PLLsysclkx(3): + par = CLK_NODE_PLL1_SYSCLK3; + break; + case OCSEL_OCSRC_oscin: + default: + par = CLK_NODE_PLL_CLKMODE; + break; + } + clk_nodes[id].parent = par; + return 0; +} +static uint32_t do_change_OCSEL1_OCSRC (uint32_t parent) { + uint32_t id = CLK_NODE_OCSEL1_OCSRC; + uint32_t v; + + switch (clk_nodes[id].parent) { + case CLK_NODE_PLL1_SYSCLK1: + v = OCSEL_OCSRC_PLLsysclkx(1); + break; + case CLK_NODE_PLL1_SYSCLK2: + v = OCSEL_OCSRC_PLLsysclkx(2); + break; + case CLK_NODE_PLL1_SYSCLK3: + v = OCSEL_OCSRC_PLLsysclkx(3); + break; + case CLK_NODE_PLL_CLKMODE: + default: + v = OCSEL_OCSRC_oscin; + break; + } + PLL1->OCSEL = FIELD_SET(PLL1->OCSEL, OCSEL_OCSRC_MASK, v); + return 0; +} + +#define cnm(name) CLK_NODE_##name, #name +#define cm(name) CLK_NODE_##name +#define cfdc(name) calc_freq_##name, do_change_##name +#define CFMUX CN_FLAG_MUX +#define REREAD CN_FLAG_REREAD +#define CFDC_VALID(flg) ((flg) & (CN_FLAG_MUX | CN_FLAG_REREAD)) +#define RECALC CN_FLAG_RECALC + +static clk_node_t clk_nodes[] = { + // ID PARENT, FLAG, MULT, DIV, CALC_FREQ, DO_CHANGE, PARENT_LIST + { cnm(INVALID), cm(INVALID), 0, 0, 0, }, + { cnm(PLL0_SYSCLK1), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK1), }, + { cnm(PLL0_SYSCLK2), cm(PLL0_PLLEN), REREAD, 0, 2, cfdc(PLL0_SYSCLK2), }, + { cnm(PLL0_SYSCLK3), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK3), }, + { cnm(PLL0_SYSCLK4), cm(PLL0_PLLEN), REREAD, 0, 4, cfdc(PLL0_SYSCLK4), }, + { cnm(PLL0_SYSCLK5), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK5), }, + { cnm(PLL0_SYSCLK6), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK6), }, + { cnm(PLL0_SYSCLK7), cm(PLL0_PLLEN), REREAD, 0, 6, cfdc(PLL0_SYSCLK7), }, + { cnm(EMA_CLKSRC), cm(PLL0_SYSCLK3), CFMUX, 0, 0, cfdc(EMA_CLKSRC), }, + { cnm(PLL0_AUXCLK), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL0_AUXCLK), }, + { cnm(PLL0_OBSCLK), cm(OSCDIV0), CFMUX, 0, 0, cfdc(PLL0_OBSCLK), }, + { cnm(PLL1_SYSCLK1), cm(PLL1_PLLEN), REREAD, 0, 1, cfdc(PLL1_SYSCLK1), }, + { cnm(PLL1_SYSCLK2), cm(PLL1_PLLEN), REREAD, 0, 2, cfdc(PLL1_SYSCLK2), }, + { cnm(PLL1_SYSCLK3), cm(PLL1_PLLEN), REREAD, 0, 3, cfdc(PLL1_SYSCLK3), }, + { cnm(PLL1_OBSCLK), cm(OSCDIV1), CFMUX, 0, 0, cfdc(PLL1_OBSCLK), }, + { cnm(ASYNC3), cm(PLL0_SYSCLK2), CFMUX, 0, 0, cfdc(ASYNC3), }, + { cnm(PLL0_PLLEN), cm(PLL_EXTSRC), CFMUX, 0, 0, cfdc(PLL0_PLLEN), }, + { cnm(PLL_EXTSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL_EXTSRC), }, + { cnm(POSTDIV0), cm(PLLM0), REREAD, 0, 0, cfdc(POSTDIV0), }, + { cnm(PLLM0), cm(PREDIV0), REREAD, 0, 0, cfdc(PLLM0), }, + { cnm(PREDIV0), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PREDIV0), }, + { cnm(PLL_CLKMODE), cm(OSCIN), 0, 1, 0, }, + { cnm(DIV4_5X), cm(DIV4_5), CFMUX, 0, 0, cfdc(DIV4_5X), }, + { cnm(DIV4_5), cm(PLLM0), 0, 2, 9, }, + { cnm(OSCDIV0), cm(OCSEL0_OCSRC),REREAD, 0, 0, cfdc(OSCDIV0), }, + { cnm(OCSEL0_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL0_OCSRC), }, + { cnm(PLL1_PLLEN), cm(POSTDIV1), CFMUX, 0, 0, cfdc(PLL1_PLLEN), }, + { cnm(POSTDIV1), cm(PLLM1), REREAD, 0, 0, cfdc(POSTDIV1), }, + { cnm(PLLM1), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PLLM1), }, + { cnm(OSCDIV1), cm(OCSEL1_OCSRC),REREAD, 0, 0, cfdc(OSCDIV1), }, + { cnm(OCSEL1_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL1_OCSRC), }, + { cnm(OSCIN), cm(INVALID), 0, 0, 0, }, +}; + +am18x_rt clk_node_init(void) { + int i; + + for (i = 0; i < countof(clk_nodes); i++) { + clk_node_t* cni = clk_nodes + i; + + cni->flag |= CN_FLAG_RECALC; + } + return AM18X_OK; +} + +static uint32_t clk_node_calc_freq_inner(uint32_t id) { + uint32_t freq; + clk_node_t* cni = clk_nodes + id; + + #if 0 + printk("%d ", id); + #endif + + if (id == CLK_NODE_INVALID) { + return 0UL; + } + if (id == CLK_NODE_OSCIN) { + return F_OSCIN; + } + if ((cni->flag & CN_FLAG_RECALC) == 0) { + return cni->freq; + } + + if (CFDC_VALID(cni->flag)) { + (cni->calc_freq)(0); + } + + freq = clk_node_calc_freq_inner(cni->parent); + if ((cni->flag & CN_FLAG_MUX) == 0) { + if (cni->multiplier != 0) freq *= cni->multiplier; + if (cni->divider != 0) freq /= cni->divider; + } + + if (cni->flag & CN_FLAG_RECALC) { + cni->flag &= ~CN_FLAG_RECALC; + cni->freq = freq; + } + return freq; +} + +am18x_rt clk_node_recalc(void) { + int i; + + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + clk_node_t* cni = clk_nodes + i; + cni->flag |= CN_FLAG_RECALC; + cni->flag &= ~CN_FLAG_VISITED; + } + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + clk_node_calc_freq_inner(i); + } + return AM18X_OK; +} + +uint32_t clk_node_get_freq(uint32_t id) { + uint32_t freq; + + freq = clk_node_calc_freq_inner(id); + + return freq; +} + +am18x_rt clk_node_output(void) { + #define ONE_MEGA 1000000UL + #define ONE_KILO 1000UL + int i; + + clk_node_recalc(); + + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + uint32_t f = clk_node_get_freq(i); + + printk("[%12s] = ", clk_nodes[i].name); + if (f % ONE_MEGA == 0) { + printk("%10dMhz\n", f / ONE_MEGA); + } else if (f < ONE_MEGA) { + uint32_t frac = f % ONE_KILO; + printk("%6d.%3dKhz\n", f / ONE_KILO, frac); + } else { + uint32_t frac = f % ONE_MEGA / 1000; + printk("%6d.%3dMhz\n", f / ONE_MEGA, frac); + } + } + return AM18X_OK; +} + +static uint32_t clk_node_tree_innner(uint32_t id, int level) { + #define LINE_SIZE 1024 + #define LINE_UNIT 14 + static char line0[LINE_SIZE]; + static char line1[LINE_SIZE]; + uint32_t freq; + am18x_bool found = AM18X_FALSE; + int i; + + freq = clk_node_get_freq(id); + + sprintf(line0 + LINE_UNIT * level, "[%12s]", clk_nodes[id].name); + sprintf(line1 + LINE_UNIT * level, " %4dMhz ", freq / ONE_MEGA); + + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + if (clk_nodes[i].parent == id) { + clk_node_tree_innner(i, level + 1); + found = AM18X_TRUE; + } + } + + if (found) { + return 0; + } + + for (i = level; i >= 0; i--) { + if (line0[i * LINE_UNIT] != '[') { + break; + } + } + if (i >= 0) { + int j = i * LINE_UNIT + LINE_UNIT / 2 + 1; + + line0[j++] = '|'; + for (; j < (i + 1) * LINE_UNIT; j++) { + line0[j] = '_'; + } + } + printk("%s\n", line0); + printk("%s\n", line1); + + for (i = 0; i < level * LINE_UNIT; i++) { + line0[i] = line1[i] = ' '; + } + return 0; +} + +am18x_rt clk_node_tree(void) { + int i; + + clk_node_recalc(); + + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + clk_node_t* cni = clk_nodes + i; + + if (cni->parent != CLK_NODE_INVALID) { + continue; + } + clk_node_tree_innner(i, 0); + } + return AM18X_OK; +} + +static am18x_bool clk_node_set_parent_inner(uint32_t id) { + am18x_bool found = AM18X_FALSE; + int i; + + clk_nodes[id].flag |= CN_FLAG_RECALC; + + for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { + if (clk_nodes[i].parent == id) { + clk_node_set_parent_inner(i); + found = AM18X_TRUE; + } + } + + return found; +} + +am18x_rt clk_node_set_parent(uint32_t id, uint32_t parent) { + clk_node_t* cni = clk_nodes + id; + + if (CFDC_VALID(cni->flag) == 0) { + return AM18X_ERR; + } + + cni->parent = parent; + (cni->do_change)(0); + + clk_node_set_parent_inner(id); + clk_node_calc_freq_inner(id); + return AM18X_OK; +} + +uint32_t dev_get_freq(uint32_t dclk_id) { + uint32_t cn_id = dclk_id / DCLK_ID_GRP_SZ; + + return clk_node_get_freq(cn_id); +} diff --git a/lib/am18x-lib/src/am18x_ddr.c b/lib/am18x-lib/src/am18x_ddr.c new file mode 100644 index 000000000..8e57cbf00 --- /dev/null +++ b/lib/am18x-lib/src/am18x_ddr.c @@ -0,0 +1,264 @@ +// tary, 11:46 2013/12/7 +#include "am18x_ddr.h" +#include "am18x_pll.h" +#include "am18x_psc.h" +#include "am18x_dclk.h" +#include "am18x_syscfg.h" +#include "auxlib.h" + +static pll_conf_t pllconf[1] = { +{ + .pllm = 30, + .prediv = 1, + .postdiv = 2, + .plldiv = { 1, 2, 3, 0, 0, 0, 0, }, + .cflag = 0, +} +}; + +static uint32_t tv2v(uint32_t freq_hz, uint32_t tv_ns) { + uint32_t r; + + r = (freq_hz / 100000 * tv_ns) / 10000; + return r; +} + +am18x_rt ddr_initialize(DDR_con_t* dcon, const ddr_conf_t* conf) { +#define _TV2V(tv) tv2v(mclk, (tv)) + uint32_t mclk, _2x_clk, reg, v; + + // 14.2.13.1 Initializing Following Device Power up or Reset + + // 1. Program PLLC1 registers to start the PLL1_SYSCLK1 + mclk = conf->freq_ck; + if (mclk > 150000000UL) { + mclk = 150000000UL; + } + pllconf->pllm = mclk * 2 * pllconf->postdiv / F_OSCIN; + pll_set_conf(PLL1, pllconf); + clk_node_recalc(); + + // 6.3.2 DDR2/mDDR Memory Controller Clocking + // 2X_CLK is sourced from PLL1_SYSCLK1 + _2x_clk = dev_get_freq(DCLK_ID_DDR2_MDDR_PHY); + + // 2X_CLK clock is again devided down by 2 in the DDR PHY controller + // to generate a clock called MCLK. + mclk = _2x_clk / 2; + printk("DDR CLK: %9d Hz\n", mclk); + + // 2. Program PSC to enable the DDR2/mDDR memory controller clock + psc_state_transition(PSC_DDR2, PSC_STATE_ENABLE); + + // 3. Perform VTP IO calibration + // 4. Set IOPWRDN bit in VTPIO_CTL + // to allow the input receivers to save power + syscfg_vtpio_calibrate(); + + // 5. Configure DRPYC1R + reg = dcon->DRPYC1R; + reg = FIELD_SET(reg, DRPYC1R_EXTSTRBEN_MASK, DRPYC1R_EXTSTRBEN_external); + reg = FIELD_SET(reg, DRPYC1R_PWRDNEN_MASK, DRPYC1R_PWRDNEN_powerdown); + reg = FIELD_SET(reg, DRPYC1R_RL_MASK, DRPYC1R_RL_VAL(conf->cl + 1)); + dcon->DRPYC1R = reg; + + // 6. Configure the DDR_SLEW + syscfg_ddr_slew(conf->ddr2_not_mddr); + + // 7. Set the BOOTUNLOCK bit (unlocked) in the SDCR + reg = dcon->SDCR; + reg = FIELD_SET(reg, SDCR_BOOTUNLOCK_MASK, SDCR_BOOTUNLOCK_unlock); + dcon->SDCR = reg; + + // 8. Program SDCR to the desired value with BOOTUNLOCK bit + // cleared to 0 and TIMUNLOCK bit set to 1 + reg = FIELD_SET(reg, SDCR_BOOTUNLOCK_MASK, SDCR_BOOTUNLOCK_none); + reg = FIELD_SET(reg, SDCR_TIMUNLOCK_MASK, SDCR_TIMUNLOCK_unlock); + reg = FIELD_SET(reg, SDCR_DDR2TERM_MASK, SDCR_DDR2TERM_disable); + reg = FIELD_SET(reg, SDCR_DDRDRIVE_MASK, SDCR_DDRDRIVE_full); + if (conf->ddr2_not_mddr) { + reg = FIELD_SET(reg, SDCR_IBANKPOS_MASK, SDCR_IBANKPOS_normal); + reg = FIELD_SET(reg, SDCR_MSDRAMEN_MASK, SDCR_MSDRAMEN_no); + reg = FIELD_SET(reg, SDCR_DDR2EN_MASK, SDCR_DDR2EN_yes); + } else { + reg = FIELD_SET(reg, SDCR_IBANKPOS_MASK, SDCR_IBANKPOS_normal); + reg = FIELD_SET(reg, SDCR_MSDRAMEN_MASK, SDCR_MSDRAMEN_yes); + reg = FIELD_SET(reg, SDCR_DDR2EN_MASK, SDCR_DDR2EN_no); + } + reg = FIELD_SET(reg, SDCR_DDRDLLDIS_MASK, SDCR_DDRDLLDIS_no); + reg = FIELD_SET(reg, SDCR_DDREN_MASK, SDCR_DDREN_yes); + reg = FIELD_SET(reg, SDCR_SDRAMEN_MASK, SDCR_SDRAMEN_yes); + reg = FIELD_SET(reg, SDCR_NM_MASK, SDCR_NM_16bit); + reg = FIELD_SET(reg, SDCR_CL_MASK, SDCR_CL_VAL(conf->cl)); + switch (conf->bank_cnt) { + case 2: v = SDCR_IBANK_2banks;break; + case 4: v = SDCR_IBANK_4banks;break; + case 8: v = SDCR_IBANK_8banks;break; + default: v = SDCR_IBANK_1bank;break; + } + reg = FIELD_SET(reg, SDCR_IBANK_MASK, v); + switch (conf->page_size) { + case 9: v = SDCR_PAGESIZE_512w9col;break; + case 10: v = SDCR_PAGESIZE_1kw10col;break; + case 11: v = SDCR_PAGESIZE_2kw11col;break; + default: v = SDCR_PAGESIZE_256w8col;break; + } + reg = FIELD_SET(reg, SDCR_PAGESIZE_MASK, v); + + dcon->SDCR = reg; + + // 9. For mDDR only, program the SDCR2 to the desired value + reg = dcon->SDCR2; + if (!conf->ddr2_not_mddr) { + switch (conf->pasr) { + case 2: v = SDCR2_PASR_2banks; break; + case 4: v = SDCR2_PASR_1banks; break; + case 8: v = SDCR2_PASR_half_bank; break; + case 16: v = SDCR2_PASR_quarter_bank; break; + default: v = SDCR2_PASR_4banks; break; + } + reg = FIELD_SET(reg, SDCR2_PASR_MASK, v); + + v = SDCR2_ROWSIZE_VAL(conf->row_size); + reg = FIELD_SET(reg, SDCR2_ROWSIZE_MASK, v); + } + dcon->SDCR2 = reg; + + // 10. Program the SDTIMR1 and SDTIMR2 to + // the desired values to meet the memory data sheet specification + reg = dcon->SDTIMR1; + v = _TV2V(conf->trfc); + reg = __field_xset(reg, SDTIMR1_TRFC_MASK, v); + v = _TV2V(conf->trp); + reg = __field_xset(reg, SDTIMR1_TRP_MASK, v); + v = _TV2V(conf->trcd); + reg = __field_xset(reg, SDTIMR1_TRCD_MASK, v); + v = _TV2V(conf->twr); + reg = __field_xset(reg, SDTIMR1_TWR_MASK, v); + v = _TV2V(conf->tras); + reg = __field_xset(reg, SDTIMR1_TRAS_MASK, v); + v = _TV2V(conf->trc); + reg = __field_xset(reg, SDTIMR1_TRC_MASK, v); + v = _TV2V(conf->trrd); + v += (conf->bank_cnt >= 8)? 1: 0; + reg = __field_xset(reg, SDTIMR1_TRRD_MASK, v); + v = _TV2V(conf->twtr); + reg = __field_xset(reg, SDTIMR1_TWTR_MASK, v); + dcon->SDTIMR1 = reg; + + reg = dcon->SDTIMR2; + v = conf->trasmax / conf->trefi - 1; + reg = __field_xset(reg, SDTIMR2_TRASMAX_MASK, v); + if (conf->txp > conf->tcke) { + reg = __field_xset(reg, SDTIMR2_TXP_MASK, conf->txp - 1); + } else { + reg = __field_xset(reg, SDTIMR2_TXP_MASK, conf->tcke - 1); + } + v = _TV2V(conf->txsnr); + reg = __field_xset(reg, SDTIMR2_TXSNR_MASK, v); + reg = __field_xset(reg, SDTIMR2_TXSRD_MASK, conf->txsrd - 1); + v = _TV2V(conf->trtp); + reg = __field_xset(reg, SDTIMR2_TRTP_MASK, v); + reg = __field_xset(reg, SDTIMR2_TCKE_MASK, conf->tcke - 1); + dcon->SDTIMR2 = reg; + + // 11. Clear TIMUNLOCK bit in SDCR + reg = dcon->SDCR; + reg = FIELD_SET(reg, SDCR_TIMUNLOCK_MASK, SDCR_TIMUNLOCK_none); + dcon->SDCR = reg; + + // 12. Program the SDRCR + reg = dcon->SDRCR; + reg = FIELD_SET(reg, SDRCR_LPMODEN_MASK, SDRCR_LPMODEN_yes); + reg = FIELD_SET(reg, SDRCR_MCLKSTOPEN_MASK, SDRCR_MCLKSTOPEN_yes); + reg = FIELD_SET(reg, SDRCR_SRPD_MASK, SDRCR_SRPD_selfrefresh); + v = _TV2V(conf->trefi); + reg = FIELD_SET(reg, SDRCR_RR_MASK, SDRCR_RR_VAL(v)); + dcon->SDRCR = reg; + + // 13. Program the PSC to reset the DDR2/mDDR memory controller + psc_state_transition(PSC_DDR2, PSC_STATE_SYNC_RESET); + + // 14. Program the PSC to re-enable the DDR2/mDDR memory controller + psc_state_transition(PSC_DDR2, PSC_STATE_ENABLE); + + // 15. Clear LPMODEN and MCLKSTOPEN bits in SDRCR to disable self-refresh + reg = dcon->SDRCR; + reg = FIELD_SET(reg, SDRCR_LPMODEN_MASK, SDRCR_LPMODEN_no); + reg = FIELD_SET(reg, SDRCR_MCLKSTOPEN_MASK, SDRCR_MCLKSTOPEN_no); + dcon->SDRCR = reg; + + // 16. Configure the PBBPR to a value lower than default value of FFh. + reg = dcon->PBBPR; + reg = FIELD_SET(reg, PBBPR_PROLDCOUNT_MASK, PBBPR_PROLDCOUNT_VAL(0x30)); + dcon->PBBPR = reg; + + return AM18X_OK; +} + +#define BYPASS_NOT_POWERDOWN 0 +am18x_rt ddr_clock_off(DDR_con_t* dcon) { + uint32_t reg, v; + + // 14.2.16.1 DDR2/mDDR Memory Controller Clock Stop Procedure + // 1. Allow software to complete the desired DDR transfers + // 2. Change the SR_PD bit to 0 and set the LPMODEN bit to 1 + // in the SDRCR to enable self-refresh mode + reg = dcon->SDRCR; + reg = FIELD_SET(reg, SDRCR_LPMODEN_MASK, SDRCR_LPMODEN_yes); + reg = FIELD_SET(reg, SDRCR_SRPD_MASK, SDRCR_SRPD_selfrefresh); + dcon->SDRCR = reg; + + // 3. Set the MCLKSTOPEN bit in SDRCR to 1 + reg = FIELD_SET(reg, SDRCR_MCLKSTOPEN_MASK, SDRCR_MCLKSTOPEN_yes); + dcon->SDRCR = reg; + + // 4. Wait 150 CPU clock cycles to allow MCLK to stop + for (v = 0; v < 150; v++) asm volatile("nop"); + + // 5. Program the PSC to disable the DDR2/mDDR memory controller VCLK + psc_state_transition(PSC_DDR2, PSC_STATE_DISABLE); + + // 6. For maximum power savings, the PLLC1 should be place in bypass and + // powered-down mode to disable 2X_CLK +#if BYPASS_NOT_POWERDOWN + pll_cmd(PLL1, PLL_CMD_BYPASS, 0); +#else + pll_cmd(PLL1, PLL_CMD_POWER_DOWN, 0); +#endif + clk_node_recalc(); + + return AM18X_OK; +} + +am18x_rt ddr_clock_on(DDR_con_t* dcon) { + uint32_t reg, v; + + // To turn clocks back on + // 1. Place the PLLC1 in PLL mode to start 2X_CLK to the mDDR controller +#if BYPASS_NOT_POWERDOWN + pll_cmd(PLL1, PLL_CMD_UNBYPASS, 0); +#else + pll_set_conf(PLL1, pllconf); +#endif + clk_node_recalc(); + + // 2. Once 2X_CLK is stable, program the PSC to enable VCLK + for (v = 0; v < 150; v++) asm volatile("nop"); + psc_state_transition(PSC_DDR2, PSC_STATE_ENABLE); + + // 3. Set the RESET_PHY bit in the DRPYRCR to 1 + reg = dcon->DRPYRCR; + reg = FIELD_SET(reg, DRPYRCR_RESETPHY_MASK, DRPYRCR_RESETPHY_reset); + dcon->DRPYRCR = reg; + + // 4. Clear the MCLKSTOPEN bit in SDRCR to 0 + reg = dcon->SDRCR; + reg = FIELD_SET(reg, SDRCR_MCLKSTOPEN_MASK, SDRCR_MCLKSTOPEN_no); + dcon->SDRCR = reg; + + // 5. Clear the LPMODEN bit in SDRCR to 0 + reg = FIELD_SET(reg, SDRCR_LPMODEN_MASK, SDRCR_LPMODEN_no); + dcon->SDRCR = reg; + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_ecap.c b/lib/am18x-lib/src/am18x_ecap.c new file mode 100644 index 000000000..86657a67f --- /dev/null +++ b/lib/am18x-lib/src/am18x_ecap.c @@ -0,0 +1,97 @@ +// tary, 20:47 2017/6/20 +#include "am18x_ecap.h" +#include "am18x_dclk.h" + +am18x_rt ecap_init(ECAP_con_t* econ) { + uint32_t v; + + v = econ->ECCTLx[CAPx_ECCTL2]; + v = FIELD_SET(v, ECCTL2_operating_MASK, ECCTL2_operating_APWM); + v = FIELD_SET(v, ECCTL2_APWMPOL_MASK, ECCTL2_APWMPOL_high); + v = FIELD_SET(v, ECCTL2_SYNCI_EN_MASK, ECCTL2_SYNCI_EN_no); + v = FIELD_SET(v, ECCTL2_SYNCO_SEL_MASK, ECCTL2_SYNCO_SEL_disable); + econ->ECCTLx[CAPx_ECCTL2] = v; + + return AM18X_OK; +} + +am18x_rt ecap_get_conf(ECAP_con_t* econ, ecap_conf_t* conf) { + uint32_t dev_freq, r, cmp; + + dev_freq = dev_get_freq(DCLK_ID_ECAPS); + + // CMP >= PERIOD + 1, output high/low always + r = econ->CAPx[CAPx_APRD] + 1; + cmp = econ->CAPx[CAPx_ACMP]; + + conf->freq = dev_freq / r; + + if (cmp >= r) { + conf->duty = 100; + } else { + conf->duty = cmp * 100 / r; + } + + conf->cflags = 0; + r = econ->ECCTLx[CAPx_ECCTL2]; + if (FIELD_GET(r, ECCTL2_APWMPOL_MASK) == ECCTL2_APWMPOL_high) { + conf->cflags |= ECAP_ACTIVE_HIGH; + } else { + conf->cflags |= ECAP_ACTIVE_LOW; + } + + if (FIELD_GET(r, ECCTL2_TSCTRSTOP_MASK) == ECCTL2_TSCTRSTOP_no) { + conf->cflags |= ECAP_ENABLE; + } else { + conf->cflags |= ECAP_DISABLE; + } + + return AM18X_OK; +} + +am18x_rt ecap_set_conf(ECAP_con_t* econ, const ecap_conf_t* conf) { + uint32_t dev_freq, cmp, r, v; + + // stop running + r = econ->ECCTLx[CAPx_ECCTL2]; + r = FIELD_SET(r, ECCTL2_TSCTRSTOP_MASK, ECCTL2_TSCTRSTOP_yes); + econ->ECCTLx[CAPx_ECCTL2] = r; + + dev_freq = dev_get_freq(DCLK_ID_ECAPS); + + // 15.2.2.7 Shadow Load and Lockout Control + // In APWM mode, shadow loading is active and two choices are permitted: + // * Immediate - APRD or ACMP are transferred to CAP1 or CAP2 immediately + // upon writing a new value. + // * On period equal, CTR[31:0] = PRD[31:0] + + // Note: In APWM mode, writing to CAP1/CAP2 active registers also writes + // the same value to the corresponding shadow registers CAP3/CAP4. + // This emulates immediate mode. + // Writting to the shadow registers CAP3/CAP4 invokes the shadow mode. + v = dev_freq / conf->freq; + econ->CAPx[CAPx_APRD] = v - 1; + + if (conf->duty >= 100) { + cmp = v; + } else { + cmp = conf->duty * v / 100; + } + econ->CAPx[CAPx_ACMP] = cmp; + + // active high/low? + r = econ->ECCTLx[CAPx_ECCTL2]; + v = (conf->cflags & ECAP_ACTIVE_HIGH)? ECCTL2_APWMPOL_high: ECCTL2_APWMPOL_low; + r = FIELD_SET(r, ECCTL2_APWMPOL_MASK, v); + + // econ->ECCTLx[CAPx_ECCTL2] = r; + // r = econ->ECCTLx[CAPx_ECCTL2]; + + // start running ? + if (conf->cflags & ECAP_ENABLE) { + r = FIELD_SET(r, ECCTL2_TSCTRSTOP_MASK, ECCTL2_TSCTRSTOP_no); + } + econ->ECCTLx[CAPx_ECCTL2] = r; + + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_edma.c b/lib/am18x-lib/src/am18x_edma.c new file mode 100644 index 000000000..b3ca42abb --- /dev/null +++ b/lib/am18x-lib/src/am18x_edma.c @@ -0,0 +1,303 @@ +// tary, 22:38 2013/6/5 +#include "am18x_edma.h" +#include "auxlib.h" + +static EDMA3CC_rgn_t* region_2_reg(EDMA3CC_con_t* ccon, int region) { + if (ccon == NULL) { + return NULL; + } + switch (region) { + case REGION_0: + return &ccon->Region0; + break; + case REGION_1: + return &ccon->Region1; + break; + case REGION_GLOBAL: + default: + break; + } + return &ccon->Global; +} + +static am18x_bool is_qchannel(const edma_conf_t* conf) { + switch (conf->trigger) { + case QDMA_AUTO_TRIGGERED: + //case QDMA_LINK_TRIGGERED: + break; + case DMA_EVENT_TRIGGERED: + case DMA_MANUALLY_TRIGGERED: + //case DMA_CHAIN_TRIGGERED: + return AM18X_FALSE; + break; + } + return AM18X_TRUE; +} + +static am18x_bool is_null_pa_entry(const pa_conf_t* pa) { + if (pa->a_cnt == 0 && pa->b_cnt == 0 && pa->c_cnt == 0) { + return AM18X_TRUE; + } + return AM18X_FALSE; +} + +static am18x_bool is_dummy_pa_entry(const pa_conf_t* pa) { + if ((pa->a_cnt == 0 || pa->b_cnt == 0 || pa->c_cnt == 0) + && (pa->a_cnt != 0 || pa->b_cnt != 0 || pa->c_cnt != 0) + ) { + return AM18X_TRUE; + } + return AM18X_FALSE; +} + +am18x_rt edma_init(EDMA_con_t* econ, const edma_conf_t* conf) { + uint32_t v, ch; + EDMA3CC_con_t* ccon = &econ->CC; + EDMA3CC_rgn_t* rgn; + + ch = conf->channel; + if (is_qchannel(conf)) { + v = ccon->QCHMAPx[ch]; + v = __field_xset(v, QCHMAP_PAENTRY_MASK, conf->pa_conf[0].index); + v = __field_xset(v, QCHMAP_TRWORD_MASK, conf->tr_word); + ccon->QCHMAPx[ch] = v; + } + + rgn = region_2_reg(ccon, conf->region); + + if (conf->region != REGION_GLOBAL) { + if (is_qchannel(conf)) { + v = ccon->QRAEx[conf->region]; + v = FIELD_SET(v, QRAE_En_MASK(ch), QRAE_En_allow(ch)); + ccon->QRAEx[conf->region] = v; + } else { + v = ccon->DRAEx[DRAE_IDX(conf->region)]; + v = FIELD_SET(v, DRAE_En_MASK(ch), DRAE_En_allow(ch)); + ccon->DRAEx[DRAE_IDX(conf->region)] = v; + } + } + + switch(conf->trigger) { + case DMA_EVENT_TRIGGERED: + case DMA_MANUALLY_TRIGGERED: + rgn->EESR = FIELD_SET(0, EExR_En_MASK(ch), EExR_En_set(ch)); + break; + case QDMA_AUTO_TRIGGERED: + break; + //case DMA_CHAIN_TRIGGERED: + //case QDMA_LINK_TRIGGERED: + // break; + } + + if (econ == EDMA0) { + if (is_qchannel(conf)) { + v = ccon->QDMAQNUM; + v = __field_xset(v, QDMAQNUM_En_MASK(ch), conf->queue); + ccon->QDMAQNUM = v; + } else { + v = ccon->DMAQNUMx[DMAQNUM_IDX(ch)]; + v = __field_xset(v, DMAQNUM_En_MASK(ch), conf->queue); + ccon->DMAQNUMx[DMAQNUM_IDX(ch)] = v; + } + } + + return AM18X_OK; +} + +am18x_rt edma_param(EDMA_con_t* econ, const edma_conf_t* conf) { + EDMA3CC_con_t* ccon = &econ->CC; + PaRAM_entry_t* pa_regs = ccon->PAEntry; + PaRAM_entry_t pa_entry[1]; + pa_conf_t* pa; + uint32_t v; + int i; + + pa = conf->pa_conf; + for (i = 0; i < conf->pa_cnt; i++, pa++) { + v = OPT_SAM_INCR | OPT_DAM_INCR | OPT_FWID_32b | + OPT_ITCCHEN_no | OPT_TCCHEN_no | OPT_ITCINTEN_no | OPT_TCINTEN_no | + OPT_STATIC_no | OPT_SYNCDIM_Async | OPT_TCCMODE_Normal; + v = FIELD_SET(v, OPT_PRIVID_MASK, OPT_PRIVID_X(pa->priv_id)); + v = FIELD_SET(v, OPT_TCC_MASK, OPT_TCC_X(pa->tcc)); + if (pa->flags & FLAG_TRANS_EVT) { + v = FIELD_SET(v, OPT_ITCCHEN_MASK, OPT_ITCCHEN_yes); + v = FIELD_SET(v, OPT_TCCHEN_MASK, OPT_TCCHEN_yes); + } + if (pa->flags & FLAG_TRANS_INTR) { + // v = FIELD_SET(v, OPT_ITCINTEN_MASK, OPT_ITCINTEN_yes); + v = FIELD_SET(v, OPT_TCINTEN_MASK, OPT_TCINTEN_yes); + } + if (pa->flags & FLAG_TCC_EARLY) { + v = FIELD_SET(v, OPT_TCCMODE_MASK, OPT_TCCMODE_Early); + } + if (pa->flags & FLAG_LAST_PAENTRY) { + v = FIELD_SET(v, OPT_STATIC_MASK, OPT_STATIC_yes); + } + if (pa->flags & FLAG_SYNCTYPE_AB) { + v = FIELD_SET(v, OPT_SYNCDIM_MASK, OPT_SYNCDIM_ABsync); + } + pa_entry->OPT = v; + + pa_entry->SRC = pa->src; + + v = __field_xset(0, PARAM_ACNT_MASK, pa->a_cnt); + v = __field_xset(v, PARAM_BCNT_MASK, pa->b_cnt); + pa_entry->A_B_CNT = v; + + pa_entry->DST = pa->dst; + + v = __field_xset(0, PARAM_SRCBIDX_MASK, pa->src_b_idx); + v = __field_xset(v, PARAM_DSTBIDX_MASK, pa->dst_b_idx); + pa_entry->SRC_DST_BIDX = v; + + v = __field_xset(0, PARAM_LINK_MASK, pa->link); + if ((pa->flags & FLAG_SYNCTYPE_AB) == 0) { + v = __field_xset(v, PARAM_BCNTRLD_MASK, pa->b_cnt); + } + pa_entry->LINK_BCNTRLD = v; + + v = __field_xset(0, PARAM_SRCCIDX_MASK, pa->src_c_idx); + v = __field_xset(v, PARAM_DSTCIDX_MASK, pa->dst_c_idx); + pa_entry->SRC_DST_CIDX = v; + + v = __field_xset(0, PARAM_CCNT_MASK, pa->c_cnt); + pa_entry->CCNT = v; + + pa_regs[pa->index] = *pa_entry; + + // printk("\n¶m0 = 0x%.8X\n", &pa_regs[pa->index]); + // dump_regs_word("pa_orig", (int)pa_entry, sizeof *pa_entry); + } + return AM18X_OK; +} + +am18x_rt edma_interrupt(EDMA_con_t* econ, const edma_conf_t* conf) { + EDMA3CC_con_t* ccon = &econ->CC; + EDMA3CC_rgn_t* rgn; + pa_conf_t* pa; + uint32_t msk; + int i; + + rgn = region_2_reg(ccon, conf->region); + + pa = conf->pa_conf; + for (i = 0; i < conf->pa_cnt; i++, pa++) { + if (pa->flags & FLAG_TRANS_INTR) { + if (conf->region != REGION_GLOBAL && pa->tcc != conf->channel) { + uint32_t v; + + v = ccon->DRAEx[DRAE_IDX(conf->region)]; + v = FIELD_SET(v, DRAE_En_MASK(pa->tcc), DRAE_En_allow(pa->tcc)); + ccon->DRAEx[DRAE_IDX(conf->region)] = v; + } + msk = IExR_En_MASK(pa->tcc); + rgn->IESR = FIELD_SET(0, msk, IExR_En_set(pa->tcc)); + } + + if (pa->flags & FLAG_TRANS_EVT) { + msk = EExR_En_MASK(pa->tcc); + rgn->EESR = FIELD_SET(0, msk, EExR_En_set(pa->tcc)); + } + } + return AM18X_OK; +} + +am18x_rt edma_transfer(EDMA_con_t* econ, const edma_conf_t* conf) { + EDMA3CC_con_t* ccon = &econ->CC; + PaRAM_entry_t* pa_regs = ccon->PAEntry; + EDMA3CC_rgn_t* rgn; + vuint32_t* tr_p; + uint32_t ch; + + rgn = region_2_reg(ccon, conf->region); + + rgn->SECR = rgn->SER; + + ch = conf->channel; + if (conf->trigger == QDMA_AUTO_TRIGGERED) { + rgn->QEESR = FIELD_SET(0, QEExR_En_MASK(ch), QEExR_En_set(ch)); + + tr_p = (vuint32_t*)&pa_regs[conf->pa_conf[0].index]; + tr_p += conf->tr_word; + // trigger the transfer by writing the tr_word in param set + *tr_p = *tr_p; + } else if (conf->trigger == DMA_MANUALLY_TRIGGERED) { + rgn->ESR = FIELD_SET(0, ExR_En_MASK(ch), ExR_En_set(ch)); + } + return AM18X_OK; +} + +am18x_rt edma_completed(EDMA_con_t* econ, const edma_conf_t* conf) { + EDMA3CC_con_t* ccon = &econ->CC; + EDMA3CC_rgn_t* rgn; + pa_conf_t* pa; + uint32_t msk; + int i; + + rgn = region_2_reg(ccon, conf->region); + + pa = conf->pa_conf; + for (i = 0; i < conf->pa_cnt; i++, pa++) { + #if 0 + if ((pa->flags & FLAG_LAST_PAENTRY) == 0) { + continue; + } + #endif + if ((pa->flags & FLAG_TRANS_INTR) == 0) { + continue; + } + msk = IxR_En_MASK(pa->tcc); + if (FIELD_GET(rgn->IPR, msk) == IxR_En_none(pa->tcc)) { + return AM18X_ERR; + } + } + + // clear pending bits in IPR + rgn->ICR = rgn->IPR; + + return AM18X_OK; +} + +am18x_rt edma_status(const EDMA_con_t* econ, edma_stat_t* stat) { + static int bit_nrs[] = {0, 1, 2, 3, 4, 16, 17, -1}; + static char* inner_status[] = { + "DMA event active", + "QDMA event active", + "transfer request active", + "write status active", + "channel controller active", + "Queue 0 active", + "Queue 1 active", + "none", + }; + uint32_t ccstat; + int i; + + ccstat = econ->CC.CCSTAT; + if (FIELD_GET(ccstat, 0x0003001FUL) == 0) { + return AM18X_ERR; + } + + if (stat == NULL) { + return AM18X_OK; + } + + stat->comp_actv = __field_xget(ccstat, CCSTAT_COMPACTV_MASK); + stat->queue_evts[0] = __field_xget(econ->CC.QSTATx[0], QSTAT_NUMVAL_MASK); + if (econ == EDMA0) { + stat->queue_evts[1] = __field_xget(econ->CC.QSTATx[1], QSTAT_NUMVAL_MASK); + } else { + stat->queue_evts[1] = 0; + } + + for (i = 0; bit_nrs[i] != -1; i++) { + if (FIELD_GET(ccstat, BIT(bit_nrs[i])) != 0) { + stat->status[i] = inner_status[i]; + } else { + stat->status[i] = "none"; + } + } + + stat->status[i] = NULL; + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_gpio.c b/lib/am18x-lib/src/am18x_gpio.c new file mode 100644 index 000000000..f56448d1d --- /dev/null +++ b/lib/am18x-lib/src/am18x_gpio.c @@ -0,0 +1,242 @@ +// tary, 0:56 2013/4/26 +#include "am18x_gpio.h" +#include "am18x_syscfg.h" + +#define gcon GPIOCON +#define reg_and_of(ra, rb) \ + uint32_t reg, of; \ + of = reg_offset(bank) + pin; \ + reg = gcon->BANKS[pair_nr(bank)]. ra##rb + + +static inline int pair_nr(gpio_bank_t bank) { + return (bank / 2); +} + +static inline int reg_offset(gpio_bank_t bank) { + if (bank & 0x01UL) { + return 16; + } + return 0; +} + +am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir) { + uint32_t mux, pos, val; + + mux = (uint32_t)-1; + pos = 0; + val = 8; + // PINMUX00[7..0] = (GP0[8..15], value = 8) + // PINMUX01[7..0] = (GP0[0..7], value = 8) + if (bank == GPIO_BANK0) { + if (pin < GPIO_PIN_8) { + mux = 1; + pos = GPIO_PIN_7 - pin; + } else { + mux = 0; + pos = GPIO_PIN_15 - pin; + } + } + if (bank == GPIO_BANK1) { + // PINMUX02[0..0] = (GP1[15], value = 8) + if (pin == GPIO_PIN_15) { + mux = 2; + pos = 0; + } else + // PINMUX02[6..1] = (GP1[9..14], value = 4) + if (GPIO_PIN_9 <= pin && pin <= GPIO_PIN_14) { + mux = 2; + pos = GPIO_PIN_15 - pin; + val = 4; + } else + // PINMUX03[0..0] = (GP1[8], value = 4) + if (pin == GPIO_PIN_8) { + mux = 3; + pos = 0; + val = 4; + } else + // PINMUX04[7..0] = (GP1[0..7], value = 4) + if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_7) { + mux = 4; + pos = GPIO_PIN_7 - pin; + val = 4; + } + } + // PINMUX05[7..0] = (GP2[8..15], value = 8) + // PINMUX06[7..0] = (GP2[0..7], value = 8) + if (bank == GPIO_BANK2) { + if (pin < GPIO_PIN_8) { + mux = 6; + pos = GPIO_PIN_7 - pin; + } else { + mux = 5; + pos = GPIO_PIN_15 - pin; + } + } + // PINMUX07[7..0] = (GP3[8..15], value = 8) + // PINMUX08[7..0] = (GP3[0..7], value = 8) + if (bank == GPIO_BANK3) { + if (pin < GPIO_PIN_8) { + mux = 8; + pos = GPIO_PIN_7 - pin; + } else { + mux = 7; + pos = GPIO_PIN_15 - pin; + } + } + // PINMUX09[7..0] = (GP4[8..15], value = 8) + // PINMUX10[7..0] = (GP4[0..7], value = 8) + if (bank == GPIO_BANK4) { + if (pin < GPIO_PIN_8) { + mux = 10; + pos = GPIO_PIN_7 - pin; + } else { + mux = 9; + pos = GPIO_PIN_15 - pin; + } + } + // PINMUX11[7..0] = (GP5[8..15], value = 8) + // PINMUX12[7..0] = (GP5[0..7], value = 8) + if (bank == GPIO_BANK5) { + if (pin < GPIO_PIN_8) { + mux = 12; + pos = GPIO_PIN_7 - pin; + } else { + mux = 11; + pos = GPIO_PIN_15 - pin; + } + } + if (bank == GPIO_BANK6) { + // PINMUX13[7..0] = (GP6[8..15], value = 8) + if (GPIO_PIN_8 <= pin && pin <= GPIO_PIN_15) { + mux = 13; + pos = GPIO_PIN_15 - pin; + } else + // PINMUX14[1..0] = (GP6[6..7], value = 8) + if (GPIO_PIN_6 <= pin && pin <= GPIO_PIN_7) { + mux = 14; + pos = GPIO_PIN_7 - pin; + } else + // PINMUX16[1..1] = (GP6[5], value = 8) + if (GPIO_PIN_5 <= pin && pin <= GPIO_PIN_5) { + mux = 16; + pos = GPIO_PIN_6 - pin; + } else + // PINMUX19[6..2] = (GP6[0..4], value = 8) + if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_4) { + mux = 19; + pos = GPIO_PIN_6 - pin; + } + } + if (bank == GPIO_BANK7) { + // PINMUX16[7..2] = (GP7[10..15], value = 8) + if (GPIO_PIN_10 <= pin && pin <= GPIO_PIN_15) { + mux = 16; + pos = 17 - pin; + } else + // PINMUX17[7..0] = (GP7[2..9], value = 8) + if (GPIO_PIN_2 <= pin && pin <= GPIO_PIN_9) { + mux = 17; + pos = GPIO_PIN_9 - pin; + } else + // PINMUX18[1..0] = (GP7[0..1], value = 8) + if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_1) { + mux = 18; + pos = GPIO_PIN_1 - pin; + } + } + if (bank == GPIO_BANK8) { + // PINMUX18[7..2] = (GP8[10..15], value = 8) + if (GPIO_PIN_10 <= pin && pin <= GPIO_PIN_15) { + mux = 18; + pos = 17 - pin; + } else + // PINMUX19[1..0] = (GP8[8..9], value = 8) + if (GPIO_PIN_8 <= pin && pin <= GPIO_PIN_9) { + mux = 19; + pos = GPIO_PIN_9 - pin; + } else + // PINMUX02[7..7] = (GP8[7], value = 4) + if (GPIO_PIN_7 <= pin && pin <= GPIO_PIN_7) { + mux = 2; + pos = pin; + val = 4; + } else + // PINMUX03[7..2] = (GP8[1..6], value = 4) + if (GPIO_PIN_1 <= pin && pin <= GPIO_PIN_6) { + mux = 3; + pos = GPIO_PIN_8 - pin; + val = 4; + } else + // PINMUX19[7..7] = (GP8[0], value = 8) + if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_0) { + mux = 19; + pos = GPIO_PIN_7 - pin; + } + } + + if (mux == (uint32_t)-1) { + return AM18X_ERR; + } + + syscfg_pinmux(mux, pos << 2, val); + + { + reg_and_of(D,IR); + gcon->BANKS[pair_nr(bank)].DIR = __field_xset(reg, XXX_GPkPj_MASK(of), + (dir == GPIO_DIR_INPUT)? DIR_GPkPj_input(0): DIR_GPkPj_output(0)); + } + return AM18X_OK; +} + +gpio_level_t gpio_get_input1(gpio_bank_t bank, gpio_pin_t pin) { + reg_and_of(IN,_DATA); + + if (FIELD_GET(reg, XXX_GPkPj_MASK(of)) == IN_DATA_GPkPj_low(of)) { + return GPIO_LOW; + } + return GPIO_HIGH; +} + +am18x_rt gpio_set_output1(gpio_bank_t bank, gpio_pin_t pin, gpio_level_t level) { + reg_and_of(OUT,_DATA); + + gcon->BANKS[pair_nr(bank)].OUT_DATA = __field_xset(reg, XXX_GPkPj_MASK(of), + (level == GPIO_LOW)? OUT_DATA_GPkPj_low(0): OUT_DATA_GPkPj_high(0)); + return AM18X_OK; +} + +gpio_level_t gpio_get_output1(gpio_bank_t bank, gpio_pin_t pin) { + reg_and_of(OUT,_DATA); + + if (FIELD_GET(reg, XXX_GPkPj_MASK(of)) == IN_DATA_GPkPj_low(of)) { + return GPIO_LOW; + } + return GPIO_HIGH; +} + +gpio_pins_t gpio_get_inputs(gpio_bank_t bank, gpio_pins_t pins) { + uint32_t reg, of = reg_offset(bank); + + reg = gcon->BANKS[pair_nr(bank)].IN_DATA; + reg = FIELD_GET(reg, pins << of); + return reg >> of; +} + +am18x_rt gpio_set_outputs(gpio_bank_t bank, gpio_pins_t pins, gpio_pins_t levels) { + uint32_t reg, of = reg_offset(bank); + + pins <<= of; + levels <<= of; + reg = gcon->BANKS[pair_nr(bank)].OUT_DATA; + gcon->BANKS[pair_nr(bank)].OUT_DATA = FIELD_SET(reg, pins, levels); + return AM18X_OK; +} + +gpio_pins_t gpio_get_outputs(gpio_bank_t bank, gpio_pins_t pins) { + uint32_t reg, of = reg_offset(bank); + + reg = gcon->BANKS[pair_nr(bank)].OUT_DATA; + reg = FIELD_GET(reg, pins << of); + return reg >> of; +} diff --git a/lib/am18x-lib/src/am18x_i2c.c b/lib/am18x-lib/src/am18x_i2c.c new file mode 100644 index 000000000..95ac69612 --- /dev/null +++ b/lib/am18x-lib/src/am18x_i2c.c @@ -0,0 +1,272 @@ +// tary, 22:02 2013/3/13 +#include "am18x_i2c.h" +#include "am18x_dclk.h" + +// 22.2.2 Clock Generation +#define PrescaledModuleClockLow (6700000UL) +#define PrescaledModuleClockHigh (13300000UL) + +// static inline +uint32_t i2c_input_freq(I2C_con_t* icon) { + if (icon == I2C0) { + return dev_get_freq(DCLK_ID_I2C0); + } + if (icon == I2C1) { + return dev_get_freq(DCLK_ID_I2C1); + } + return 0UL; +} + +static inline uint32_t ipsc_to_d(uint32_t ipsc) { + uint32_t d; + + if (ipsc == 0) { + d = 7; + } else if (ipsc == 1) { + d = 6; + } else { + d = 5; + } + return d; +} + +uint32_t i2c_get_serial_clock(I2C_con_t* icon) { + uint32_t freq, scale_freq, ipsc, divider; + + freq = i2c_input_freq(icon); + + ipsc = FIELD_XGET(icon->ICPSC, ICPSC_IPSC_MASK); + + divider = (ipsc_to_d(ipsc) << 1); + divider += FIELD_XGET(icon->ICCLKL, ICCLKL_MASK); + divider += FIELD_XGET(icon->ICCLKH, ICCLKH_MASK); + + scale_freq = freq / (ipsc + 1); + + return scale_freq / divider; +} + +#define I2C_RESET(ic) { ic->ICMDR = FIELD_SET(ic->ICMDR, ICMDR_IRS_MASK, ICMDR_IRS_reset); } +#define I2C_UNRESET(ic) { ic->ICMDR = FIELD_SET(ic->ICMDR, ICMDR_IRS_MASK, ICMDR_IRS_none); } + +am18x_rt i2c_set_serial_clock(I2C_con_t* icon, uint32_t freq) { + uint32_t ipsc, scale_freq; + // uint32_t msk; + + if (icon == I2C0) { + ipsc = 1; + } else { + ipsc = 0; + } + + scale_freq = i2c_input_freq(icon) / (ipsc + 1); + + // msk = ICMDR_IRS_MASK; + // icon->ICMDR = FIELD_SET(icon->ICMDR, msk, ICMDR_IRS_reset); + + icon->ICPSC = FIELD_SET(0, ICPSC_IPSC_MASK, ICPSC_IPSC_VAL(ipsc)); + + // 22.2.2 Clock Generation + // I2C serial clock frequency = prescaled module clock frequency + // / ( ICCL + d ) + ( ICCH + d ) + icon->ICCLKL = scale_freq / (freq * 2) - ipsc_to_d(ipsc); + icon->ICCLKH = icon->ICCLKL; + + // icon->ICMDR = FIELD_SET(icon->ICMDR, msk, ICMDR_IRS_none); + + return AM18X_OK; +} + +am18x_rt i2c_conf(I2C_con_t* icon, i2c_conf_t* conf) { + uint32_t reg, msk, v; + + // 22.2.11.1 Configuring the I2C in Master Receiver Mode + // and Servicing Receive Data via CPU + + // 1. Enable I2C Clock from Power and Sleep Controller, + // if it is driven by the Power and Sleep Controller + + // 2. Place I2C in reset + I2C_RESET(icon); + + // 3. Configure ICMDR + reg = icon->ICMDR; + msk = v = 0; + + // Configure I2C as Master + msk |= ICMDR_MST_MASK; + if (conf->opermode == I2C_OPERMODE_Master_receiver + || conf->opermode == I2C_OPERMODE_Master_transmitter) { + v |= ICMDR_MST_master; + } else { + v |= ICMDR_MST_slave; + } + + // Indicate the I2C configuration to be used + msk |= ICMDR_TRX_MASK; + if (conf->opermode == I2C_OPERMODE_Slave_transmitter + || conf->opermode == I2C_OPERMODE_Master_transmitter) { + v |= ICMDR_TRX_transmitter; + } else { + v |= ICMDR_TRX_receiver; + } + + // Indicate 7-bit addressing is to be used + msk |= ICMDR_XA_MASK; + if (conf->bitmode == I2C_BITMODE_7BIT) { + v |= ICMDR_XA_7bit; + } else if (conf->bitmode == I2C_BITMODE_10BIT) { + v |= ICMDR_XA_10bit; + } + + // Disable repeat mode + msk |= ICMDR_RM_MASK; + v |= ICMDR_RM_no; + + // Disable loopback mode + msk |= ICMDR_DLB_MASK; + v |= ICMDR_DLB_disable; + + // Disable free data format + msk |= ICMDR_FDF_MASK; + if (conf->bitmode == I2C_BITMODE_FreeDataFormat) { + v |= ICMDR_FDF_yes; + } else { + v |= ICMDR_FDF_no; + } + + // Disable start byte mode + // if addressing a fully fledged I2C device + msk |= ICMDR_STB_MASK; + v |= ICMDR_STB_no; + + // Set number of bits to fransfer to be 8 bits + msk |= ICMDR_BC_MASK; + v |= ICMDR_BC_VAL(8); + + icon->ICMDR = FIELD_SET(reg, msk, v); + + // 4. Configure Slave Address: the I2C device + // this I2C master would be addressing + if (conf->opermode == I2C_OPERMODE_Master_receiver + || conf->opermode == I2C_OPERMODE_Master_transmitter) { + msk = ICSAR_SADDR_MASK; + icon->ICSAR = FIELD_SET(0, msk, ICSAR_SADDR_VAL(conf->addr)); + } else { + // Set i2c own address, if it's as slave device + msk = ICOAR_OADDR_MASK; + icon->ICOAR = FIELD_SET(0, msk, ICOAR_OADDR_VAL(conf->addr)); + } + + // 5. Configure the peripheral clock operation frequency. + // 6. Configure I2C master clock frequency + i2c_set_serial_clock(icon, conf->freq); + + // 7. Make sure the interrupt status register (ICSTR) is cleared + icon->ICSTR = icon->ICSTR; + while (icon->ICIVR != 0); + + // 8. Take I2C controller out of reset + I2C_UNRESET(icon); + + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_FREE_MASK, ICMDR_FREE_run); + + return AM18X_OK; +} + +am18x_rt i2c_cmd(I2C_con_t* icon, uint32_t cmd, uint32_t arg) { + uint32_t reg; + + switch (cmd) { + case I2C_CMD_WAIT_FREE: + // 9. Wait until bus busy bit is cleared + while (FIELD_GET(icon->ICSTR, ICSTR_BB_MASK) != ICSTR_BB_free); + break; + + case I2C_CMD_WAIT_BUSY: + while (FIELD_GET(icon->ICSTR, ICSTR_BB_MASK) != ICSTR_BB_busy); + break; + + case I2C_CMD_WAIT_SLAVE: + while (FIELD_GET(icon->ICMDR, ICMDR_MST_MASK) != ICMDR_MST_slave); + break; + + case I2C_CMD_WAIT_ARDY: + while (FIELD_GET(icon->ICSTR, ICSTR_ARDY_MASK) != ICSTR_ARDY_ready); + break; + + case I2C_CMD_BUS_START: + // 10. Generate a START event, followed by Slave Address, etc. + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_STT_MASK, ICMDR_STT_yes); + break; + + case I2C_CMD_WAIT_RX: + // 11. Wait until data is received + while (FIELD_GET(icon->ICSTR, ICSTR_ICRRDY_MASK) != ICSTR_ICRRDY_ready); + break; + + case I2C_CMD_WAIT_TX: + while (FIELD_GET(icon->ICSTR, ICSTR_ICXRDY_MASK) != ICSTR_ICXRDY_ready); + break; + + case I2C_CMD_CLR_RX: + icon->ICSTR = FIELD_SET(icon->ICSTR, ICSTR_ICRRDY_MASK, ICSTR_ICRRDY_clear); + break; + + case I2C_CMD_CLR_TX: + icon->ICSTR = FIELD_SET(icon->ICSTR, ICSTR_ICXRDY_MASK, ICSTR_ICXRDY_clear); + break; + + case I2C_CMD_BUS_NACK: + // 13. Configure the I2C controller not to generate an ACK on + // the next/final byte reception + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_NACKMOD_MASK, ICMDR_NACKMOD_yes); + break; + + case I2C_CMD_BUS_STOP: + // 14. End transer/release bus when transfer is done. + // Generate a STOP event + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_STP_MASK, ICMDR_STP_yes); + break; + + case I2C_CMD_SET_CNT: + icon->ICCNT = FIELD_SET(0, ICCNT_MASK, arg); + break; + + case I2C_CMD_SET_REPEAT: + I2C_RESET(icon); + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_RM_MASK, ICMDR_RM_yes); + I2C_UNRESET(icon); + break; + + case I2C_CMD_CLR_REPEAT: + I2C_RESET(icon); + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_RM_MASK, ICMDR_RM_no); + I2C_UNRESET(icon); + break; + + case I2C_CMD_TRANSMITTER: + I2C_RESET(icon); + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_TRX_MASK, ICMDR_TRX_transmitter); + I2C_UNRESET(icon); + break; + + case I2C_CMD_RECEIVER: + I2C_RESET(icon); + reg = icon->ICMDR; + icon->ICMDR = FIELD_SET(reg, ICMDR_TRX_MASK, ICMDR_TRX_receiver); + I2C_UNRESET(icon); + break; + + default: + break; + } + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_lcd.c b/lib/am18x-lib/src/am18x_lcd.c new file mode 100644 index 000000000..6fe44ba7a --- /dev/null +++ b/lib/am18x-lib/src/am18x_lcd.c @@ -0,0 +1,328 @@ +// tary, 22:33 2015/4/4 +#include "am18x_lcd.h" +#include "am18x_dclk.h" +#include "auxlib.h" + +#define WIDTH_2_PPL(w) (((w) >> 4) - 1) + +static am18x_rt lcd_set_pclk(LCD_con_t* lcon, uint32_t freq) { + uint32_t lcd_clk; + uint32_t reg, v; + + lcd_clk = dev_get_freq(DCLK_ID_LCDC); + printk("LCD_CLK = %d\n", lcd_clk); + v = lcd_clk / freq; + + reg = lcon->LCD_CTRL; + lcon->LCD_CTRL = __field_xset(reg, LCD_CTRL_CLKDIV_MASK, v); + return AM18X_OK; +} + +am18x_rt lcd_conf(LCD_con_t* lcon, const lcd_conf_t* conf) { + uint32_t reg, msk, v; + + // disable raster controller + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_EN_MASK, RASTER_CTRL_EN_no); + lcon->RASTER_CTRL = reg; + + reg = lcon->LCD_CTRL; + v = LCD_CTRL_MODESEL_Raster; + lcon->LCD_CTRL = FIELD_SET(reg, LCD_CTRL_MODESEL_MASK, v); + + lcd_set_pclk(lcon, conf->pclk); + + reg = lcon->RASTER_TIMING_0; + reg = __field_xset(reg, RT0_HFP_MASK, conf->hfp - 1); + reg = __field_xset(reg, RT0_HBP_MASK, conf->hbp - 1); + reg = __field_xset(reg, RT0_HSW_MASK, conf->hsw - 1); + reg = __field_xset(reg, RT0_PPL_MASK, WIDTH_2_PPL(conf->width)); + lcon->RASTER_TIMING_0 = reg; + + reg = lcon->RASTER_TIMING_1; + reg = __field_xset(reg, RT1_VFP_MASK, conf->vfp - 1); + reg = __field_xset(reg, RT1_VBP_MASK, conf->vbp - 1); + reg = __field_xset(reg, RT1_VSW_MASK, conf->vsw - 1); + reg = __field_xset(reg, RT1_LPP_MASK, conf->height - 1); + lcon->RASTER_TIMING_1 = reg; + + reg = lcon->RASTER_TIMING_2; + msk = RT2_SYNCCTRL_MASK | RT2_SYNCEDGE_MASK; + switch (conf->hvsync) { + case LCD_HVSYNC_RISING: + v = RT2_SYNCCTRL_Active | RT2_SYNCEDGE_Rising; + break; + case LCD_HVSYNC_FALLING: + v = RT2_SYNCCTRL_Active | RT2_SYNCEDGE_Falling; + break; + case LCD_HVSYNC_PCLK: + default: + v = RT2_SYNCCTRL_Inactive; + break; + } + reg = FIELD_SET(reg, msk, v); + + v = conf->cflag & LCD_CFLAG_BIAS_LOW? RT2_BIAS_low: RT2_BIAS_high; + reg = FIELD_SET(reg, RT2_BIAS_MASK, v); + v = conf->cflag & LCD_CFLAG_PIXEL_FALLING? RT2_IPC_falling: RT2_IPC_rising; + reg = FIELD_SET(reg, RT2_IPC_MASK, v); + v = conf->cflag & LCD_CFLAG_HSYNC_LOW? RT2_IHS_low: RT2_IHS_high; + reg = FIELD_SET(reg, RT2_IHS_MASK, v); + v = conf->cflag & LCD_CFLAG_VSYNC_LOW? RT2_IVS_low: RT2_IVS_high; + reg = FIELD_SET(reg, RT2_IVS_MASK, v); + reg = FIELD_SET(reg, RT2_ACBI_MASK, RT2_ACBI_VAL(0)); + reg = FIELD_SET(reg, RT2_ACB_MASK, RT2_ACB_VAL(0xFF)); + lcon->RASTER_TIMING_2 = reg; + + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_STN565_MASK, RASTER_CTRL_STN565_disabled); + reg = FIELD_SET(reg, RASTER_CTRL_ALTMAP_MASK, RASTER_CTRL_ALTMAP_D15_0); + v = conf->bpp < 8? RASTER_CTRL_NIB_enabled: RASTER_CTRL_NIB_disabled; + reg = FIELD_SET(reg, RASTER_CTRL_NIB_MASK, v); + reg = FIELD_SET(reg, RASTER_CTRL_PLM_MASK, RASTER_CTRL_PLM_PaletteData); + reg = FIELD_SET(reg, RASTER_CTRL_FDD_MASK, RASTER_CTRL_FDD_X(2)); + reg = FIELD_SET(reg, RASTER_CTRL_RDORDER_MASK, RASTER_CTRL_RDORDER_Little); + reg = FIELD_SET(reg, RASTER_CTRL_TS_MASK, RASTER_CTRL_TS_TFT); + reg = FIELD_SET(reg, RASTER_CTRL_MC_MASK, RASTER_CTRL_MC_Color); + + // disable all interrupt + msk = RASTER_CTRL_FUFEN_MASK | RASTER_CTRL_SLEN_MASK | RASTER_CTRL_PLEN_MASK; + msk |= RASTER_CTRL_DONEEN_MASK | RASTER_CTRL_ACEN_MASK; + v = RASTER_CTRL_FUFEN_no | RASTER_CTRL_SLEN_no | RASTER_CTRL_PLEN_no; + v |= RASTER_CTRL_DONEEN_no | RASTER_CTRL_ACEN_no; + reg = FIELD_SET(reg, msk, v); + lcon->RASTER_CTRL = reg; + + reg = lcon->LCDDMA_CTRL; + reg = FIELD_SET(reg, LDMAC_TFR_MASK, LDMAC_TFR_128dwords); + reg = FIELD_SET(reg, LDMAC_BURSTSIZE_MASK, LDMAC_BURSTSIZE_16); + reg = FIELD_SET(reg, LDMAC_EOFINTEN_MASK, LDMAC_EOFINTEN_no); + reg = FIELD_SET(reg, LDMAC_BIGENDIAN_MASK, LDMAC_BIGENDIAN_disabled); + v = conf->fb1_base? LDMAC_FRAMEMODE_two: LDMAC_FRAMEMODE_one; + reg = FIELD_SET(reg, LDMAC_FRAMEMODE_MASK, v); + lcon->LCDDMA_CTRL = reg; + + lcon->LCDDMA_FB0_BASE = conf->fb0_base; + v = conf->bpp == 8? 512: 32; // Palette size + v += conf->width * conf->height * conf->bpp >> 3; // Pixels size + v -= 2; + lcon->LCDDMA_FB0_CEILING = conf->fb0_base + v; + if (conf->fb1_base) { + lcon->LCDDMA_FB1_BASE = conf->fb1_base; + lcon->LCDDMA_FB1_CEILING = conf->fb1_base + v; + } + + return AM18X_OK; +} + +am18x_rt lcd_cmd(LCD_con_t* lcon, uint32_t cmd, uint32_t arg) { + uint32_t reg; + + switch(cmd) { + case LCD_CMD_RASTER_EN: + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_EN_MASK, RASTER_CTRL_EN_yes); + lcon->RASTER_CTRL = reg; + break; + case LCD_CMD_RASTER_DIS: + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_EN_MASK, RASTER_CTRL_EN_no); + lcon->RASTER_CTRL = reg; + break; + case LCD_CMD_PALETTE: + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_PLM_MASK, RASTER_CTRL_PLM_Palette); + lcon->RASTER_CTRL = reg; + break; + case LCD_CMD_DATA: + reg = lcon->RASTER_CTRL; + reg = FIELD_SET(reg, RASTER_CTRL_PLM_MASK, RASTER_CTRL_PLM_Data); + lcon->RASTER_CTRL = reg; + break; + case LCD_CMD_FB_SET: + if (arg == 0) { + lcon->LCDDMA_FB0_BASE = lcon->LCDDMA_FB0_BASE; + } else { + lcon->LCDDMA_FB0_BASE = arg; + } + break; + default: + break; + } + return AM18X_OK; +} + +am18x_rt lcd_intr_enable(LCD_con_t* lcon, uint32_t intr) { + uint32_t reg, msk, v; + + if (intr == LCD_INTR_EOF) { + reg = lcon->LCDDMA_CTRL; + reg = FIELD_SET(reg, LDMAC_EOFINTEN_MASK, LDMAC_EOFINTEN_yes); + lcon->LCDDMA_CTRL = reg; + return AM18X_OK; + } + + reg = lcon->RASTER_CTRL; + msk = 0; + v = 0; + switch(intr) { + case LCD_INTR_AC: + msk = RASTER_CTRL_ACEN_MASK; + v = RASTER_CTRL_ACEN_yes; + break; + case LCD_INTR_DONE: + msk = RASTER_CTRL_DONEEN_MASK; + v = RASTER_CTRL_DONEEN_yes; + break; + case LCD_INTR_PL: + msk = RASTER_CTRL_PLEN_MASK; + v = RASTER_CTRL_PLEN_yes; + break; + case LCD_INTR_SL: + msk = RASTER_CTRL_SLEN_MASK; + v = RASTER_CTRL_SLEN_yes; + break; + case LCD_INTR_FUF: + msk = RASTER_CTRL_FUFEN_MASK; + v = RASTER_CTRL_FUFEN_yes; + break; + default: + break; + } + reg = FIELD_SET(reg, msk, v); + lcon->RASTER_CTRL = reg; + + return AM18X_OK; +} + +am18x_rt lcd_intr_disable(LCD_con_t* lcon, uint32_t intr) { + uint32_t reg, msk, v; + + if (intr == LCD_INTR_EOF) { + reg = lcon->LCDDMA_CTRL; + reg = FIELD_SET(reg, LDMAC_EOFINTEN_MASK, LDMAC_EOFINTEN_no); + lcon->LCDDMA_CTRL = reg; + return AM18X_OK; + } + + reg = lcon->RASTER_CTRL; + msk = 0; + v = 0; + switch(intr) { + case LCD_INTR_AC: + msk = RASTER_CTRL_ACEN_MASK; + v = RASTER_CTRL_ACEN_no; + break; + case LCD_INTR_DONE: + msk = RASTER_CTRL_DONEEN_MASK; + v = RASTER_CTRL_DONEEN_no; + break; + case LCD_INTR_PL: + msk = RASTER_CTRL_PLEN_MASK; + v = RASTER_CTRL_PLEN_no; + break; + case LCD_INTR_SL: + msk = RASTER_CTRL_SLEN_MASK; + v = RASTER_CTRL_SLEN_no; + break; + case LCD_INTR_FUF: + msk = RASTER_CTRL_FUFEN_MASK; + v = RASTER_CTRL_FUFEN_no; + break; + default: + break; + } + reg = FIELD_SET(reg, msk, v); + lcon->RASTER_CTRL = reg; + + return AM18X_OK; +} + +am18x_rt lcd_intr_clear(LCD_con_t* lcon, uint32_t intr) { + uint32_t msk, v; + + msk = 0; + v = 0; + switch(intr) { + case LCD_INTR_AC: + msk = LCD_STAT_ABC_MASK; + v = LCD_STAT_ABC_zero; + break; + case LCD_INTR_DONE: + msk = LCD_STAT_DONE_MASK; + v = LCD_STAT_DONE_yes; + break; + case LCD_INTR_PL: + msk = LCD_STAT_PL_MASK; + v = LCD_STAT_PL_yes; + break; + case LCD_INTR_SL: + msk = LCD_STAT_SYNC_MASK; + v = LCD_STAT_SYNC_lost; + break; + case LCD_INTR_FUF: + msk = LCD_STAT_FUF_MASK; + v = LCD_STAT_FUF_yes; + break; + case LCD_INTR_EOF: + msk = LCD_STAT_EOF0_MASK; + v = LCD_STAT_EOF0_yes; + break; + case LCD_INTR_EOF1: + msk = LCD_STAT_EOF1_MASK; + v = LCD_STAT_EOF1_yes; + break; + case LCD_INTR_ALL: + msk = 0xFFFFFFFFUL; + v = lcon->LCD_STAT; + break; + default: + break; + } + lcon->LCD_STAT = FIELD_SET(0, msk, v);; + + return AM18X_OK; +} + +am18x_bool lcd_intr_state(const LCD_con_t* lcon, uint32_t intr) { + uint32_t msk, v; + am18x_bool r = AM18X_FALSE; + + switch(intr) { + case LCD_INTR_AC: + msk = LCD_STAT_ABC_MASK; + v = LCD_STAT_ABC_zero; + break; + case LCD_INTR_DONE: + msk = LCD_STAT_DONE_MASK; + v = LCD_STAT_DONE_yes; + break; + case LCD_INTR_PL: + msk = LCD_STAT_PL_MASK; + v = LCD_STAT_PL_yes; + break; + case LCD_INTR_SL: + msk = LCD_STAT_SYNC_MASK; + v = LCD_STAT_SYNC_lost; + break; + case LCD_INTR_FUF: + msk = LCD_STAT_FUF_MASK; + v = LCD_STAT_FUF_yes; + break; + case LCD_INTR_EOF: + msk = LCD_STAT_EOF0_MASK; + v = LCD_STAT_EOF0_yes; + break; + case LCD_INTR_EOF1: + msk = LCD_STAT_EOF1_MASK; + v = LCD_STAT_EOF1_yes; + break; + default: + return r; + } + if (FIELD_GET(lcon->LCD_STAT, msk) == v) { + r = AM18X_TRUE; + } + + return r; +} diff --git a/lib/am18x-lib/src/am18x_mmcsd.c b/lib/am18x-lib/src/am18x_mmcsd.c new file mode 100644 index 000000000..d6b69af5b --- /dev/null +++ b/lib/am18x-lib/src/am18x_mmcsd.c @@ -0,0 +1,400 @@ +// tary, 20:23 2013/7/10 +#include "am18x_dclk.h" +#include "am18x_mmcsd.h" +#include "auxlib.h" + +static uint32_t mmcsd_get_freq(const MMCSD_con_t* mcon) { + uint32_t reg, f; + + reg = mcon->MMCCLK; + f = dev_get_freq(DCLK_ID_MMC_SDS); + f /= (2 * (__field_xget(reg, MMCCLK_CLKRT_MASK) + 1)); + if (FIELD_GET(reg, MMCCLK_DIV4_MASK) == MMCCLK_DIV4_div4) { + f /= 2; + } + return f; +} + +uint32_t mmcsd_xet_freq(MMCSD_con_t* mcon, uint32_t freq) { + uint32_t reg, msk, v; + + if (freq == 0x0UL) { + return mmcsd_get_freq(mcon); + } + + reg = mcon->MMCCLK; + msk = MMCCLK_CLKRT_MASK; + v = dev_get_freq(DCLK_ID_MMC_SDS) / (freq * 2); + if (FIELD_GET(reg, MMCCLK_DIV4_MASK) == MMCCLK_DIV4_div4) { + v /= 2; + } + if (v == 0) v = 1; + mcon->MMCCLK = FIELD_SET(reg, msk, MMCCLK_CLKRT_VAL(v)); + + if (mmcsd_get_freq(mcon) > freq) { + v++; + mcon->MMCCLK = FIELD_SET(reg, msk, MMCCLK_CLKRT_VAL(v)); + } + + return mmcsd_get_freq(mcon); +} + +am18x_rt mmcsd_con_init(MMCSD_con_t* mcon, const mmcsd_conf_t* conf) { + uint32_t reg, msk, v; + + // 1. Place the MMC/SD controller in its reset state + msk = MMCCTL_CMDRST_MASK | MMCCTL_DATRST_MASK; + v = MMCCTL_CMDRST_disabled | MMCCTL_DATRST_disabled; + mcon->MMCCTL = FIELD_SET(0, msk, v); + + // 2. Write the required values to other registers + // Initialize the MMC Control Register + reg = mcon->MMCCTL; + msk = MMCCTL_WIDTH0_MASK | MMCCTL_WIDTH1_MASK; + v = MMCCTL_WIDTH0_1bit | MMCCTL_WIDTH1_1_4bit; + mcon->MMCCTL = FIELD_SET(reg, msk, v); + + // Initializing the Clock Controller Regisr + reg = mcon->MMCCLK; + msk = MMCCLK_DIV4_MASK | MMCCLK_CLKEN_MASK; + v = MMCCLK_DIV4_div2 | MMCCLK_CLKEN_low; + mcon->MMCCLK = FIELD_SET(reg, msk, v); + + mmcsd_xet_freq(mcon, conf->freq); + + // Initialize the Interrupt Mask Register + mcon->MMCIM = 0x0UL; + + // Initialize the Time-Out Registers + v = FIELD_SET(0, MMCTOR_TOD25_16_MASK, MMCTOR_TOD25_16_VAL(conf->timeout_dat)); + v = FIELD_SET(v, MMCTOR_TOR_MASK, MMCTOR_TOR_VAL(conf->timeout_rsp)); + mcon->MMCTOR = v; + + reg = mcon->MMCTOR; + v = MMCTOD_TOD15_0_VAL(conf->timeout_dat); + mcon->MMCTOD = FIELD_SET(reg, MMCTOD_TOD15_0_MASK, v); + + // Initialize the Data Block Registers + mcon->MMCBLEN = MMCSD_BLOCK_SIZE; + mcon->MMCNBLK = 1UL; + + // 3. release the MMC/SD controller from its reset state + v = MMCCTL_CMDRST_enabled | MMCCTL_DATRST_enabled; + mcon->MMCCTL = FIELD_SET(0, msk, v); + + // 4. Enable the MMCSD_CLK pin so that the memory clock is + // sent to the memory card + reg = mcon->MMCCLK; + mcon->MMCCLK = FIELD_SET(reg, MMCCLK_CLKEN_MASK, MMCCLK_CLKEN_enabled); + + return AM18X_OK; +} + +am18x_rt mmcsd_send_cmd(MMCSD_con_t* mcon, const mmcsd_cmd_t* cmd) { + uint32_t reg, msk, v; + uint32_t idx; + + assert(mcon); + assert(cmd); + assert(cmd->index < 0x40); + + idx = cmd->index; + + mcon->MMCCIDX = 0; + mcon->MMCRSP[0] = 0; + mcon->MMCRSP[1] = 0; + mcon->MMCRSP[2] = 0; + mcon->MMCRSP[3] = 0; + + reg = mcon->MMCCMD; + // Bug Fix, DCLR_clear is going data shift 2 bytes + reg = FIELD_SET(reg, MMCCMD_DCLR_MASK, MMCCMD_DCLR_none); + + if (cmd->cflags & MMCSD_CMD_F_BUSY) { + reg = FIELD_SET(reg, MMCCMD_BSYEXP_MASK, MMCCMD_BSYEXP_expected); + } else { + reg = FIELD_SET(reg, MMCCMD_BSYEXP_MASK, MMCCMD_BSYEXP_none); + } + + msk = MMCCMD_WDATX_MASK; + if (cmd->cflags & MMCSD_CMD_F_DATA) { + reg = FIELD_SET(reg, msk, MMCCMD_WDATX_yes); + reg = FIELD_SET(reg, MMCCMD_STRMTP_MASK, MMCCMD_STRMTP_block); + + if (cmd->cflags & MMCSD_CMD_F_WRITE) { + reg = FIELD_SET(reg, MMCCMD_DTRW_MASK, MMCCMD_DTRW_write); + } else { + reg = FIELD_SET(reg, MMCCMD_DMATRIG_MASK, MMCCMD_DMATRIG_triggered); + reg = FIELD_SET(reg, MMCCMD_DTRW_MASK, MMCCMD_DTRW_read); + } + } else { + reg = FIELD_SET(reg, msk, MMCCMD_WDATX_no); + } + + msk = MMCCMD_RSPFMT_MASK; + v = MMCCMD_RSPFMT_none; + if (cmd->cflags & MMCSD_CMD_F_RSP) { + if (cmd->cflags & MMCSD_CMD_F_LONG) { + v = MMCCMD_RSPFMT_136b; + } else if (cmd->cflags & MMCSD_CMD_F_CRC) { + v = MMCCMD_RSPFMT_48bCRC; + } else { + v = MMCCMD_RSPFMT_48b; + } + } + reg = FIELD_SET(reg, msk, v); + + reg = FIELD_SET(reg, MMCCMD_CMD_MASK, MMCCMD_CMD_VAL(idx)); + + mcon->MMCARGHL = cmd->arg; + mcon->MMCCMD = reg; + + if (cmd->cflags & MMCSD_CMD_F_DATA) { + printk("*** MMCCMD = 0x%.8X ***\n", mcon->MMCCMD); + } + + return AM18X_OK; +} + +#define TRACK_SAMPLES 40000 +#define TRACK_SAVES 0x400 +mmcsd_cmd_state_t mmcsd_cmd_state(const MMCSD_con_t* mcon, am18x_bool need_crc) { +#if 1 + uint32_t reg; + + reg = mcon->MMCST0; + if (FIELD_GET(reg, MMCST0_RSPDNE_MASK) == MMCST0_RSPDNE_done) { + return MMCSD_SC_RSP_OK; + } + if (FIELD_GET(reg, MMCST0_CRCRS_MASK) == MMCST0_CRCRS_detected) { + return MMCSD_SC_CRC_ERR; + } + if (FIELD_GET(reg, MMCST0_TOUTRS_MASK) == MMCST0_TOUTRS_occurred) { + return MMCSD_SC_RSP_TOUT; + } +#else + { + uint32_t reg_tracks[TRACK_SAVES]; + int i, n = 0; + + reg_tracks[n++] = mcon->MMCST0; + for (i = 0; i < TRACK_SAMPLES; i++) { + if (reg_tracks[n - 1] != (reg_tracks[n] = mcon->MMCST0)) { + n++; + } + } + + printk("%s() \n", __func__); + for (i = 0; i < n; i++) { + printk("[%.3d] = 0x%.8X\n", i, reg_tracks[i]); + if (FIELD_GET(reg_tracks[i], MMCST0_RSPDNE_MASK) == MMCST0_RSPDNE_done + //|| FIELD_GET(reg_tracks[i], MMCST0_BSYDNE_MASK) == MMCST0_BSYDNE_done + ) { + return MMCSD_SC_RSP_OK; + } + if (FIELD_GET(reg_tracks[i], MMCST0_CRCRS_MASK) == MMCST0_CRCRS_detected) { + return MMCSD_SC_CRC_ERR; + } + if (FIELD_GET(reg_tracks[i], MMCST0_TOUTRS_MASK) == MMCST0_TOUTRS_occurred) { + return MMCSD_SC_RSP_TOUT; + } + } + } +#endif + return MMCSD_SC_NONE; +} + +mmcsd_dat_state_t mmcsd_busy_state(const MMCSD_con_t* mcon) { + return MMCSD_SD_OK; +} + +mmcsd_dat_state_t mmcsd_rd_state(const MMCSD_con_t* mcon) { +#if 1 + uint32_t reg; + + reg = mcon->MMCST0; + if (FIELD_GET(reg, MMCST0_CRCRD_MASK) == MMCST0_CRCRD_detected) { + return MMCSD_SD_CRC_ERR; + } + if (FIELD_GET(reg, MMCST0_TOUTRD_MASK) == MMCST0_TOUTRD_occurred) { + return MMCSD_SD_TOUT; + } + if (FIELD_GET(reg, MMCST0_DRRDY_MASK) == MMCST0_DRRDY_ready) { + return MMCSD_SD_RECVED; + } + if (FIELD_GET(reg, MMCST0_DATDNE_MASK) == MMCST0_DATDNE_done) { + return MMCSD_SD_OK; + } +#else + uint32_t reg_tracks[TRACK_SAVES]; + int i, n = 0; + + reg_tracks[n++] = mcon->MMCST0; + for (i = 0; i < TRACK_SAMPLES; i++) { + if (reg_tracks[n - 1] != (reg_tracks[n] = mcon->MMCST0)) { + n++; + } + } + + printk("%s() \n", __func__); + for (i = 0; i < n; i++) { + printk("[%.3d] = 0x%.8X\n", i, reg_tracks[i]); + } + for (i = 0; i < n; i++) { + if (FIELD_GET(reg_tracks[i], MMCST0_CRCRD_MASK) == MMCST0_CRCRD_detected) { + return MMCSD_SD_CRC_ERR; + } + if (FIELD_GET(reg_tracks[i], MMCST0_TOUTRD_MASK) == MMCST0_TOUTRD_occurred) { + return MMCSD_SD_TOUT; + } + if (FIELD_GET(reg_tracks[i], MMCST0_DRRDY_MASK) == MMCST0_DRRDY_ready) { + return MMCSD_SD_RECVED; + } + if (FIELD_GET(reg_tracks[i], MMCST0_DATDNE_MASK) == MMCST0_DATDNE_done) { + return MMCSD_SD_OK; + } + } +#endif + return MMCSD_SD_NONE; +} + +mmcsd_dat_state_t mmcsd_wr_state(const MMCSD_con_t* mcon) { +#if 1 + uint32_t reg; + + reg = mcon->MMCST0; + if (FIELD_GET(reg, MMCST0_CRCWR_MASK) == MMCST0_CRCWR_detected) { + return MMCSD_SD_CRC_ERR; + } + if (FIELD_GET(reg, MMCST0_DXRDY_MASK) == MMCST0_DXRDY_ready) { + return MMCSD_SD_SENT; + } + if (FIELD_GET(reg, MMCST0_DATDNE_MASK) == MMCST0_DATDNE_done) { + return MMCSD_SD_OK; + } +#else + uint32_t reg_tracks[TRACK_SAVES]; + int i, n = 0; + + reg_tracks[n++] = mcon->MMCST0; + for (i = 0; i < TRACK_SAMPLES; i++) { + if (reg_tracks[n - 1] != (reg_tracks[n] = mcon->MMCST0)) { + n++; + } + } + + printk("%s() \n", __func__); + for (i = 0; i < n; i++) { + printk("[%.3d] = 0x%.8X\n", i, reg_tracks[i]); + } + for (i = 0; i < n; i++) { + if (FIELD_GET(reg_tracks[i], MMCST0_CRCWR_MASK) == MMCST0_CRCWR_detected) { + return MMCSD_SD_CRC_ERR; + } + if (FIELD_GET(reg_tracks[i], MMCST0_DXRDY_MASK) == MMCST0_DXRDY_ready) { + return MMCSD_SD_SENT; + } + if (FIELD_GET(reg_tracks[i], MMCST0_DATDNE_MASK) == MMCST0_DATDNE_done) { + return MMCSD_SD_OK; + } + } +#endif + return MMCSD_SD_NONE; +} + +am18x_rt mmcsd_get_resp(const MMCSD_con_t* mcon, mmcsd_resp_type_t type, mmcsd_resp_t* resp) { + int i; + + assert(mcon); + assert(resp); + + switch(type) { + case MMCSD_RESP_LONG: + for (i = 0; i < 4; i++) { + resp->v[i] = mcon->MMCRSP[i]; + } + break; + case MMCSD_RESP_SHORT: + default: + resp->v[0] = mcon->MMCRSP[3]; + break; + } + return AM18X_OK; +} + +am18x_rt mmcsd_cntl_misc(MMCSD_con_t* mcon, const mmcsd_misc_t* misc) { + uint32_t reg, msk, v; + + if (misc->mflags & MMCSD_MISC_F_BUS4BIT) { + // Initialize the MMC Control Register + reg = mcon->MMCCTL; + msk = MMCCTL_WIDTH0_MASK | MMCCTL_WIDTH1_MASK; + v = MMCCTL_WIDTH0_4bit | MMCCTL_WIDTH1_1_4bit; + mcon->MMCCTL = FIELD_SET(reg, msk, v); + return 0; + } + + // setting block count + if (misc->blkcnt) { + mcon->MMCNBLK = misc->blkcnt; + } + + // 7. Set the FIFO direction to transmit/receive + reg = 0; + msk = MMCFIFOCTL_FIFODIR_MASK; + if (misc->mflags & MMCSD_MISC_F_WRITE) { + v = MMCFIFOCTL_FIFODIR_write; + } else { + v = MMCFIFOCTL_FIFODIR_read; + } + reg = FIELD_SET(reg, msk, v); + + // 8. Set the access width + msk = MMCFIFOCTL_ACCWD_MASK; + reg = FIELD_SET(reg, msk, MMCFIFOCTL_ACCWD_4bytes); + + // 9. Set the FIFO threshold + msk = MMCFIFOCTL_FIFOLEV_MASK; + if (misc->mflags & MMCSD_MISC_F_FIFO_64B) { + reg = FIELD_SET(reg, msk, MMCFIFOCTL_FIFOLEV_64B); + } else { + reg = FIELD_SET(reg, msk, MMCFIFOCTL_FIFOLEV_32B); + } + + // 6. Reset the FIFO + // reg = mcon->MMCFIFOCTL; + msk = MMCFIFOCTL_FIFORST_MASK; + if (misc->mflags & MMCSD_MISC_F_FIFO_RST) { + mcon->MMCFIFOCTL = FIELD_SET(reg, msk, MMCFIFOCTL_FIFORST_reset); + } + + mcon->MMCFIFOCTL = reg; + + printk("*** MMCFIFOCTL = 0x%.8X ***\n", mcon->MMCFIFOCTL); + + reg = mcon->MMCIM; + msk = MMCIM_ECRCRS_MASK | MMCIM_ETOUTRS_MASK | MMCIM_ERSPDNE_MASK | MMCIM_EDATDNE_MASK; + v = MMCIM_ECRCRS_enabled | MMCIM_ETOUTRS_enabled | MMCIM_ERSPDNE_enabled | MMCIM_EDATDNE_enabled; + reg = FIELD_SET(reg, msk, v); + if (misc->mflags & MMCSD_MISC_F_WRITE) { + // 10. Enable the DXRDYINT interrupt + msk = MMCIM_EDXRDY_MASK | MMCIM_ECRCWR_MASK; + v = MMCIM_EDXRDY_enabled | MMCIM_ECRCWR_enabled; + } else { + // 11. Enable the DRRDYINT interrupt + msk = MMCIM_EDRRDY_MASK | MMCIM_ECRCRD_MASK | MMCIM_ETOUTRD_MASK; + v = MMCIM_EDRRDY_enabled | MMCIM_ECRCRD_enabled | MMCIM_ETOUTRD_enabled; + } + mcon->MMCIM = FIELD_SET(reg, msk, v); + + return AM18X_OK; +} + +uint32_t mmcsd_read(const MMCSD_con_t* mcon) { + return mcon->MMCDRR; +} + +am18x_rt mmcsd_write(MMCSD_con_t* mcon, uint32_t data) { + mcon->MMCDXR = data; + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_pll.c b/lib/am18x-lib/src/am18x_pll.c new file mode 100644 index 000000000..878ae04b5 --- /dev/null +++ b/lib/am18x-lib/src/am18x_pll.c @@ -0,0 +1,254 @@ +// tary, 21:18 2013/4/15 +#include "am18x_pll.h" + +#define PLL0_DIV_CNT 7 +#define PLL1_DIV_CNT 3 + +// PLL0 plldivn = 1..7 +// PLL1 plldivn = 1..3 +am18x_rt pll_changing_sysclk_dividers(PLL_con_t* pcon, uint32_t plldivn, uint32_t divider) { + uint32_t reg, msk, idx; + + // 1. Wait for the GOSTAT bit in PLLSTAT to clear to 0 + while (FIELD_GET(pcon->PLLSTAT, PLLSTAT_GOSTAT_MASK) != PLLSTAT_GOSTAT_done); + + // 2. Program the RATIO field in PLLDIVn + msk = XXXDIVx_RATIO_MASK; + if (plldivn <= PLL1_DIV_CNT) { + idx = PLLDIVxA_IDX_1 + plldivn - 1; + reg = pcon->PLLDIVxA[idx]; + reg = FIELD_SET(reg, XXXDIVx_DxEN_MASK, XXXDIVx_DxEN_enable); + pcon->PLLDIVxA[idx] = FIELD_SET(reg, msk, XXXDIVx_RATIO_WR(divider)); + } else if (plldivn <= PLL0_DIV_CNT) { + idx = PLLDIVxB_IDX_4 + plldivn - 4; + reg = pcon->PLLDIVxB[idx]; + reg = FIELD_SET(reg, XXXDIVx_DxEN_MASK, XXXDIVx_DxEN_enable); + pcon->PLLDIVxB[idx] = FIELD_SET(reg, msk, XXXDIVx_RATIO_WR(divider)); + } + + // 3. Set the GOSET bit in PLLCMD to 1 + pcon->PLLCMD = FIELD_SET(pcon->PLLCMD, PLLCMD_GOSET_MASK, PLLCMD_GOSET_initiate); + + // 4. Wait for the GOSTAT bit in PLLSTAT to clear to 0 + while (FIELD_GET(pcon->PLLSTAT, PLLSTAT_GOSTAT_MASK) != PLLSTAT_GOSTAT_done); + + return AM18X_OK; +} + +am18x_rt pll_get_conf(const PLL_con_t* pcon, pll_conf_t* conf) { + uint32_t msk, v; + int i; + + conf->prediv = 1UL; + if (pcon == PLL0) { + conf->prediv += __field_xget(pcon->PREDIV, XXXDIVx_RATIO_MASK); + } + conf->pllm = 1UL + __field_xget(pcon->PLLM, PLLM_MASK); + conf->postdiv = 1UL + __field_xget(pcon->POSTDIV, XXXDIVx_RATIO_MASK); + + for (i = 0; i < PLL0_DIV_CNT; i++) { + if (i < PLL1_DIV_CNT) { + v = pcon->PLLDIVxA[PLLDIVxA_IDX_1 + i]; + conf->plldiv[i] = 1UL + __field_xget(v, XXXDIVx_RATIO_MASK); + } else if (pcon == PLL0) { + v = pcon->PLLDIVxB[PLLDIVxB_IDX_4 + i - PLL1_DIV_CNT]; + conf->plldiv[i] = 1UL + __field_xget(v, XXXDIVx_RATIO_MASK); + } + } + + conf->cflag = 0; + + msk = PLLCTL_EXTCLKSRC_MASK; + v = PLLCTL_EXTCLKSRC_PLL1sysclk3; + if (pcon == PLL0 && FIELD_GET(pcon->PLLCTL, msk) == v) { + conf->cflag |= PLL_CFLAG_EXT_CLK_PLL1; + } + + msk = PLLCTL_CLKMODE_MASK; + v = PLLCTL_CLKMODE_wave; + if (pcon == PLL0 && FIELD_GET(pcon->PLLCTL, msk) == v) { + conf->cflag |= PLL_CFLAG_REF_SQUARE; + } + + msk = PLLCTL_PLLPWRDN_MASK; + v = PLLCTL_PLLPWRDN_yes; + if (FIELD_GET(pcon->PLLCTL, msk) == v) { + conf->cflag |= PLL_CFLAG_POWER_DOWN; + } + + return AM18X_OK; +} + +am18x_rt pll_set_conf(PLL_con_t* pcon, const pll_conf_t* conf) { + uint32_t msk, v; + + // 1. Program the CLKMODE bit in PLLC0 PLLCTL + if (pcon == PLL0 && (conf->cflag & PLL_CFLAG_FROM_POWERON)) { + msk = PLLCTL_CLKMODE_MASK; + if (conf->cflag & PLL_CFLAG_REF_SQUARE) { + v = PLLCTL_CLKMODE_wave; + } else { + v = PLLCTL_CLKMODE_crystal; + } + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, v); + } + + // 2. Switch the PLL to bypass mode + // a) Clear the PLLENSRC bit in PLLCTL to 0 + // allows PLLEN bit to take effect + msk = PLLCTL_PLLENSRC_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLENSRC_cleared); + + // b) For PLL0 only, select the clock source by programming + // the EXTCLKSRC bit in PLLCTL + if (pcon == PLL0) { + msk = PLLCTL_EXTCLKSRC_MASK; + if (conf->cflag & PLL_CFLAG_EXT_CLK_PLL1) { + v = PLLCTL_EXTCLKSRC_PLL1sysclk3; + } else { + v = PLLCTL_EXTCLKSRC_oscin; + } + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, v); + } + + // c) Clear the PLLEN bit in PLLCTL to 0 + msk = PLLCTL_PLLEN_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_no); + + // d) Wait for 4 OSCIN cycles to ensure that + // the PLLC has switch to bypass mode + for (v = 0; v < 456 * 4 / 12; v++) { + asm volatile ("nop"); + } + + // 3. Clear PLLRST in PLLCTL to 0 + msk = PLLCTL_PLLRST_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLRST_asserted); + + // 4. Clear the PLLPWRDN bit in PLLCTL to 0 + msk = PLLCTL_PLLPWRDN_MASK; + if (FIELD_GET(pcon->PLLCTL, msk) == PLLCTL_PLLPWRDN_yes) { + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLPWRDN_no); + } + + // 5. Program the desired multiplier value in PLLM. + // Program the POSTDIV, as needed. + pcon->PLLM = FIELD_SET(0, PLLM_MASK, PLLM_WR(conf->pllm)); + msk = XXXDIVx_DxEN_MASK | XXXDIVx_RATIO_MASK; + if (pcon == PLL0) { + v = XXXDIVx_DxEN_enable | XXXDIVx_RATIO_WR(conf->prediv); + pcon->PREDIV = FIELD_SET(0, msk, v); + } + v = XXXDIVx_DxEN_enable | XXXDIVx_RATIO_WR(conf->postdiv); + pcon->POSTDIV = FIELD_SET(0, msk, v); + + // 6. If desired, program PLLDIVn registers to change + // the SYSCLKn divide values + for (v = 0; v < PLL0_DIV_CNT; v++) { + if (pcon == PLL1 && v >= PLL1_DIV_CNT) break; + pll_changing_sysclk_dividers(pcon, v + 1, conf->plldiv[v]); + } + + // 7. Set the PLLRST bit in PLL to 1 (brings PLL out of reset) + msk = PLLCTL_PLLRST_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLRST_deasserted); + + // 8. Wait for the PLL to lock + // am1808.pdf 5.6.1 PLL Device-Specific Information + // Max PLL Lock Time = 2000 * N / sqrt(M) + // N = Pre-Divider Ratio + // M = PLL Multiplier + for (v = 0; v < 456 * ( 2000 * conf->prediv / 2) / 12; v++) { + asm volatile ("nop"); + } + + // 9. Set the PLLEN bit in PLLCTL to 1 (removes PLL from bypass mode) + msk = PLLCTL_PLLEN_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_yes); + + return AM18X_OK; +} + +am18x_rt pll_cmd(PLL_con_t* pcon, uint32_t cmd, uint32_t arg) { + uint32_t reg, msk; + int i; + + switch (cmd) { + case PLL_CMD_SOFT_RESET: + if (pcon != PLL0) break; + pcon->RSCTRL = FIELD_SET(0, RSCTRL_KEY_MASK, RSCTRL_KEY_unlock); + while (FIELD_GET(pcon->RSCTRL, RSCTRL_KEY_MASK) != RSCTRL_KEY_unlocked); + pcon->RSCTRL = FIELD_SET(0, RSCTRL_SWRST_MASK, RSCTRL_SWRST_yes); + break; + + case PLL_CMD_ENABLE_PLL1_DIVS: + if (pcon != PLL1) break; + msk = XXXDIVx_DxEN_MASK; + for (i = 0; i < PLL1_DIV_CNT; i++) { + int idx = PLLDIVxA_IDX_1 + i; + reg = pcon->PLLDIVxA[idx]; + pcon->PLLDIVxA[idx] = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); + } + break; + + case PLL_CMD_POWER_DOWN: + msk = PLLCTL_PLLEN_MASK; + if (FIELD_GET(pcon->PLLCTL, msk) == PLLCTL_PLLEN_yes) { + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_no); + } + msk = PLLCTL_PLLPWRDN_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLPWRDN_yes); + break; + + case PLL_CMD_BYPASS: + msk = PLLCTL_PLLEN_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_no); + for (i = 0; i < 456 * 4 / 12; i++) { + asm volatile ("nop"); + } + break; + + case PLL_CMD_CHG_MULT: + pcon->PLLM = FIELD_SET(0, PLLM_MASK, PLLM_WR(arg)); + for (i = 0; i < 456 * ( 2000 * (pcon->PREDIV + 1) / 2) / 12; i++) { + asm volatile ("nop"); + } + break; + + case PLL_CMD_UNBYPASS: + msk = PLLCTL_PLLEN_MASK; + pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_yes); + break; + + case PLL_CMD_IS_ENABLE: + msk = PLLCTL_PLLPWRDN_MASK; + if (FIELD_GET(pcon->PLLCTL, msk) != PLLCTL_PLLPWRDN_no) { + return AM18X_ERR; + } + msk = PLLCTL_PLLEN_MASK; + if (FIELD_GET(pcon->PLLCTL, msk) != PLLCTL_PLLEN_yes) { + return AM18X_ERR; + } + break; + + default: + break; + } + + return AM18X_OK; +} + +pll_reset_t pll_get_reset(void) { + PLL_con_t* pcon = PLL0; + pll_reset_t r; + + r = PLL_RESET_SOFTWARE; + if (FIELD_GET(pcon->RSTYPE, RSTYPE_XWRST_MASK) == RSTYPE_XWRST_yes) { + r = PLL_RESET_EXTERNAL; + } + if (FIELD_GET(pcon->RSTYPE, RSTYPE_POR_MASK) == RSTYPE_POR_yes) { + r = PLL_RESET_POWER_ON; + } + + return r; +} diff --git a/lib/am18x-lib/src/am18x_pru.c b/lib/am18x-lib/src/am18x_pru.c new file mode 100644 index 000000000..99a434ac6 --- /dev/null +++ b/lib/am18x-lib/src/am18x_pru.c @@ -0,0 +1,93 @@ +// tary, 22:52 2013/5/10 +#include "am18x_pru.h" +#include "auxlib.h" + +am18x_rt pru_load(PRU_con_t* pcon, const uint32_t* inst, uint32_t count) { + uint32_t* pram; + int i; + + pram = (uint32_t*)PRU_InstRAM0_BASE; + if (pcon == PRU1) { + pram = (uint32_t*)PRU_InstRAM1_BASE; + } + + if (count * sizeof(uint32_t) > PRU_InstRAM0_SIZE) { + count = PRU_InstRAM0_SIZE / sizeof(uint32_t); + } + + for (i = 0; i < count; i++) { + pram[i] = inst[i]; + } + return AM18X_OK; +} + +am18x_rt pru_cmd(PRU_con_t* pcon, pru_cmd_t cmd, uint32_t arg) { + uint32_t reg, msk; + + reg = pcon->CONTROL; + + switch (cmd) { + case PRU_CMD_DISABLE: + msk = CONTROL_COUNTENABLE_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_COUNTENABLE_no); + reg = pcon->CONTROL; + msk = CONTROL_ENABLE_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_ENABLE_no); + reg = pcon->CONTROL; + msk = CONTROL_SOFTRESET_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_SOFTRESET_yes); + break; + + case PRU_CMD_ENABLE: + msk = CONTROL_SOFTRESET_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_SOFTRESET_yes); + break; + + case PRU_CMD_RUN: + msk = CONTROL_COUNTENABLE_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_COUNTENABLE_yes); + reg = pcon->CONTROL; + msk = CONTROL_ENABLE_MASK; + pcon->CONTROL = FIELD_SET(reg, msk, CONTROL_ENABLE_yes); + break; + + case PRU_CMD_IS_HALT: + msk = CONTROL_RUNSTATE_MASK; + if (FIELD_GET(reg, msk) == CONTROL_RUNSTATE_running) { + return AM18X_ERR; + } + break; + + default: + break; + } + return AM18X_OK; +} + +#define KOFP(x) KOF(PRU_con_t, x) +static kv_t of_regs[] = { + KOFP(CONTROL), + KOFP(STATUS), + KOFP(WAKEUP), + KOFP(CYCLECNT), + KOFP(STALLCNT), + KOFP(CONTABBLKIDX0), + KOFP(CONTABPROPTR), + KOFP(INTGPR), + KOFP(INTCTER), +}; + +am18x_rt pru_dump_regs(PRU_con_t* pcon) { + uint32_t* ptr; + int i; + + for (i = 0; i < countof(of_regs); i++) { + int of; + + of = of_regs[i].key; + ptr = (uint32_t*)pcon + (of >> 2); + printk("%-14s[0x%.8X] = 0x%.8X\n", of_regs[i].val, ptr, *ptr); + } + + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_psc.c b/lib/am18x-lib/src/am18x_psc.c new file mode 100644 index 000000000..c6258d7ff --- /dev/null +++ b/lib/am18x-lib/src/am18x_psc.c @@ -0,0 +1,151 @@ +// tary, 0:35 2012/12/27 +#include "am18x_psc.h" +#include "auxlib.h" + +static PSC_con_t* module_to_psc(psc_module_t module, uint32_t* nr) { + if (module < MODULE_NR_PER_PSC) { + *nr = module; + return PSC0; + } + *nr = module - MODULE_NR_PER_PSC; + return PSC1; +} + +// 8.3.2 Module State Transitions +am18x_rt psc_state_transition(psc_module_t module, psc_state_t state) { + PSC_con_t* psc; + uint32_t nr; + uint32_t reg, val; + + psc = module_to_psc(module, &nr); + + // 1. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0 + while (FIELD_GET(psc->PTSTAT, PTSTAT_GO0_MASK) != PTSTAT_GO0_no); + + // 2. Set the NEXT bit MDCTLn to 0..5 + switch(state) { + case PSC_STATE_SW_RST_DISABLE: + val = MDCTLx_STATE_SwRstDisable; + break; + case PSC_STATE_SYNC_RESET: + val = MDCTLx_STATE_SyncReset; + break; + case PSC_STATE_ENABLE: + val = MDCTLx_STATE_Enable; + break; + case PSC_STATE_DISABLE: + default: + val = MDCTLx_STATE_Disable; + break; + } + reg = psc->MDCTLx[nr]; + psc->MDCTLx[nr] = FIELD_SET(reg, MDCTLx_STATE_MASK, val); + + // 3. Set the GO[x] bit in PTCMD to 1 to initiate the transition(s) + psc->PTCMD = FIELD_SET(psc->PTCMD, PTCMD_GO0, PTCMD_GO0); + + // 4. Wait for the GOSTAT[x] bit in PTSTAT to clear to 0 + while (FIELD_GET(psc->PTSTAT, PTSTAT_GO0_MASK) != PTSTAT_GO0_no); + + // while (__field_xget(psc->MDSTATx[nr], MDSTATx_STATE_MASK) != val); + + return AM18X_OK; +} + +am18x_rt psc_enable_interrupt(psc_module_t module) { + PSC_con_t* psc; + uint32_t nr; + uint32_t reg, msk, val; + + psc = module_to_psc(module, &nr); + + // 1. Set the EMUIHBIE bit in PDCTLn, + reg = psc->PDCTL0; + val = PDCTLx_EMUIHBIE_enable; + psc->PDCTL0 = FIELD_SET(reg, PDCTLx_EMUIHBIE_MASK, val); + // the EMUIHBIE and the EMURSTIE bits in MDCTLn + // to enable the interrupt events that you want. + reg = psc->MDCTLx[nr]; + msk = MDCTLx_EMUIHBIE_MASK | MDCTLx_EMURSTIE_MASK; + val = MDCTLx_EMUIHBIE_enable | MDCTLx_EMURSTIE_enable; + psc->MDCTLx[nr] = FIELD_SET(reg, msk, val); + + // 2. Enable the power sleep controller interrupt (PSCn_ALLINT) + // in the device interrupt controller. + return AM18X_OK; +} + +psc_state_t psc_get_state(psc_module_t module) { + PSC_con_t* psc; + uint32_t nr; + uint32_t val; + psc_state_t s = PSC_STATE_DISABLE; + + psc = module_to_psc(module, &nr); + + val = __field_xget(psc->MDSTATx[nr], MDSTATx_STATE_MASK); + if (MDSTATx_STATE_in_transition(val)) { + return PSC_STATE_IN_TRANSITION; + } + switch (val) { + case MDSTATx_STATE_SwRstDisable: + s = PSC_STATE_SW_RST_DISABLE; + break; + case MDSTATx_STATE_SyncReset: + s = PSC_STATE_SYNC_RESET; + break; + case MDSTATx_STATE_Disable: + s = PSC_STATE_DISABLE; + break; + case MDSTATx_STATE_Enable: + s = PSC_STATE_ENABLE; + break; + } + + return s; +} + +#define KOFP(x) KOF(PSC_con_t, x) +static kv_t of_regs[] = { + KOFP(REVID), + KOFP(INTEVAL), + KOFP(MERRPR0), + KOFP(MERRCR0), + KOFP(PERRPR), + KOFP(PERRCR), + KOFP(PTCMD), + KOFP(PTSTAT), + KOFP(PDSTAT0), + KOFP(PDSTAT1), + KOFP(PDCTL0), + KOFP(PDCTL1), + KOFP(PDCFG0), + KOFP(PDCFG1), + KOFP(MDSTATx), + KOFP(MDCTLx), +}; + +am18x_rt psc_dump_regs(PSC_con_t* pcon) { + uint32_t* ptr; + int i, s; + + for (i = 0; i < countof(of_regs) - 2; i++) { + int of; + + of = of_regs[i].key; + ptr = (uint32_t*)pcon + (of >> 2); + printk("%-8s[0x%.8X] = 0x%.8X\n", of_regs[i].val, ptr, *ptr); + } + + s = MODULE_NR_PER_PSC; + if (pcon == PSC0) s = s / 2; + ptr = &pcon->MDSTATx; + for (i = 0; i < s; i++) { + printk("MDSTAT%-2d[0x%.8X] = 0x%.8X\n", i, ptr + i, ptr[i]); + } + ptr = &pcon->MDCTLx; + for (i = 0; i < s; i++) { + printk("MDCTL%-3d[0x%.8X] = 0x%.8X\n", i, ptr + i, ptr[i]); + } + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_rtc.c b/lib/am18x-lib/src/am18x_rtc.c new file mode 100644 index 000000000..ec05832bc --- /dev/null +++ b/lib/am18x-lib/src/am18x_rtc.c @@ -0,0 +1,100 @@ +// tary, 20:03 2016/6/4 +#include "am18x_rtc.h" + +am18x_rt rtc_conf(RTC_con_t* rtc, const rtc_tm_t* tm) { + uint32_t reg; + + assert(rtc); + assert(tm); + + rtc->KICKnR[0] = RTC_KICK0R_VAL; + rtc->KICKnR[1] = RTC_KICK1R_VAL; + + if (tm->cflags & RTC_DISABLE) { + reg = rtc->CTRL; + reg = FIELD_SET(reg, RTCTL_RUN_MASK, RTCTL_RUN_no); + rtc->CTRL = reg; + rtc->CTRL = FIELD_SET(reg, RTCTL_DISABLE_MASK, RTCTL_DISABLE_yes); + } + if (tm->cflags & RTC_ENABLE) { + reg = rtc->CTRL; + reg = FIELD_SET(reg, RTCTL_DISABLE_MASK, RTCTL_DISABLE_no); + rtc->CTRL = reg; + rtc->CTRL = FIELD_SET(reg, RTCTL_RUN_MASK, RTCTL_RUN_yes); + } + + if (tm->cflags & RTC_TICKINT_DISABLE) { + reg = rtc->INTERRUPT; + rtc->INTERRUPT = FIELD_SET(reg, RTCINT_TIMER_MASK, RTCINT_TIMER_disabled); + } + if (tm->cflags & RTC_TICKINT_ENABLE) { + reg = rtc->INTERRUPT; + reg = FIELD_SET(reg, RTCINT_TIMER_MASK, RTCINT_TIMER_enabled); + rtc->INTERRUPT = FIELD_SET(reg, RTCINT_EVERY_MASK, RTCINT_EVERY_Second); + } + + if (tm->cflags & RTC_SET_TIME) { + rtc->SECOND = BIN2BCD(tm->second); + rtc->MINUTE = BIN2BCD(tm->minute); + rtc->HOUR = BIN2BCD(tm->hour); + rtc->DAY = BIN2BCD(tm->day); + rtc->MONTH = BIN2BCD(tm->month); + rtc->YEAR = BIN2BCD(tm->year - 2000); + } + + return AM18X_OK; +} + +am18x_rt rtc_alarm(RTC_con_t* rtc, const rtc_tm_t* tm) { + uint32_t reg, v; + + assert(rtc); + + reg = rtc->INTERRUPT; + v = (tm == NULL)? RTCINT_ALARM_disabled: RTCINT_ALARM_enabled; + rtc->INTERRUPT = reg = FIELD_SET(reg, RTCINT_ALARM_MASK, v); + if (tm == NULL) { + return AM18X_ERR; + } + + rtc->INTERRUPT = FIELD_SET(reg, RTCINT_EVERY_MASK, RTCINT_EVERY_Second); + rtc->ALARMSECOND = BIN2BCD(tm->second); + rtc->ALARMMINUTE = BIN2BCD(tm->minute); + rtc->ALARMHOUR = BIN2BCD(tm->hour); + rtc->ALARMDAY = BIN2BCD(tm->day); + rtc->ALARMMONTH = BIN2BCD(tm->month); + rtc->ALARMYEAR = BIN2BCD(tm->year - 2000); + + return AM18X_OK; +} + +am18x_rt rtc_state(const RTC_con_t* rtc, rtc_tm_t* tm) { + uint8_t reg; + + assert(rtc); + assert(tm); + + reg = rtc->STATUS; + if (FIELD_GET(reg, RTCSTAT_RUN_MASK) != RTCSTAT_RUN_yes) { + return AM18X_ERR; + } + + tm->second = BCD2BIN(rtc->SECOND); + tm->minute = BCD2BIN(rtc->MINUTE); + tm->hour = BCD2BIN(rtc->HOUR); + tm->weekday = rtc->DOTW; + tm->day = BCD2BIN(rtc->DAY); + tm->month = BCD2BIN(rtc->MONTH); + tm->year = BCD2BIN(rtc->YEAR) + 2000; + + reg = rtc->INTERRUPT; + if (FIELD_GET(reg, RTCINT_TIMER_MASK) == RTCINT_TIMER_enabled) { + tm->cflags = RTC_TICKINT_ENABLE; + // TODO: + tm->tickcnt = 1; + } else { + tm->cflags = RTC_TICKINT_DISABLE; + } + + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_syscfg.c b/lib/am18x-lib/src/am18x_syscfg.c new file mode 100644 index 000000000..9fce62490 --- /dev/null +++ b/lib/am18x-lib/src/am18x_syscfg.c @@ -0,0 +1,217 @@ +// tary, 13:15 2012/12/28 +#include "am18x_syscfg.h" + +am18x_rt syscfg_kick(am18x_bool lock) { + uint32_t kick0, kick1; + + if (lock) { + kick0 = KICK0R_LOCK; + kick1 = KICK1R_LOCK; + } else { + kick0 = KICK0R_UNLOCK; + kick1 = KICK1R_UNLOCK; + } + + SYSCFG0->KICKxR[0] = kick0; + SYSCFG0->KICKxR[1] = kick1; + + return AM18X_OK; +} + +am18x_rt syscfg_pll(am18x_bool lock) { + uint32_t cfg0, cfg3, msk; + + cfg0 = SYSCFG0->CFGCHIP0; + cfg3 = SYSCFG0->CFGCHIP3; + if (lock) { + msk = CFGCHIP0_PLL_MASTER_LOCK_MASK; + cfg0 = FIELD_SET(cfg0, msk, CFGCHIP0_PLL_MASTER_LOCK_yes); + msk = CFGCHIP3_PLL1_MASTER_LOCK_MASK; + cfg3 = FIELD_SET(cfg3, msk, CFGCHIP3_PLL1_MASTER_LOCK_yes); + } else { + msk = CFGCHIP0_PLL_MASTER_LOCK_MASK; + cfg0 = FIELD_SET(cfg0, msk, CFGCHIP0_PLL_MASTER_LOCK_no); + msk = CFGCHIP3_PLL1_MASTER_LOCK_MASK; + cfg3 = FIELD_SET(cfg3, msk, CFGCHIP3_PLL1_MASTER_LOCK_no); + } + + SYSCFG0->CFGCHIP0 = cfg0; + SYSCFG0->CFGCHIP3 = cfg3; + + return AM18X_OK; +} + +am18x_rt syscfg_aync3(am18x_bool src_y_pll0_n_pll1) { + uint32_t msk, v; + + msk = CFGCHIP3_ASYNC3_CLKSRC_MASK; + v = src_y_pll0_n_pll1? CFGCHIP3_ASYNC3_CLKSRC_pll0: CFGCHIP3_ASYNC3_CLKSRC_pll1; + SYSCFG0->CFGCHIP3 = FIELD_SET(SYSCFG0->CFGCHIP3, msk, v); + + return AM18X_OK; +} + +// pos = [0,4,8,12,16,20,24,28] +// val = [0..15] +am18x_rt syscfg_pinmux(uint32_t mux, uint32_t pos, uint32_t val) { + uint32_t reg; + + if (mux >= 20 || pos >= 32 || (pos & 0x3UL) != 0 || val > 0xFUL) { + return AM18X_ERR; + } + + reg = SYSCFG0->PINMUXx[mux]; + SYSCFG0->PINMUXx[mux] = __field_xset(reg, (0xFUL << pos), val); + + return AM18X_OK; +} + +int32_t syscfg_bootmode(void) { + return __field_xget(SYSCFG0->BOOTCFG, BOOTCFG_BOOTMODE_MASK); +} + +am18x_rt syscfg_vtpio_calibrate(void) { + uint32_t reg, msk; + + reg = SYSCFG1->VTPIO_CTL; + // a) Clear POWERDN bit in the VTPIO_CTL + reg = FIELD_SET(reg, VTPIO_CTL_POWERDN_MASK, VTPIO_CTL_POWERDN_no); + SYSCFG1->VTPIO_CTL = reg; + + // b) Clear LOCK bit in VTPIO_CTL + reg = FIELD_SET(reg, VTPIO_CTL_LOCK_MASK, VTPIO_CTL_LOCK_no); + SYSCFG1->VTPIO_CTL = reg; + + // c) Pulse CLKRZ bit in VTPIO_CTL + msk = VTPIO_CTL_CLKRZ_MASK; + reg = FIELD_SET(SYSCFG1->VTPIO_CTL, msk, VTPIO_CTL_CLKRZ_none); + SYSCFG1->VTPIO_CTL = reg; + reg = FIELD_SET(SYSCFG1->VTPIO_CTL, msk, VTPIO_CTL_CLKRZ_clear); + SYSCFG1->VTPIO_CTL = reg; + reg = FIELD_SET(SYSCFG1->VTPIO_CTL, msk, VTPIO_CTL_CLKRZ_none); + SYSCFG1->VTPIO_CTL = reg; + + // d) Poll READY bit in VTPIO_CTL until it changes to 1 + do { + reg = FIELD_GET(SYSCFG1->VTPIO_CTL, VTPIO_CTL_READY_MASK); + } while (reg != VTPIO_CTL_READY_yes); + + // e) Set LOCK bit in VTPIO_CTL is locked + // and dynamic calibration is disabled + reg = SYSCFG1->VTPIO_CTL; + reg = FIELD_SET(reg, VTPIO_CTL_LOCK_MASK, VTPIO_CTL_LOCK_yes); + SYSCFG1->VTPIO_CTL = reg; + + // f) Set POWERDN bit in VTPIO_CTL to save power + reg = FIELD_SET(reg, VTPIO_CTL_POWERDN_MASK, VTPIO_CTL_POWERDN_yes); + SYSCFG1->VTPIO_CTL = reg; + + reg = FIELD_SET(reg, VTPIO_CTL_IOPWRDN_MASK, VTPIO_CTL_IOPWRDN_yes); + SYSCFG1->VTPIO_CTL = reg; + + return AM18X_OK; +} + +am18x_rt syscfg_ddr_slew(am18x_bool ddr2_not_mddr) { + uint32_t reg, v; + + reg = SYSCFG1->DDR_SLEW; + v = (ddr2_not_mddr)? DDR_SLEW_CMOSEN_SSTL: DDR_SLEW_CMOSEN_LVCMOS; + SYSCFG1->DDR_SLEW = FIELD_SET(reg, DDR_SLEW_CMOSEN_MASK, v); + return AM18X_OK; +} + +static uint32_t freq_table[][2] = { + {CFGCHIP2_USB0REFFREQ_12MHz, 12000000}, + {CFGCHIP2_USB0REFFREQ_24MHz, 24000000}, + {CFGCHIP2_USB0REFFREQ_48MHz, 48000000}, + {CFGCHIP2_USB0REFFREQ_19_2MHz, 19200000}, + {CFGCHIP2_USB0REFFREQ_38_4MHz, 38400000}, + {CFGCHIP2_USB0REFFREQ_13MHz, 13000000}, + {CFGCHIP2_USB0REFFREQ_26MHz, 26000000}, + {CFGCHIP2_USB0REFFREQ_20MHz, 20000000}, + {CFGCHIP2_USB0REFFREQ_40MHz, 40000000}, +}; + +// USB#0 (USB2.0 subsystem) +am18x_rt syscfg_set_usb0phy(am18x_bool y_on_n_off, uint32_t freq) { + uint32_t reg, msk, v; + int i; + + reg = SYSCFG0->CFGCHIP2; + + v = CFGCHIP2_RESET_yes; + if (!y_on_n_off) { + v |= CFGCHIP2_USB0PHYPWDN_down; + v |= CFGCHIP2_USB0OTGPWRDN_down; + } + + // RESET: Hold PHY in Reset + reg = FIELD_SET(reg, CFGCHIP2_RESET_MASK, v); + SYSCFG0->CFGCHIP2 = reg; + // Drive Reset for few clock cycles + for (v = 0; v < 50; v++) { + asm volatile ("nop"); + } + + if (!y_on_n_off) { + return AM18X_OK; + } + + // RESET: Release PHY from Reset + reg = FIELD_SET(reg, CFGCHIP2_RESET_MASK, CFGCHIP2_RESET_no); + SYSCFG0->CFGCHIP2 = reg; + + // Do Not Override PHY Values + reg = FIELD_SET(reg, CFGCHIP2_USB0OTGMODE_MASK, CFGCHIP2_USB0OTGMODE_none); + reg = FIELD_SET(reg, CFGCHIP2_USB0PHYPWDN_MASK, CFGCHIP2_USB0PHYPWDN_none); + reg = FIELD_SET(reg, CFGCHIP2_USB0OTGPWRDN_MASK, CFGCHIP2_USB0OTGPWRDN_none); + reg = FIELD_SET(reg, CFGCHIP2_USB0DATPOL_MASK, CFGCHIP2_USB0DATPOL_none); + reg = FIELD_SET(reg, CFGCHIP2_USB0SESNDEN_MASK, CFGCHIP2_USB0SESNDEN_enabled); + reg = FIELD_SET(reg, CFGCHIP2_USB0VBDTCTEN_MASK, CFGCHIP2_USB0VBDTCTEN_enabled); + SYSCFG0->CFGCHIP2 = reg; + + v = CFGCHIP2_USB0REFFREQ_12MHz; + for (i = 0; i < countof(freq_table); i++) { + if (freq == freq_table[i][1]) { + v = freq_table[i][0]; + break; + } + } + if (i >= countof(freq_table)) { + return AM18X_ERR; + } + + // Configure PHY PLL use and Select Source + reg = FIELD_SET(reg, CFGCHIP2_USB0REFFREQ_MASK, v); + reg = FIELD_SET(reg, CFGCHIP2_USB0PHYCLKMUX_MASK, CFGCHIP2_USB0PHYCLKMUX_AUXCLK); + SYSCFG0->CFGCHIP2 = reg; + + // PHY_PLLON: On Simulation PHY PLL is OFF + msk = CFGCHIP2_USB0PHY_PLLON_MASK; + reg = FIELD_SET(reg, msk, CFGCHIP2_USB0PHY_PLLON_yes); + SYSCFG0->CFGCHIP2 = reg; + + // Wait Until PHY Clock is Good + msk = CFGCHIP2_USB0PHYCLKGD_MASK; + while (FIELD_GET(SYSCFG0->CFGCHIP2, msk) == CFGCHIP2_USB0PHYCLKGD_no); + + return AM18X_OK; +} + +// USB#1 (USB1.1 subsystem) +am18x_rt syscfg_set_usb1phy(am18x_bool y_on_n_off, am18x_bool phy_clk_y_usb0_n_refin) { + uint32_t reg, v; + + reg = SYSCFG0->CFGCHIP2; + + v = phy_clk_y_usb0_n_refin? CFGCHIP2_USB1PHYCLKMUX_USB0PHY: CFGCHIP2_USB1PHYCLKMUX_REFCLKIN; + reg = FIELD_SET(reg, CFGCHIP2_USB1PHYCLKMUX_MASK, v); + + v = y_on_n_off? CFGCHIP2_USB1SUSPENDM_no: CFGCHIP2_USB1SUSPENDM_yes; + reg = FIELD_SET(reg, CFGCHIP2_USB1SUSPENDM_MASK, v); + + SYSCFG0->CFGCHIP2 = reg; + + return AM18X_OK; +} diff --git a/lib/am18x-lib/src/am18x_timer.c b/lib/am18x-lib/src/am18x_timer.c new file mode 100644 index 000000000..203c8839c --- /dev/null +++ b/lib/am18x-lib/src/am18x_timer.c @@ -0,0 +1,147 @@ +// tary, 22:05 2013/3/6 +#include "am18x_timer.h" +#include "am18x_dclk.h" + +uint32_t timer_input_freq(TIMER_con_t* tcon) { + if (tcon == TIMER0) { + return dev_get_freq(DCLK_ID_TIMER64P0); + } + if (tcon == TIMER1) { + return dev_get_freq(DCLK_ID_TIMER64P1); + } + if (tcon == TIMER2) { + return dev_get_freq(DCLK_ID_TIMER64P2); + } + if (tcon == TIMER3) { + return dev_get_freq(DCLK_ID_TIMER64P3); + } + return 0UL; +} + +am18x_rt timer_conf(TIMER_con_t* tcon, const timer_conf_t* conf) { + uint32_t reg, msk, v; + + // 30.2.1.4.1.3 64-Bit Timer Configuration Procedure + // 1. Select 64-bit mode (TIMMODE in TGCR) + reg = tcon->TGCR; + reg = FIELD_SET(reg, TGCR_PLUSEN_MASK, TGCR_PLUSEN_available); + msk = TGCR_TIMMODE_MASK; + switch (conf->mode) { + case TIMER_MODE_32_BIT_UNCHANINED: + v = TGCR_TIMMODE_unchained; + break; + case TIMER_MODE_32_BIT_CHAINED: + v = TGCR_TIMMODE_chained; + break; + case TIMER_MODE_WATCHDOG: + v = TGCR_TIMMODE_watchdog; + break; + case TIMER_MODE_64_BIT: + default: + v = TGCR_TIMMODE_64bit; + break; + } + tcon->TGCR = FIELD_SET(reg, msk, v); + + // 2. Remove the timer from reset (TIM12RS and TIM34RS in TGCR) + reg = tcon->TCR; + reg = FIELD_SET(reg, TGCR_TIM12RS_MASK, TGCR_TIM12RS_reset); + tcon->TCR = FIELD_SET(reg, TGCR_TIM34RS_MASK, TGCR_TIM34RS_reset); + + // 3. Select the desired timer period (PRD12 and PRD34) + tcon->PRDx[0] = conf->period - 1UL; + tcon->PRDx[1] = 0UL; + + // 4. Enable the timer (ENAMODE12 in TCR) + reg = tcon->TCR; + reg = FIELD_SET(reg, TCR_ENAMODE34_MASK, TCR_ENAMODE34_disabled); + msk = TCR_ENAMODE12_MASK; + switch (conf->operation) { + case TIMER_OPER_ONE_TIME: + v = TCR_ENAMODE12_once; + break; + case TIMER_OPER_CONTINUOUS: + v = TCR_ENAMODE12_enabled; + break; + case TIMER_OPER_RELOAD: + v = TCR_ENAMODE12_reload; + break; + default: + v = TCR_ENAMODE12_disabled; + break; + } + reg = FIELD_SET(reg, msk, v); + + if (conf->source == TIMER_SOURCE_INTERNAL) { + v = TCR_CLKSRC12_internal; + } else { + v = TCR_CLKSRC12_external; + } + tcon->TCR = FIELD_SET(reg, TCR_CLKSRC12_MASK, v); + + switch(conf->result) { + case TIMER_RESULT_DMA_SYNC: + case TIMER_RESULT_INTERRUPT: + reg = tcon->INTCTLSTAT; + msk = INTCTLSTAT_PRDINTEN12_MASK; + tcon->INTCTLSTAT = FIELD_SET(reg, msk, INTCTLSTAT_PRDINTEN12_enable); + break; + case TIMER_RESULT_NONE: + default: + reg = tcon->INTCTLSTAT; + msk = INTCTLSTAT_PRDINTEN12_MASK; + tcon->INTCTLSTAT = FIELD_SET(reg, msk, INTCTLSTAT_PRDINTEN12_disable); + break; + } + + msk = EMUMGT_FREE_MASK; + tcon->EMUMGT = FIELD_SET(tcon->EMUMGT, msk, EMUMGT_FREE_run); + + tcon->TIMx[0] = 0UL; + + return AM18X_OK; +} + +am18x_rt timer_cmd(TIMER_con_t* tcon, timer_cmd_t cmd, uint32_t arg) { + uint32_t reg, msk; + + switch(cmd) { +/* case TIMER_CMD_PAUSE: + msk = TCR_ENAMODE12_MASK; + tcon->TCR = FIELD_SET(tcon->TCR, msk, TCR_ENAMODE12_disabled); + break; + case TIMER_CMD_RESTART: + msk = TCR_ENAMODE12_MASK; + tcon->TCR = FIELD_SET(tcon->TCR, msk, TCR_ENAMODE12_enabled); + break; +*/ + case TIMER_CMD_PAUSE: + case TIMER_CMD_RESET: + msk = TGCR_TIM12RS_MASK; + tcon->TGCR = FIELD_SET(tcon->TGCR, msk, TGCR_TIM12RS_reset); + break; + case TIMER_CMD_RESTART: + case TIMER_CMD_START: + msk = TGCR_TIM12RS_MASK; + tcon->TGCR = FIELD_SET(tcon->TGCR, msk, TGCR_TIM12RS_none); + break; + case TIMER_CMD_RELOAD: + tcon->RELx[0] = arg - 1UL; + tcon->RELx[1] = 0UL; + break; + case TIMER_CMD_INTR_CLEAR: + reg = tcon->INTCTLSTAT; + msk = INTCTLSTAT_PRDINTSTAT12_MASK; + tcon->INTCTLSTAT = FIELD_SET(reg, msk, INTCTLSTAT_PRDINTSTAT12_clear); + default: + break; + } + + return AM18X_OK; +} + +uint32_t timer_get_count(TIMER_con_t* tcon) { + return tcon->TIMx[0]; +} + +//#error TIMER diff --git a/lib/am18x-lib/src/am18x_uart.c b/lib/am18x-lib/src/am18x_uart.c new file mode 100644 index 000000000..fd2533084 --- /dev/null +++ b/lib/am18x-lib/src/am18x_uart.c @@ -0,0 +1,166 @@ +// tary, 0:22 2012/12/22 +#include "am18x_uart.h" +#include "am18x_dclk.h" + +uint32_t uart_input_freq(UART_con_t* ucon) { + if (ucon == UART0) { + return dev_get_freq(DCLK_ID_UART0); + } + if (ucon == UART1) { + return dev_get_freq(DCLK_ID_UART1); + } + if (ucon == UART2) { + return dev_get_freq(DCLK_ID_UART2); + } + return 0UL; +} + +static inline uint32_t uart_get_divisor(UART_con_t* ucon, uint32_t baud_rate) { + uint32_t samp_clk; + + samp_clk = 16; + if (FIELD_GET(ucon->MDR, MDR_OSM_SEL_MASK) == MDR_OSM_SEL_13x) { + samp_clk = 13; + } + + return uart_input_freq(ucon) / (samp_clk * baud_rate); +} + +am18x_rt uart_init_conf(uart_conf_t* conf) { + assert(conf); + + conf->baudrate = 115200UL; + conf->length = UART_LENGTH_8BIT; + conf->stop = UART_STOP_1BIT; + conf->parity = UART_PARITY_NONE; + conf->flow = UART_FLOW_NONE; + conf->mode = UART_MODE_INTR; + + return AM18X_OK; +} + +am18x_rt uart_set_conf(UART_con_t* ucon, const uart_conf_t* conf) { + uint32_t reg, msk, v; + + assert(conf); + assert(conf->baudrate); + + // 2. Set the desired baud rate by writing the appropriate + // clock divisor values to the divisor latch registers + ucon->MDR = FIELD_SET(ucon->MDR, MDR_OSM_SEL_MASK, MDR_OSM_SEL_13x); + + v = uart_get_divisor(ucon, conf->baudrate); + ucon->DLL = __field_xget(v, 0x00FF); + ucon->DLH = __field_xget(v, 0xFF00); + + // 4. Choose the desired protocol settings by writing the + // appropriate values to the line control register + reg = FIELD_SET(ucon->LCR, LCR_DLAB_MASK, LCR_DLAB_rbr_thr_ier); + reg = FIELD_SET(reg, LCR_BC_MASK, LCR_BC_disabled); + + msk = LCR_PEN_MASK | LCR_EPS_MASK | LCR_SP_MASK; + switch (conf->parity) { + case UART_PARITY_ODD: + v = LCR_PEN_Yes | LCR_EPS_Odd | LCR_SP_disabled; + break; + case UART_PARITY_EVEN: + v = LCR_PEN_Yes | LCR_EPS_Even | LCR_SP_disabled; + break; + case UART_PARITY_1S: + v = LCR_PEN_Yes | LCR_EPS_Odd | LCR_SP_enabled;; + break; + case UART_PARITY_0S: + v = LCR_PEN_Yes | LCR_EPS_Even | LCR_SP_enabled; + break; + case UART_PARITY_NONE: + default: + v = LCR_PEN_No; + break; + } + reg = FIELD_SET(reg, msk, v); + + switch (conf->stop) { + case UART_STOP_2BIT: + v = LCR_STB_15_2STOP; + break; + case UART_STOP_1BIT: + default: + v = LCR_STB_1STOP; + break; + } + reg = FIELD_SET(reg, LCR_STB_MASK, v); + + switch(conf->length) { + case UART_LENGTH_5BIT: + v = LCR_WLS_5bits; + break; + case UART_LENGTH_6BIT: + v = LCR_WLS_6bits; + break; + case UART_LENGTH_7BIT: + v = LCR_WLS_7bits; + break; + case UART_LENGTH_8BIT: + default: + v = LCR_WLS_8bits; + break; + } + reg = FIELD_SET(reg, LCR_WLS_MASK, v); + ucon->LCR = reg; + + // 6. Choose the desired response to emulation suspend events + // by configuring the FREE bit and enable the UART + // by setting the UTRST and URRST bits in the power and emulation + // management register + msk = PWREMU_UTRST_MASK | PWREMU_URRST_MASK; + v = PWREMU_UTRST_enabled | PWREMU_URRST_enabled;// | PWREMU_FREE_run; + ucon->PWREMU_MGMT = FIELD_SET(ucon->PWREMU_MGMT, msk, v); + + return AM18X_OK; +} + +am18x_bool uart_state(const UART_con_t* ucon, uart_state_type_t type) { + am18x_bool r; + + r = AM18X_FALSE; + switch (type) { + case STATE_TX_EMPTY: + if (FIELD_GET(ucon->LSR, LSR_TEMT_MASK) == LSR_TEMT_yes) { + r = AM18X_TRUE; + } + break; + case STATE_TX_BUF_EMPTY: + if (FIELD_GET(ucon->LSR, LSR_THRE_MASK) == LSR_THRE_yes) { + r = AM18X_TRUE; + } + break; + case STATE_RX_READY: + if (FIELD_GET(ucon->LSR, LSR_DR_MASK) == LSR_DR_yes) { + r = AM18X_TRUE; + } + break; + case STATE_ERROR_ANY: + case STATE_ERROR_BREAK: + case STATE_ERROR_FRAME: + case STATE_ERROR_PARITY: + case STATE_ERROR_OVERRUN: + + case STATE_CTS_ACTIVE: + case STATE_CTS_CHANGED: + + case STATE_FIFO_XXFULL: + case STATE_FIFO_TXFULL: + case STATE_FIFO_RXFULL: + break; + } + return r; +} + +am18x_rt uart_write_byte(UART_con_t* ucon, uint8_t c) { + ucon->THRw = c; + return AM18X_OK; +} + +uint8_t uart_read_byte(const UART_con_t* ucon) { + return ucon->RBRr; +} diff --git a/lib/am18x-lib/src/am18x_usb0.c b/lib/am18x-lib/src/am18x_usb0.c new file mode 100644 index 000000000..e89b3947a --- /dev/null +++ b/lib/am18x-lib/src/am18x_usb0.c @@ -0,0 +1,165 @@ +// tary, 20:35 2015/6/6 +#include "am18x_usb.h" +#include "am18x_syscfg.h" +#include "am18x_dclk.h" +#include "am18x_psc.h" +#include "auxlib.h" + +#define ucon USB0 + +am18x_rt usb0_conf(const usb0_conf_t* conf) { + uint32_t reg, msk, v; + uint32_t freq; + int i; + + // Make sure write access key is initialized + // prior to accessing any of the BOOTCFG registers + syscfg_kick(AM18X_FALSE); + + psc_state_transition(PSC_USB0, PSC_STATE_ENABLE); + + // Reset the USB controller + reg = ucon->CTRLR; + msk = CTRLR_RESET_MASK; + ucon->CTRLR = FIELD_SET(reg, msk, CTRLR_RESET_reset); + while (FIELD_GET(ucon->CTRLR, msk) == CTRLR_RESET_reset); + + freq = dev_get_freq(DCLK_ID_USB2_0_PHY); + printk("USB0 PHY CLK = %d Hz\n", freq); + + // Configure PHY with the Desired Operation + syscfg_set_usb0phy(AM18X_TRUE, freq); + + reg = ucon->POWER; + v = (conf->highspeed)? POWER_HSEN_high: POWER_HSEN_full; + ucon->POWER = FIELD_SET(reg, POWER_HSEN_MASK, v); + + // Enable PDR2.0 Interrupt + reg = ucon->CTRLR; + ucon->CTRLR = FIELD_SET(reg, CTRLR_UINT_MASK, CTRLR_UINT_PDR); + + reg = ucon->INTRRXE; + msk = v = 0; + for (i = 1; i < USB0_EP_CNT; i++) { + msk |= INTRx_EP_MASK(i); + v |= INTRx_EP_enable(i); + } + // Enable All Core Rx Endpoints Interrupts + ucon->INTRRXE = FIELD_SET(reg, msk, v); + + reg = ucon->INTRTXE; + msk |= INTRx_EP_MASK(0); + v |= INTRx_EP_enable(0); + // Enable All Core Tx Endpoints Interrupts + EP0 Tx/Rx Interrupts + // spruh82a.pdf, Page 1674 + // Use INTRTX only when in the non-PDR interrupt mode, that is, + // when handling the interrupt directly from the controller + ucon->INTRTXE = FIELD_SET(reg, msk, v); + + reg = ucon->INTRUSBE; + msk = v = 0; + for (i = INTUSB_SUSPEND; i < INTUSB_CNT; i++) { + msk |= INTRUSBx_INTUSB_MASK(i); + v |= INTRUSBx_INTUSB_yes(i); + } + // Enable all USB interrupts in MUSBMHDRC + // spruh82a.pdf, Page 1677 + // Use INTRUSB only when in the non-PDR interrupt mode, that is + // when handling the interrupt directly from the controller + ucon->INTRUSBE = reg = FIELD_SET(reg, msk, v); + printk("Write INTRUSBE = 0x%.8X\n", reg); + + /* + reg = ucon->CTRLR; + ucon->CTRLR = FIELD_SET(reg, CTRLR_UINT_MASK, CTRLR_UINT_PDR); + */ + + /* msk |= INTxR_USBDRVVBUS_MASK | INTxR_VBUSERR_MASK | INTxR_SESSREQ_MASK; + msk |= INTxR_DISCON_MASK | INTxR_CONN_MASK | INTxR_SOF_MASK; + msk |= INTxR_BABBLE_MASK | INTxR_RESUME_MASK | INTxR_SUSPEND_MASK; + v |= INTxR_USBDRVVBUS_yes | INTxR_VBUSERR_yes | INTxR_SESSREQ_yes; + v |= INTxR_DISCON_yes | INTxR_CONN_yes | INTxR_SOF_yes; + v |= INTxR_BABBLE_yes | INTxR_RESUME_yes | INTxR_SUSPEND_yes; + */ + reg = ucon->INTMSKSETR; + msk = v = 0; + for (i = 0; i < USB0_EP_CNT; i++) { + msk |= INTxR_TXEPn_MASK(i); + v |= INTxR_TXEPn_yes(i); + if (i == 0) continue; + msk |= INTxR_RXEPn_MASK(i); + v |= INTxR_RXEPn_yes(i); + } + for (i = INTUSB_SUSPEND; i < INTUSB_CNT; i++) { + msk |= INTxR_INTUSB_MASK(i); + v |= INTxR_INTUSB_yes(i); + } + // Enable interrupts in OTG block + // spruh82a.pdf, Page 1667 + // Other than USB bit field, to make use of INTMSKSETR, + // the PDR interrupt handler must be enabled. + ucon->INTMSKSETR = FIELD_SET(reg, msk, v); + + reg = ucon->CTRLR; + ucon->CTRLR = FIELD_SET(reg, CTRLR_UINT_MASK, CTRLR_UINT_non_PDR); + + printk( "### non_PDR ###\n" + "INTRTXE = 0x%.8X\n" + "INTRRXE = 0x%.8X\n" + "INTRUSBE = 0x%.8X\n" + "INTMSKSETR = 0x%.8X\n", + ucon->INTRTXE, + ucon->INTRRXE, + ucon->INTRUSBE, + ucon->INTMSKSETR); + + reg = ucon->CTRLR; + ucon->CTRLR = FIELD_SET(reg, CTRLR_UINT_MASK, CTRLR_UINT_PDR); + + printk( "### PDR ###\n" + "INTRTXE = 0x%.8X\n" + "INTRRXE = 0x%.8X\n" + "INTRUSBE = 0x%.8X\n" + "INTMSKSETR = 0x%.8X\n", + ucon->INTRTXE, + ucon->INTRRXE, + ucon->INTRUSBE, + ucon->INTMSKSETR); + + // Enable SUSPENDM so that suspend can be seen UTMI signal + reg = ucon->POWER; + ucon->POWER = FIELD_SET(reg, POWER_SUSPENDM_MASK, POWER_SUSPENDM_entry); + + // Clear all pending interrupts + ucon->INTCLRR = reg = ucon->INTSRCR; + #if 0 + reg = ucon->INTRTX | ucon->INTRRX; + printk( "\nINTSRCR = 0x%.8X\n", + ucon->INTSRCR); + + printk( "\n&INTRUSBE = 0x%.8X\n", + &ucon->INTRUSBE); + #endif + + // Set softconn bit + reg = ucon->POWER; + ucon->POWER = FIELD_SET(reg, POWER_SOFTCONN_MASK, POWER_SOFTCONN_yes); + + // Stay here until controller goes in Session + msk = DEVCTL_SESSION_MASK; + while (FIELD_GET(ucon->DEVCTL, msk) == DEVCTL_SESSION_none); + + return AM18X_OK; +} + +uint32_t usb0_intr_state(void) { + uint32_t reg; + + ucon->INTCLRR = reg = ucon->INTSRCR; + return reg; +} + +am18x_rt usb0_intr_clear(void) { + ucon->EOIR = 0x0UL; + return AM18X_OK; +} From a7d5bae90d4c838351bfd91b29bbfa16599f9787 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 10 Jun 2024 19:51:19 +0200 Subject: [PATCH 2/6] lib/am18x-lib: Compile it. --- bricks/_common/arm_none_eabi.mk | 70 +- lib/am18x-lib/inc/am18x_i2c.h | 2 +- lib/am18x-lib/inc/am18x_type.h | 7 +- lib/am18x-lib/lib/arm920t.c | 2 +- lib/am18x-lib/lib/arm920t.h | 12 +- lib/am18x-lib/lib/auxlib.c | 214 ---- lib/am18x-lib/lib/auxlib.h | 6 +- lib/am18x-lib/lib/dvfs.c | 7 +- lib/am18x-lib/lib/i2c_inf.c | 4 +- lib/am18x-lib/lib/uart.c | 82 +- lib/am18x-lib/lib/vsprintf.c | 1786 ------------------------------ lib/am18x-lib/prj/am1808exp.c | 7 +- lib/am18x-lib/prj/am18x_conf.c | 2 +- lib/am18x-lib/src/am18x_dclk.c | 72 +- lib/am18x-lib/src/am18x_ddr.c | 4 +- lib/am18x-lib/src/am18x_edma.c | 4 +- lib/am18x-lib/src/am18x_gpio.c | 8 +- lib/am18x-lib/src/am18x_pll.c | 10 +- lib/am18x-lib/src/am18x_pru.c | 4 +- lib/am18x-lib/src/am18x_psc.c | 6 +- lib/am18x-lib/src/am18x_syscfg.c | 4 +- 21 files changed, 193 insertions(+), 2120 deletions(-) delete mode 100644 lib/am18x-lib/lib/auxlib.c delete mode 100644 lib/am18x-lib/lib/vsprintf.c diff --git a/bricks/_common/arm_none_eabi.mk b/bricks/_common/arm_none_eabi.mk index d5ac000b9..8e38e37a6 100644 --- a/bricks/_common/arm_none_eabi.mk +++ b/bricks/_common/arm_none_eabi.mk @@ -130,6 +130,11 @@ endif ifeq ($(PB_LIB_STM32_USB_DEVICE),1) INC += -I$(PBTOP)/lib/STM32_USB_Device_Library/Core/Inc/ endif +ifeq ($(PB_MCU_FAMILY),TIAM1808) +INC += -I$(PBTOP)/lib/am18x-lib/inc +INC += -I$(PBTOP)/lib/am18x-lib/lib +INC += -I$(PBTOP)/lib/am18x-lib/prj +endif INC += -I$(PBTOP) INC += -I$(BUILD) @@ -153,7 +158,7 @@ ifeq ($(PB_MCU_FAMILY),AT91SAM7) CFLAGS_MCU = -mthumb -mthumb-interwork -mtune=arm7tdmi -mcpu=arm7tdmi -msoft-float else ifeq ($(PB_MCU_FAMILY),TIAM1808) -CFLAGS_MCU = +CFLAGS_MCU = -mcpu=arm926ej-s -mabi=aapcs -gdwarf-2 else $(error unsupported PB_MCU_FAMILY) endif @@ -260,6 +265,57 @@ PY_EXTRA_SRC_C += $(addprefix bricks/ev3/,\ SRC_S += shared/runtime/gchelper_thumb1.s endif +# AM18X-LIB + +AM18X_LIB_PRJ_SRC_C = $(addprefix lib/am18x-lib/prj/,\ + am1808exp.c \ + am18x_conf.c \ + tca6416.c \ + tps6507x.c \ + ) + +AM18X_LIB_SRC_SRC_C = $(addprefix lib/am18x-lib/src/,\ + am18x_aintc.c \ + am18x_ddr.c \ + am18x_edma.c \ + am18x_i2c.c \ + am18x_mmcsd.c \ + am18x_pru.c \ + am18x_rtc.c \ + am18x_timer.c \ + am18x_usb0.c \ + am18x_dclk.c \ + am18x_ecap.c \ + am18x_gpio.c \ + am18x_lcd.c \ + am18x_pll.c \ + am18x_psc.c \ + am18x_syscfg.c \ + am18x_uart.c \ + ) + +AM18X_LIB_LIB_SRC_C = $(addprefix lib/am18x-lib/lib/,\ + arm920t.c \ + ctype.c \ + dvfs.c \ + i2c_inf.c \ + systick.c \ + uart.c \ + ) + +AM18X_LIB_PRJ_SRC_S = $(addprefix lib/am18x-lib/prj/,\ + abt_handler.S \ + uart_dbg.S \ + undef_handler.S \ + ) # excluding start.S for now since it conflics with start.s in platform/startup.s + +AM18X_LIB_LIB_SRC_S = $(addprefix lib/am18x-lib/lib/,\ + arm920t_s.S \ + div64.S \ + lib1funcs.S \ + lshrdi3.S \ + ) + # STM32 Bluetooth stack BLUENRG_SRC_C = $(addprefix lib/BlueNRG-MS/hci/,\ @@ -474,6 +530,18 @@ OBJ += $(addprefix $(BUILD)/, $(NXOS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(NXOS_SRC_S:.s=.o)) endif +ifeq ($(PB_MCU_FAMILY),TIAM1808) +OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_SRC_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_C:.c=.o)) + +OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_S:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_S:.S=.o)) +$(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_S:.S=.o)): CFLAGS += -D__ASSEMBLY__ +$(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_S:.S=.o)): CFLAGS += -D__ASSEMBLY__ + +endif + # List of sources for qstr extraction SRC_QSTR += $(PY_EXTRA_SRC_C) $(PYBRICKS_PYBRICKS_SRC_C) # Append any auto-generated sources that are needed by sources listed in SRC_QSTR diff --git a/lib/am18x-lib/inc/am18x_i2c.h b/lib/am18x-lib/inc/am18x_i2c.h index 394465c27..fcf72650e 100644 --- a/lib/am18x-lib/inc/am18x_i2c.h +++ b/lib/am18x-lib/inc/am18x_i2c.h @@ -54,7 +54,7 @@ am18x_rt i2c_conf(I2C_con_t* icon, i2c_conf_t* conf); static inline int32_t i2c_get_rx(I2C_con_t* icon) { return icon->ICDRR; } -static inline am18x_rt i2c_set_tx(I2C_con_t* icon, uint8_t data) { +static inline am18x_bool i2c_set_tx(I2C_con_t* icon, uint8_t data) { icon->ICDXR = data; return AM18X_TRUE; } diff --git a/lib/am18x-lib/inc/am18x_type.h b/lib/am18x-lib/inc/am18x_type.h index 303c842e8..8ac6f5e6e 100644 --- a/lib/am18x-lib/inc/am18x_type.h +++ b/lib/am18x-lib/inc/am18x_type.h @@ -3,6 +3,9 @@ #ifndef __AM18X_TYPE_H__ #define __AM18X_TYPE_H__ +typedef enum { AM18X_ERR = -1, AM18X_OK = 0} am18x_rt; +typedef enum { AM18X_FALSE = 0, AM18X_TRUE = !AM18X_FALSE} am18x_bool; + #define __USE_STDINT_H #ifdef __USE_STDINT_H @@ -122,9 +125,6 @@ static inline uint32_t __field_xset(uint32_t reg, uint32_t msk, uint32_t vx) { return (reg & ~msk) | ((vx << __ffs(msk)) & msk); } -typedef enum { AM18X_ERR = -1, AM18X_OK = 0} am18x_rt; -typedef enum { AM18X_FALSE = 0, AM18X_TRUE = !AM18X_FALSE} am18x_bool; - #ifndef NULL #define NULL ((void*)0UL) #endif @@ -138,5 +138,4 @@ typedef enum { AM18X_FALSE = 0, AM18X_TRUE = !AM18X_FALSE} am18x_bool; r##_##b##_##bdis = (0x0UL << (of)), \ r##_##b##_##ben = (0x1UL << (of)) - #endif//__AM18X_TYPE_H__ diff --git a/lib/am18x-lib/lib/arm920t.c b/lib/am18x-lib/lib/arm920t.c index c4bc133d4..3f099b827 100644 --- a/lib/am18x-lib/lib/arm920t.c +++ b/lib/am18x-lib/lib/arm920t.c @@ -60,7 +60,7 @@ int arm_mmu_show_control(const cp15_control_t* c1) { unsigned arm_read_cp15_fault_address(void) { unsigned fadr; - asm volatile( + __asm volatile( "mrc p15, 0, %0, c6, c0, 0\n" : "=r"(fadr)); return fadr; diff --git a/lib/am18x-lib/lib/arm920t.h b/lib/am18x-lib/lib/arm920t.h index fffff7588..7a6585684 100644 --- a/lib/am18x-lib/lib/arm920t.h +++ b/lib/am18x-lib/lib/arm920t.h @@ -64,7 +64,7 @@ typedef struct { static inline cp15_id_code_t arm_read_cp15_id_code(void) { cp15_id_code_t c0; - asm volatile( + __asm volatile( "mrc p15, 0, %0, c0, c0, 0\n" : "=r" (c0) ); @@ -99,7 +99,7 @@ typedef struct { static inline cp15_cache_type_t arm_read_cp15_cache_type(void) { cp15_cache_type_t c0; - asm volatile( + __asm volatile( "mrc p15, 0, %0, c0, c0, 1\n" : "=r" (c0) ); @@ -137,14 +137,14 @@ typedef struct { static inline cp15_control_t arm_read_cp15_control(void) { cp15_control_t c1; - asm volatile( + __asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" : "=r" (c1) ); return c1; } static inline cp15_control_t arm_write_cp15_control(cp15_control_t c1) { - asm volatile( + __asm volatile( "mcr p15, 0, %0, c1, c0, 0\n" : "=r" (c1) ); @@ -207,7 +207,7 @@ unsigned arm_read_cp15_fault_address(void); #ifndef __ASSEMBLY__ static inline int arm_wfi(void) { - asm volatile( + __asm volatile( "mov r0, #0\n" "mcr p15, 0, r0, c7, c0, 4\n" /* wait for interrupt */ ::: "r0" @@ -231,7 +231,7 @@ static inline int arm_wfi(void) { #ifndef __ASSEMBLY__ static inline int arm_tlb_invalid_all(void) { - asm volatile( + __asm volatile( "mov r0, #0\n" "mcr p15, 0, r0, c7, c10, 4\n" /* drain WB */ "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate I & D TLBs */ diff --git a/lib/am18x-lib/lib/auxlib.c b/lib/am18x-lib/lib/auxlib.c deleted file mode 100644 index 246a16bac..000000000 --- a/lib/am18x-lib/lib/auxlib.c +++ /dev/null @@ -1,214 +0,0 @@ -// tary 22:35 2011/6/19 -#include -#include "ctype.h" -#include "auxlib.h" -#include "_uart.h" - -#ifndef NULL -#define NULL ((void*)0) -#endif - -extern int vsprintf(char *buf, const char *fmt, va_list args); - -int delay(int d) { - for (;d > 0; d--) { - asm volatile("nop"); - } - return 0; -} - -int puts(const char* s) { - const char* st = s; - while (*s) { - putchar(*s++); - } - return s - st; -} - -int printk(const char* s, ...) { - static char prbuf[1024]; - va_list v; - int r; - - va_start(v, s); - r = vsprintf(prbuf, s, v); - puts(prbuf); - va_end(v); - return r; -} - -int memset(void* dst, int pattern, size_t size) { - char* dstc; - int i; - - dstc = (char*)dst; - for (i = 0; i < size; i++) { - dstc[i] = pattern; - } - return size; -} - -int memcpy(char* dst, const char* src, size_t size) { - int i; - - for (i = 0; i < size; i++) { - dst[i] = src[i]; - } - return size; -} - -size_t strlen(const char* s) { - const char* b = s; - - while (*++s); - return s - b; -} - -size_t strnlen(const char* s, size_t size) { - size_t i; - - for (i = 0; i < size && s[i] != 0; i++); - - return i; -} - -int strcmp(const char* ss, const char* sd) { - for (;*ss && *sd && *ss == *sd; ss++, sd++); - return *ss - *sd; -} - -int strncmp(const char* ss, const char* sd, size_t size) { - size_t i; - for (i = 0; i < size && *ss == *sd && *ss; ss++, sd++, i++); - return *ss - *sd; -} - -const char* strchr(const char* s, char c) { - for (; *s && *s != c; s++); - if (*s == c) { - return s; - } - return NULL; -} - -int debug_buf(const char* head, char* buf, int len) { - int i; - - printk("\nDBG:%s[%d] = \n\t", head, len); - for (i = 0; i < len; i++) { - printk("%.2X ", buf[i]); - if ((i & 0xFUL) == 0xFUL && i != len - 1) { - printk("\n\t"); - } - } - printk("\n"); - return len; -} - -int debug_line(const char* file, int lin, int nr, ...) { - int val = 0; - const char* s; - va_list ap; - - printk("\nDBG:%s() L%d\t", file, lin); - - va_start(ap, nr); - while (nr-- > 0) { - s = va_arg(ap, char*); - if (nr-- <= 0) { - printk(s); - break; - } - val = va_arg(ap, int); - if (strchr(s, '%') == NULL) { - printk("%s=%d", s, val); - } else { - printk(s, val); - } - } - va_end(ap); - printk("\n"); - - return nr; -} - -int dump_regs_word(const char* head, unsigned base, size_t size) { - int i; - - for (i = 0; i < size / sizeof (unsigned long); i++) { - printk("%s[0x%.2X] = 0x%.8X\n", head, i << 2, ((volatile unsigned*)base)[i]); - } - return 0; -} - -// read a unsigned value from bytes [buf, buf + size) -unsigned get_byte_uint(char* buf, int size, int bigend) { - int i; - unsigned r = 0; - unsigned char* ubuf = (unsigned char*)buf; - - if (size > sizeof(unsigned)) size = sizeof(unsigned); - - if (! bigend) { - memcpy((char*)&r, &buf[0], size); - return r; - } - - for(i = 0; i < size; i++) { - r = (r << 8) + ubuf[i]; - } - return r; -} - -// write a unsigned value to bytes [buf, buf + size) -int set_byte_uint(char* buf, int size, unsigned value, int bigend) { - int i; - unsigned r; - - r = value; - if (size > sizeof(unsigned)) size = sizeof(unsigned); - - if (! bigend) { - memcpy(&buf[0], (char*)&r, size); - return r; - } - - for (i = size - 1; i >= 0; i--) { - buf[i] = value & 0xFF; - value >>= 8; - } - return r; -} - -int make_argv(char* s, int size, char *argv[], int av_max) { - char* se; - int n; - - n = 0; - se = s + size - 1; - while (s < se && *s && isspace(*s)) { - s++; - } - - while (s < se && *s && n < av_max - 1) { - if (*s) { - argv[n++] = s; - } - - while (s < se && *s && ! isspace(*s)) { - s++; - } - - if (s < se && *s) { - *s++ = '\0'; - } - - while (s < se && *s && isspace(*s)) { - s++; - } - } - - argv[n] = NULL; - - return n; -} diff --git a/lib/am18x-lib/lib/auxlib.h b/lib/am18x-lib/lib/auxlib.h index e778270fb..31571d15c 100644 --- a/lib/am18x-lib/lib/auxlib.h +++ b/lib/am18x-lib/lib/auxlib.h @@ -30,8 +30,10 @@ typedef struct { // typedef unsigned long size_t; +#define __HAS_STRING_H__ + int delay(int d); -#ifndef __LINUX_STRING_H__ +#ifndef __HAS_STRING_H__ int puts(const char* s); #endif int printk(const char* s, ...); @@ -40,7 +42,7 @@ int sprintf(char * buf, const char *fmt, ...); size_t strlen(const char* s); int strcmp(const char* ss, const char* sd); int strncmp(const char* ss, const char* sd, size_t size); -#ifndef __LINUX_STRING_H__ +#ifndef __HAS_STRING_H__ int memset(void* dst, int pattern, size_t size); int memcpy(char* dst, const char* src, size_t size); #endif diff --git a/lib/am18x-lib/lib/dvfs.c b/lib/am18x-lib/lib/dvfs.c index 13a285f52..76425f2a2 100644 --- a/lib/am18x-lib/lib/dvfs.c +++ b/lib/am18x-lib/lib/dvfs.c @@ -25,7 +25,8 @@ static int abs(int x) { } int dvfs_get_opp(void) { - int i, volt; + int volt; + uint32_t i; if (pll_cmd(PLL0, PLL_CMD_IS_ENABLE, 0) != AM18X_OK) { return 0; @@ -46,14 +47,14 @@ int dvfs_get_opp(void) { // unit, mV int dvfs_get_volt(int opp) { - if (opp < 0 || opp >= countof(opps)) { + if (opp < 0 || opp >= (int) countof(opps)) { return 0; } return opps[opp].volt; } int dvfs_get_freq(int opp) { - if (opp < 0 || opp >= countof(opps)) { + if (opp < 0 || opp >= (int) countof(opps)) { return 0; } return opps[opp].freq; diff --git a/lib/am18x-lib/lib/i2c_inf.c b/lib/am18x-lib/lib/i2c_inf.c index c6e1cb9fe..d297522b6 100644 --- a/lib/am18x-lib/lib/i2c_inf.c +++ b/lib/am18x-lib/lib/i2c_inf.c @@ -50,7 +50,7 @@ int i2c_init(I2C_con_t* bus, uint32_t freq) { } int i2c_read(I2C_con_t* bus, uint16_t dev, uint8_t* bytes, uint32_t cnt) { - int i; + uint32_t i; i2c_conf_t* iconf = bus2conf(bus); iconf->opermode = I2C_OPERMODE_Master_receiver; @@ -76,7 +76,7 @@ int i2c_read(I2C_con_t* bus, uint16_t dev, uint8_t* bytes, uint32_t cnt) { } int i2c_write(I2C_con_t* bus, uint16_t dev, cuint8_t* bytes, uint32_t cnt) { - int i; + uint32_t i; i2c_conf_t* iconf = bus2conf(bus); iconf->opermode = I2C_OPERMODE_Master_transmitter; diff --git a/lib/am18x-lib/lib/uart.c b/lib/am18x-lib/lib/uart.c index 5b4c22a35..fef950571 100644 --- a/lib/am18x-lib/lib/uart.c +++ b/lib/am18x-lib/lib/uart.c @@ -31,49 +31,49 @@ int __putchar(int c) { return c; } -int putchar(int c) { - if (c == UART_LF) { - __putchar(UART_CR); - } - __putchar(c); - return c; -} +// int putchar(int c) { +// if (c == UART_LF) { +// __putchar(UART_CR); +// } +// __putchar(c); +// return c; +// } -int getchar(void) { - while (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)); - return uart_read_byte(UART1); -} +// int getchar(void) { +// while (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)); +// return uart_read_byte(UART1); +// } -int peekchar(void) { - if (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)) { - return -1; - } - return uart_read_byte(UART1); -} +// int peekchar(void) { +// if (AM18X_FALSE == uart_state(UART1, STATE_RX_READY)) { +// return -1; +// } +// return uart_read_byte(UART1); +// } -int uart_gets(char *line, int n) { - int cnt = 0; - char c; +// int uart_gets(char *line, int n) { +// int cnt = 0; +// char c; - do { - if ((c = getchar()) == UART_CR) { - c = UART_LF; /* read character */ - } +// do { +// if ((c = getchar()) == UART_CR) { +// c = UART_LF; /* read character */ +// } - if (c != UART_BACKSPACE && c != UART_DEL) { /* process backspace */ - cnt++; - *line++ = c; - if (c != UART_LF) { /* echo and store character */ - putchar(c); - } - } else if (cnt != 0) { - cnt--; - line--; - putchar(UART_BACKSPACE); /* echo backspace */ - putchar(' '); - putchar(UART_BACKSPACE); - } - } while (cnt < n - 1 && c != UART_LF); /* check limit and line feed */ - *line = 0; /* mark end of string */ - return cnt; -} +// if (c != UART_BACKSPACE && c != UART_DEL) { /* process backspace */ +// cnt++; +// *line++ = c; +// if (c != UART_LF) { /* echo and store character */ +// putchar(c); +// } +// } else if (cnt != 0) { +// cnt--; +// line--; +// putchar(UART_BACKSPACE); /* echo backspace */ +// putchar(' '); +// putchar(UART_BACKSPACE); +// } +// } while (cnt < n - 1 && c != UART_LF); /* check limit and line feed */ +// *line = 0; /* mark end of string */ +// return cnt; +// } diff --git a/lib/am18x-lib/lib/vsprintf.c b/lib/am18x-lib/lib/vsprintf.c deleted file mode 100644 index ece55bb18..000000000 --- a/lib/am18x-lib/lib/vsprintf.c +++ /dev/null @@ -1,1786 +0,0 @@ -/* - * linux/lib/vsprintf.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ -/* - * Fri Jul 13 2001 Crutcher Dunnavant - * - changed to provide snprintf and vsnprintf functions - * So Feb 1 16:51:32 CET 2004 Juergen Quade - * - scnprintf and vscnprintf - */ -#include -#include -#include -#include -#include "linkage.h" -#include "ctype.h" -#include "div64.h" - -#define EINVAL 1 -#define PAGE_SIZE 0x20 - -/* Works only for digits and letters, but small and fast */ -#define TOLOWER(x) ((x) | 0x20) - -static unsigned int simple_guess_base(const char *cp) -{ - if (cp[0] == '0') { - if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) - return 16; - else - return 8; - } else { - return 10; - } -} - -/** - * simple_strtoul - convert a string to an unsigned long - * @cp: The start of the string - * @endp: A pointer to the end of the parsed string will be placed here - * @base: The number base to use - */ -unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) -{ - unsigned long result = 0; - - if (!base) - base = simple_guess_base(cp); - - if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') - cp += 2; - - while (isxdigit(*cp)) { - unsigned int value; - - value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; - if (value >= base) - break; - result = result * base + value; - cp++; - } - - if (endp) - *endp = (char *)cp; - return result; -} -EXPORT_SYMBOL(simple_strtoul); - -/** - * simple_strtol - convert a string to a signed long - * @cp: The start of the string - * @endp: A pointer to the end of the parsed string will be placed here - * @base: The number base to use - */ -long simple_strtol(const char *cp, char **endp, unsigned int base) -{ - if(*cp == '-') - return -simple_strtoul(cp + 1, endp, base); - return simple_strtoul(cp, endp, base); -} -EXPORT_SYMBOL(simple_strtol); - -/** - * simple_strtoull - convert a string to an unsigned long long - * @cp: The start of the string - * @endp: A pointer to the end of the parsed string will be placed here - * @base: The number base to use - */ -unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) -{ - unsigned long long result = 0; - - if (!base) - base = simple_guess_base(cp); - - if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') - cp += 2; - - while (isxdigit(*cp)) { - unsigned int value; - - value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; - if (value >= base) - break; - result = result * base + value; - cp++; - } - - if (endp) - *endp = (char *)cp; - return result; -} -EXPORT_SYMBOL(simple_strtoull); - -/** - * simple_strtoll - convert a string to a signed long long - * @cp: The start of the string - * @endp: A pointer to the end of the parsed string will be placed here - * @base: The number base to use - */ -long long simple_strtoll(const char *cp, char **endp, unsigned int base) -{ - if(*cp=='-') - return -simple_strtoull(cp + 1, endp, base); - return simple_strtoull(cp, endp, base); -} - -/** - * strict_strtoul - convert a string to an unsigned long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtoul converts a string to an unsigned long only if the - * string is really an unsigned long string, any string containing - * any invalid char at the tail will be rejected and -EINVAL is returned, - * only a newline char at the tail is acceptible because people generally - * change a module parameter in the following way: - * - * echo 1024 > /sys/module/e1000/parameters/copybreak - * - * echo will append a newline to the tail. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - * - * simple_strtoul just ignores the successive invalid characters and - * return the converted value of prefix part of the string. - */ -int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) -{ - char *tail; - unsigned long val; - size_t len; - - *res = 0; - len = strlen(cp); - if (len == 0) - return -EINVAL; - - val = simple_strtoul(cp, &tail, base); - if (tail == cp) - return -EINVAL; - if ((*tail == '\0') || - ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { - *res = val; - return 0; - } - - return -EINVAL; -} -EXPORT_SYMBOL(strict_strtoul); - -/** - * strict_strtol - convert a string to a long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtol is similiar to strict_strtoul, but it allows the first - * character of a string is '-'. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - */ -int strict_strtol(const char *cp, unsigned int base, long *res) -{ - int ret; - if (*cp == '-') { - ret = strict_strtoul(cp + 1, base, (unsigned long *)res); - if (!ret) - *res = -(*res); - } else { - ret = strict_strtoul(cp, base, (unsigned long *)res); - } - - return ret; -} -EXPORT_SYMBOL(strict_strtol); - -/** - * strict_strtoull - convert a string to an unsigned long long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtoull converts a string to an unsigned long long only if the - * string is really an unsigned long long string, any string containing - * any invalid char at the tail will be rejected and -EINVAL is returned, - * only a newline char at the tail is acceptible because people generally - * change a module parameter in the following way: - * - * echo 1024 > /sys/module/e1000/parameters/copybreak - * - * echo will append a newline to the tail of the string. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - * - * simple_strtoull just ignores the successive invalid characters and - * return the converted value of prefix part of the string. - */ -int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res) -{ - char *tail; - unsigned long long val; - size_t len; - - *res = 0; - len = strlen(cp); - if (len == 0) - return -EINVAL; - - val = simple_strtoull(cp, &tail, base); - if (tail == cp) - return -EINVAL; - if ((*tail == '\0') || - ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) { - *res = val; - return 0; - } - - return -EINVAL; -} -EXPORT_SYMBOL(strict_strtoull); - -/** - * strict_strtoll - convert a string to a long long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtoll is similiar to strict_strtoull, but it allows the first - * character of a string is '-'. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - */ -int strict_strtoll(const char *cp, unsigned int base, long long *res) -{ - int ret; - if (*cp == '-') { - ret = strict_strtoull(cp + 1, base, (unsigned long long *)res); - if (!ret) - *res = -(*res); - } else { - ret = strict_strtoull(cp, base, (unsigned long long *)res); - } - - return ret; -} -EXPORT_SYMBOL(strict_strtoll); - -static int skip_atoi(const char **s) -{ - int i=0; - - while (isdigit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -/* Decimal conversion is by far the most typical, and is used - * for /proc and /sys data. This directly impacts e.g. top performance - * with many processes running. We optimize it for speed - * using code from - * http://www.cs.uiowa.edu/~jones/bcd/decimal.html - * (with permission from the author, Douglas W. Jones). */ - -/* Formats correctly any integer in [0,99999]. - * Outputs from one to five digits depending on input. - * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ -static char* put_dec_trunc(char *buf, unsigned q) -{ - unsigned d3, d2, d1, d0; - d1 = (q>>4) & 0xf; - d2 = (q>>8) & 0xf; - d3 = (q>>12); - - d0 = 6*(d3 + d2 + d1) + (q & 0xf); - q = (d0 * 0xcd) >> 11; - d0 = d0 - 10*q; - *buf++ = d0 + '0'; /* least significant digit */ - d1 = q + 9*d3 + 5*d2 + d1; - if (d1 != 0) { - q = (d1 * 0xcd) >> 11; - d1 = d1 - 10*q; - *buf++ = d1 + '0'; /* next digit */ - - d2 = q + 2*d2; - if ((d2 != 0) || (d3 != 0)) { - q = (d2 * 0xd) >> 7; - d2 = d2 - 10*q; - *buf++ = d2 + '0'; /* next digit */ - - d3 = q + 4*d3; - if (d3 != 0) { - q = (d3 * 0xcd) >> 11; - d3 = d3 - 10*q; - *buf++ = d3 + '0'; /* next digit */ - if (q != 0) - *buf++ = q + '0'; /* most sign. digit */ - } - } - } - return buf; -} -/* Same with if's removed. Always emits five digits */ -static char* put_dec_full(char *buf, unsigned q) -{ - /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ - /* but anyway, gcc produces better code with full-sized ints */ - unsigned d3, d2, d1, d0; - d1 = (q>>4) & 0xf; - d2 = (q>>8) & 0xf; - d3 = (q>>12); - - /* Possible ways to approx. divide by 10 */ - /* gcc -O2 replaces multiply with shifts and adds */ - // (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) - // (x * 0x67) >> 10: 1100111 - // (x * 0x34) >> 9: 110100 - same - // (x * 0x1a) >> 8: 11010 - same - // (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) - - d0 = 6*(d3 + d2 + d1) + (q & 0xf); - q = (d0 * 0xcd) >> 11; - d0 = d0 - 10*q; - *buf++ = d0 + '0'; - d1 = q + 9*d3 + 5*d2 + d1; - q = (d1 * 0xcd) >> 11; - d1 = d1 - 10*q; - *buf++ = d1 + '0'; - - d2 = q + 2*d2; - q = (d2 * 0xd) >> 7; - d2 = d2 - 10*q; - *buf++ = d2 + '0'; - - d3 = q + 4*d3; - q = (d3 * 0xcd) >> 11; /* - shorter code */ - /* q = (d3 * 0x67) >> 10; - would also work */ - d3 = d3 - 10*q; - *buf++ = d3 + '0'; - *buf++ = q + '0'; - return buf; -} - -/* No inlining helps gcc to use registers better */ -static char* put_dec(char *buf, unsigned long long num) -{ - while (1) { - unsigned rem; - if (num < 100000) - return put_dec_trunc(buf, num); - rem = do_div(num, 100000); - buf = put_dec_full(buf, rem); - } -} - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SMALL 32 /* Must be 32 == 0x20 */ -#define SPECIAL 64 /* 0x */ - -enum format_type { - FORMAT_TYPE_NONE, /* Just a string part */ - FORMAT_TYPE_WIDTH, - FORMAT_TYPE_PRECISION, - FORMAT_TYPE_CHAR, - FORMAT_TYPE_STR, - FORMAT_TYPE_PTR, - FORMAT_TYPE_PERCENT_CHAR, - FORMAT_TYPE_INVALID, - FORMAT_TYPE_LONG_LONG, - FORMAT_TYPE_ULONG, - FORMAT_TYPE_LONG, - FORMAT_TYPE_UBYTE, - FORMAT_TYPE_BYTE, - FORMAT_TYPE_USHORT, - FORMAT_TYPE_SHORT, - FORMAT_TYPE_UINT, - FORMAT_TYPE_INT, - FORMAT_TYPE_NRCHARS, - FORMAT_TYPE_SIZE_T, - FORMAT_TYPE_PTRDIFF -}; - -struct printf_spec { - enum format_type type; - int flags; /* flags to number() */ - int field_width; /* width of output field */ - int base; - int precision; /* # of digits/chars */ - int qualifier; -}; - -static char *number(char *buf, char *end, unsigned long long num, - struct printf_spec spec) -{ - /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ - static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ - - char tmp[66]; - char sign; - char locase; - int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); - int i; - - /* locase = 0 or 0x20. ORing digits or letters with 'locase' - * produces same digits or (maybe lowercased) letters */ - locase = (spec.flags & SMALL); - if (spec.flags & LEFT) - spec.flags &= ~ZEROPAD; - sign = 0; - if (spec.flags & SIGN) { - if ((signed long long) num < 0) { - sign = '-'; - num = - (signed long long) num; - spec.field_width--; - } else if (spec.flags & PLUS) { - sign = '+'; - spec.field_width--; - } else if (spec.flags & SPACE) { - sign = ' '; - spec.field_width--; - } - } - if (need_pfx) { - spec.field_width--; - if (spec.base == 16) - spec.field_width--; - } - - /* generate full string in tmp[], in reverse order */ - i = 0; - if (num == 0) - tmp[i++] = '0'; - /* Generic code, for any base: - else do { - tmp[i++] = (digits[do_div(num,base)] | locase); - } while (num != 0); - */ - else if (spec.base != 10) { /* 8 or 16 */ - int mask = spec.base - 1; - int shift = 3; - if (spec.base == 16) shift = 4; - do { - tmp[i++] = (digits[((unsigned char)num) & mask] | locase); - num >>= shift; - } while (num); - } else { /* base 10 */ - i = put_dec(tmp, num) - tmp; - } - - /* printing 100 using %2d gives "100", not "00" */ - if (i > spec.precision) - spec.precision = i; - /* leading space padding */ - spec.field_width -= spec.precision; - if (!(spec.flags & (ZEROPAD+LEFT))) { - while(--spec.field_width >= 0) { - if (buf < end) - *buf = ' '; - ++buf; - } - } - /* sign */ - if (sign) { - if (buf < end) - *buf = sign; - ++buf; - } - /* "0x" / "0" prefix */ - if (need_pfx) { - if (buf < end) - *buf = '0'; - ++buf; - if (spec.base == 16) { - if (buf < end) - *buf = ('X' | locase); - ++buf; - } - } - /* zero or space padding */ - if (!(spec.flags & LEFT)) { - char c = (spec.flags & ZEROPAD) ? '0' : ' '; - while (--spec.field_width >= 0) { - if (buf < end) - *buf = c; - ++buf; - } - } - /* hmm even more zero padding? */ - while (i <= --spec.precision) { - if (buf < end) - *buf = '0'; - ++buf; - } - /* actual digits of result */ - while (--i >= 0) { - if (buf < end) - *buf = tmp[i]; - ++buf; - } - /* trailing space padding */ - while (--spec.field_width >= 0) { - if (buf < end) - *buf = ' '; - ++buf; - } - return buf; -} - -static char *string(char *buf, char *end, char *s, struct printf_spec spec) -{ - int len, i; - - if ((unsigned long)s < PAGE_SIZE) - s = ""; - - len = strnlen(s, spec.precision); - - if (!(spec.flags & LEFT)) { - while (len < spec.field_width--) { - if (buf < end) - *buf = ' '; - ++buf; - } - } - for (i = 0; i < len; ++i) { - if (buf < end) - *buf = *s; - ++buf; ++s; - } - while (len < spec.field_width--) { - if (buf < end) - *buf = ' '; - ++buf; - } - return buf; -} - -static char *symbol_string(char *buf, char *end, void *ptr, - struct printf_spec spec, char ext) -{ - unsigned long value = (unsigned long) ptr; -#ifdef CONFIG_KALLSYMS - char sym[KSYM_SYMBOL_LEN]; - if (ext != 'f') - sprint_symbol(sym, value); - else - kallsyms_lookup(value, NULL, NULL, NULL, sym); - return string(buf, end, sym, spec); -#else - spec.field_width = 2*sizeof(void *); - spec.flags |= SPECIAL | SMALL | ZEROPAD; - spec.base = 16; - return number(buf, end, value, spec); -#endif -} - - - -static char *ip4_addr_string(char *buf, char *end, uint8_t *addr, - struct printf_spec spec) -{ - char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */ - char temp[3]; /* hold each IP quad in reverse order */ - char *p = ip4_addr; - int i, digits; - - for (i = 0; i < 4; i++) { - digits = put_dec_trunc(temp, addr[i]) - temp; - /* reverse the digits in the quad */ - while (digits--) - *p++ = temp[digits]; - if (i != 3) - *p++ = '.'; - } - *p = '\0'; - spec.flags &= ~SPECIAL; - - return string(buf, end, ip4_addr, spec); -} - -/* - * Show a '%p' thing. A kernel extension is that the '%p' is followed - * by an extra set of alphanumeric characters that are extended format - * specifiers. - * - * Right now we handle: - * - * - 'F' For symbolic function descriptor pointers with offset - * - 'f' For simple symbolic function names without offset - * - 'S' For symbolic direct pointers - * - 'R' For a struct resource pointer, it prints the range of - * addresses (not the name nor the flags) - * - 'M' For a 6-byte MAC address, it prints the address in the - * usual colon-separated hex notation - * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated - * decimal for v4 and colon separated network-order 16 bit hex for v6) - * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is - * currently the same - * - * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 - * function pointers are really function descriptors, which contain a - * pointer to the real address. - */ -static char *pointer(const char *fmt, char *buf, char *end, void *ptr, - struct printf_spec spec) -{ - if (!ptr) - return string(buf, end, "(null)", spec); - - switch (*fmt) { - case 'S': - return symbol_string(buf, end, ptr, spec, *fmt); - case 'm': - spec.flags |= SPECIAL; - /* Fallthrough */ - case 'i': - spec.flags |= SPECIAL; - /* Fallthrough */ - case 'I': - if (fmt[1] == '4') - return ip4_addr_string(buf, end, ptr, spec); - spec.flags &= ~SPECIAL; - break; - } - spec.flags |= SMALL; - if (spec.field_width == -1) { - spec.field_width = 2*sizeof(void *); - spec.flags |= ZEROPAD; - } - spec.base = 16; - - return number(buf, end, (unsigned long) ptr, spec); -} - -/* - * Helper function to decode printf style format. - * Each call decode a token from the format and return the - * number of characters read (or likely the delta where it wants - * to go on the next call). - * The decoded token is returned through the parameters - * - * 'h', 'l', or 'L' for integer fields - * 'z' support added 23/7/1999 S.H. - * 'z' changed to 'Z' --davidm 1/25/99 - * 't' added for ptrdiff_t - * - * @fmt: the format string - * @type of the token returned - * @flags: various flags such as +, -, # tokens.. - * @field_width: overwritten width - * @base: base of the number (octal, hex, ...) - * @precision: precision of a number - * @qualifier: qualifier of a number (long, size_t, ...) - */ -static int format_decode(const char *fmt, struct printf_spec *spec) -{ - const char *start = fmt; - - /* we finished early by reading the field width */ - if (spec->type == FORMAT_TYPE_WIDTH) { - if (spec->field_width < 0) { - spec->field_width = -spec->field_width; - spec->flags |= LEFT; - } - spec->type = FORMAT_TYPE_NONE; - goto precision; - } - - /* we finished early by reading the precision */ - if (spec->type == FORMAT_TYPE_PRECISION) { - if (spec->precision < 0) - spec->precision = 0; - - spec->type = FORMAT_TYPE_NONE; - goto qualifier; - } - - /* By default */ - spec->type = FORMAT_TYPE_NONE; - - for (; *fmt ; ++fmt) { - if (*fmt == '%') - break; - } - - /* Return the current non-format string */ - if (fmt != start || !*fmt) - return fmt - start; - - /* Process flags */ - spec->flags = 0; - - while (1) { /* this also skips first '%' */ - int found = 1; - - ++fmt; - - switch (*fmt) { - case '-': spec->flags |= LEFT; break; - case '+': spec->flags |= PLUS; break; - case ' ': spec->flags |= SPACE; break; - case '#': spec->flags |= SPECIAL; break; - case '0': spec->flags |= ZEROPAD; break; - default: found = 0; - } - - if (!found) - break; - } - - /* get field width */ - spec->field_width = -1; - - if (isdigit(*fmt)) - spec->field_width = skip_atoi(&fmt); - else if (*fmt == '*') { - /* it's the next argument */ - spec->type = FORMAT_TYPE_WIDTH; - return ++fmt - start; - } - -precision: - /* get the precision */ - spec->precision = -1; - if (*fmt == '.') { - ++fmt; - if (isdigit(*fmt)) { - spec->precision = skip_atoi(&fmt); - if (spec->precision < 0) - spec->precision = 0; - } else if (*fmt == '*') { - /* it's the next argument */ - spec->type = FORMAT_TYPE_PRECISION; - return ++fmt - start; - } - } - -qualifier: - /* get the conversion qualifier */ - spec->qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || - *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { - spec->qualifier = *fmt++; - if (unlikely(spec->qualifier == *fmt)) { - if (spec->qualifier == 'l') { - spec->qualifier = 'L'; - ++fmt; - } else if (spec->qualifier == 'h') { - spec->qualifier = 'H'; - ++fmt; - } - } - } - - /* default base */ - spec->base = 10; - switch (*fmt) { - case 'c': - spec->type = FORMAT_TYPE_CHAR; - return ++fmt - start; - - case 's': - spec->type = FORMAT_TYPE_STR; - return ++fmt - start; - - case 'p': - spec->type = FORMAT_TYPE_PTR; - return fmt - start; - /* skip alnum */ - - case 'n': - spec->type = FORMAT_TYPE_NRCHARS; - return ++fmt - start; - - case '%': - spec->type = FORMAT_TYPE_PERCENT_CHAR; - return ++fmt - start; - - /* integer number formats - set up the flags and "break" */ - case 'o': - spec->base = 8; - break; - - case 'x': - spec->flags |= SMALL; - - case 'X': - spec->base = 16; - break; - - case 'd': - case 'i': - spec->flags |= SIGN; - case 'u': - break; - - default: - spec->type = FORMAT_TYPE_INVALID; - return fmt - start; - } - - if (spec->qualifier == 'L') - spec->type = FORMAT_TYPE_LONG_LONG; - else if (spec->qualifier == 'l') { - if (spec->flags & SIGN) - spec->type = FORMAT_TYPE_LONG; - else - spec->type = FORMAT_TYPE_ULONG; - } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') { - spec->type = FORMAT_TYPE_SIZE_T; - } else if (spec->qualifier == 't') { - spec->type = FORMAT_TYPE_PTRDIFF; - } else if (spec->qualifier == 'H') { - if (spec->flags & SIGN) - spec->type = FORMAT_TYPE_BYTE; - else - spec->type = FORMAT_TYPE_UBYTE; - } else if (spec->qualifier == 'h') { - if (spec->flags & SIGN) - spec->type = FORMAT_TYPE_SHORT; - else - spec->type = FORMAT_TYPE_USHORT; - } else { - if (spec->flags & SIGN) - spec->type = FORMAT_TYPE_INT; - else - spec->type = FORMAT_TYPE_UINT; - } - - return ++fmt - start; -} - -/** - * vsnprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @args: Arguments for the format string - * - * This function follows C99 vsnprintf, but has some extensions: - * %pS output the name of a text symbol - * %pF output the name of a function pointer with its offset - * %pf output the name of a function pointer without its offset - * %pR output the address range in a struct resource - * - * The return value is the number of characters which would - * be generated for the given input, excluding the trailing - * '\0', as per ISO C99. If you want to have the exact - * number of characters written into @buf as return value - * (not including the trailing '\0'), use vscnprintf(). If the - * return is greater than or equal to @size, the resulting - * string is truncated. - * - * Call this function if you are already dealing with a va_list. - * You probably want snprintf() instead. - */ -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) -{ - unsigned long long num; - char *str, *end, c; - int read; - struct printf_spec spec = {0}; - - /* Reject out-of-range values early. Large positive sizes are - used for unknown buffer sizes. */ - if (unlikely((int) size < 0)) { - /* There can be only one.. */ - static char warn = 1; - WARN_ON(warn); - warn = 0; - return 0; - } - - str = buf; - end = buf + size; - - /* Make sure end is always >= buf */ - if (end < buf) { - end = ((void *)-1); - size = end - buf; - } - - while (*fmt) { - const char *old_fmt = fmt; - - read = format_decode(fmt, &spec); - - fmt += read; - - switch (spec.type) { - case FORMAT_TYPE_NONE: { - int copy = read; - if (str < end) { - if (copy > end - str) - copy = end - str; - memcpy(str, old_fmt, copy); - } - str += read; - break; - } - - case FORMAT_TYPE_WIDTH: - spec.field_width = va_arg(args, int); - break; - - case FORMAT_TYPE_PRECISION: - spec.precision = va_arg(args, int); - break; - - case FORMAT_TYPE_CHAR: - if (!(spec.flags & LEFT)) { - while (--spec.field_width > 0) { - if (str < end) - *str = ' '; - ++str; - - } - } - c = (unsigned char) va_arg(args, int); - if (str < end) - *str = c; - ++str; - while (--spec.field_width > 0) { - if (str < end) - *str = ' '; - ++str; - } - break; - - case FORMAT_TYPE_STR: - str = string(str, end, va_arg(args, char *), spec); - break; - - case FORMAT_TYPE_PTR: - str = pointer(fmt+1, str, end, va_arg(args, void *), - spec); - while (isalnum(*fmt)) - fmt++; - break; - - case FORMAT_TYPE_PERCENT_CHAR: - if (str < end) - *str = '%'; - ++str; - break; - - case FORMAT_TYPE_INVALID: - if (str < end) - *str = '%'; - ++str; - break; - - case FORMAT_TYPE_NRCHARS: { - int qualifier = spec.qualifier; - - if (qualifier == 'l') { - long *ip = va_arg(args, long *); - *ip = (str - buf); - } else if (qualifier == 'Z' || - qualifier == 'z') { - size_t *ip = va_arg(args, size_t *); - *ip = (str - buf); - } else { - int *ip = va_arg(args, int *); - *ip = (str - buf); - } - break; - } - - default: - switch (spec.type) { - case FORMAT_TYPE_LONG_LONG: - num = va_arg(args, long long); - break; - case FORMAT_TYPE_ULONG: - num = va_arg(args, unsigned long); - break; - case FORMAT_TYPE_LONG: - num = va_arg(args, long); - break; - case FORMAT_TYPE_SIZE_T: - num = va_arg(args, size_t); - break; - case FORMAT_TYPE_PTRDIFF: - num = va_arg(args, unsigned long); - break; - case FORMAT_TYPE_UBYTE: - num = (unsigned char) va_arg(args, int); - break; - case FORMAT_TYPE_BYTE: - num = (signed char) va_arg(args, int); - break; - case FORMAT_TYPE_USHORT: - num = (unsigned short) va_arg(args, int); - break; - case FORMAT_TYPE_SHORT: - num = (short) va_arg(args, int); - break; - case FORMAT_TYPE_INT: - num = (int) va_arg(args, int); - break; - default: - num = va_arg(args, unsigned int); - } - - str = number(str, end, num, spec); - } - } - - if (size > 0) { - if (str < end) - *str = '\0'; - else - end[-1] = '\0'; - } - - /* the trailing null byte doesn't count towards the total */ - return str-buf; - -} -EXPORT_SYMBOL(vsnprintf); - -/** - * vscnprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @args: Arguments for the format string - * - * The return value is the number of characters which have been written into - * the @buf not including the trailing '\0'. If @size is <= 0 the function - * returns 0. - * - * Call this function if you are already dealing with a va_list. - * You probably want scnprintf() instead. - * - * See the vsnprintf() documentation for format string extensions over C99. - */ -int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) -{ - int i; - - i=vsnprintf(buf,size,fmt,args); - return (i >= size) ? (size - 1) : i; -} -EXPORT_SYMBOL(vscnprintf); - -/** - * snprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @...: Arguments for the format string - * - * The return value is the number of characters which would be - * generated for the given input, excluding the trailing null, - * as per ISO C99. If the return is greater than or equal to - * @size, the resulting string is truncated. - * - * See the vsnprintf() documentation for format string extensions over C99. - */ -int snprintf(char * buf, size_t size, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=vsnprintf(buf,size,fmt,args); - va_end(args); - return i; -} -EXPORT_SYMBOL(snprintf); - -/** - * scnprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @...: Arguments for the format string - * - * The return value is the number of characters written into @buf not including - * the trailing '\0'. If @size is <= 0 the function returns 0. - */ - -int scnprintf(char * buf, size_t size, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i = vsnprintf(buf, size, fmt, args); - va_end(args); - return (i >= size) ? (size - 1) : i; -} -EXPORT_SYMBOL(scnprintf); - -/** - * vsprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @fmt: The format string to use - * @args: Arguments for the format string - * - * The function returns the number of characters written - * into @buf. Use vsnprintf() or vscnprintf() in order to avoid - * buffer overflows. - * - * Call this function if you are already dealing with a va_list. - * You probably want sprintf() instead. - * - * See the vsnprintf() documentation for format string extensions over C99. - */ -int vsprintf(char *buf, const char *fmt, va_list args) -{ - return vsnprintf(buf, INT_MAX, fmt, args); -} -EXPORT_SYMBOL(vsprintf); - -/** - * sprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @fmt: The format string to use - * @...: Arguments for the format string - * - * The function returns the number of characters written - * into @buf. Use snprintf() or scnprintf() in order to avoid - * buffer overflows. - * - * See the vsnprintf() documentation for format string extensions over C99. - */ -int sprintf(char * buf, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=vsnprintf(buf, INT_MAX, fmt, args); - va_end(args); - return i; -} -EXPORT_SYMBOL(sprintf); - -#ifdef CONFIG_BINARY_PRINTF -/* - * bprintf service: - * vbin_printf() - VA arguments to binary data - * bstr_printf() - Binary data to text string - */ - -/** - * vbin_printf - Parse a format string and place args' binary value in a buffer - * @bin_buf: The buffer to place args' binary value - * @size: The size of the buffer(by words(32bits), not characters) - * @fmt: The format string to use - * @args: Arguments for the format string - * - * The format follows C99 vsnprintf, except %n is ignored, and its argument - * is skiped. - * - * The return value is the number of words(32bits) which would be generated for - * the given input. - * - * NOTE: - * If the return value is greater than @size, the resulting bin_buf is NOT - * valid for bstr_printf(). - */ -int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) -{ - struct printf_spec spec = {0}; - char *str, *end; - int read; - - str = (char *)bin_buf; - end = (char *)(bin_buf + size); - -#define save_arg(type) \ -do { \ - if (sizeof(type) == 8) { \ - unsigned long long value; \ - str = PTR_ALIGN(str, sizeof(u32)); \ - value = va_arg(args, unsigned long long); \ - if (str + sizeof(type) <= end) { \ - *(u32 *)str = *(u32 *)&value; \ - *(u32 *)(str + 4) = *((u32 *)&value + 1); \ - } \ - } else { \ - unsigned long value; \ - str = PTR_ALIGN(str, sizeof(type)); \ - value = va_arg(args, int); \ - if (str + sizeof(type) <= end) \ - *(typeof(type) *)str = (type)value; \ - } \ - str += sizeof(type); \ -} while (0) - - - while (*fmt) { - read = format_decode(fmt, &spec); - - fmt += read; - - switch (spec.type) { - case FORMAT_TYPE_NONE: - break; - - case FORMAT_TYPE_WIDTH: - case FORMAT_TYPE_PRECISION: - save_arg(int); - break; - - case FORMAT_TYPE_CHAR: - save_arg(char); - break; - - case FORMAT_TYPE_STR: { - const char *save_str = va_arg(args, char *); - size_t len; - if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE - || (unsigned long)save_str < PAGE_SIZE) - save_str = ""; - len = strlen(save_str); - if (str + len + 1 < end) - memcpy(str, save_str, len + 1); - str += len + 1; - break; - } - - case FORMAT_TYPE_PTR: - save_arg(void *); - /* skip all alphanumeric pointer suffixes */ - while (isalnum(*fmt)) - fmt++; - break; - - case FORMAT_TYPE_PERCENT_CHAR: - break; - - case FORMAT_TYPE_INVALID: - break; - - case FORMAT_TYPE_NRCHARS: { - /* skip %n 's argument */ - int qualifier = spec.qualifier; - void *skip_arg; - if (qualifier == 'l') - skip_arg = va_arg(args, long *); - else if (qualifier == 'Z' || qualifier == 'z') - skip_arg = va_arg(args, size_t *); - else - skip_arg = va_arg(args, int *); - break; - } - - default: - switch (spec.type) { - - case FORMAT_TYPE_LONG_LONG: - save_arg(long long); - break; - case FORMAT_TYPE_ULONG: - case FORMAT_TYPE_LONG: - save_arg(unsigned long); - break; - case FORMAT_TYPE_SIZE_T: - save_arg(size_t); - break; - case FORMAT_TYPE_PTRDIFF: - save_arg(ptrdiff_t); - break; - case FORMAT_TYPE_UBYTE: - case FORMAT_TYPE_BYTE: - save_arg(char); - break; - case FORMAT_TYPE_USHORT: - case FORMAT_TYPE_SHORT: - save_arg(short); - break; - default: - save_arg(int); - } - } - } - return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; - -#undef save_arg -} -EXPORT_SYMBOL_GPL(vbin_printf); - -/** - * bstr_printf - Format a string from binary arguments and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space - * @fmt: The format string to use - * @bin_buf: Binary arguments for the format string - * - * This function like C99 vsnprintf, but the difference is that vsnprintf gets - * arguments from stack, and bstr_printf gets arguments from @bin_buf which is - * a binary buffer that generated by vbin_printf. - * - * The format follows C99 vsnprintf, but has some extensions: - * %pS output the name of a text symbol - * %pF output the name of a function pointer with its offset - * %pf output the name of a function pointer without its offset - * %pR output the address range in a struct resource - * %n is ignored - * - * The return value is the number of characters which would - * be generated for the given input, excluding the trailing - * '\0', as per ISO C99. If you want to have the exact - * number of characters written into @buf as return value - * (not including the trailing '\0'), use vscnprintf(). If the - * return is greater than or equal to @size, the resulting - * string is truncated. - */ -int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) -{ - unsigned long long num; - char *str, *end, c; - const char *args = (const char *)bin_buf; - - struct printf_spec spec = {0}; - - if (unlikely((int) size < 0)) { - /* There can be only one.. */ - static char warn = 1; - WARN_ON(warn); - warn = 0; - return 0; - } - - str = buf; - end = buf + size; - -#define get_arg(type) \ -({ \ - typeof(type) value; \ - if (sizeof(type) == 8) { \ - args = PTR_ALIGN(args, sizeof(u32)); \ - *(u32 *)&value = *(u32 *)args; \ - *((u32 *)&value + 1) = *(u32 *)(args + 4); \ - } else { \ - args = PTR_ALIGN(args, sizeof(type)); \ - value = *(typeof(type) *)args; \ - } \ - args += sizeof(type); \ - value; \ -}) - - /* Make sure end is always >= buf */ - if (end < buf) { - end = ((void *)-1); - size = end - buf; - } - - while (*fmt) { - int read; - const char *old_fmt = fmt; - - read = format_decode(fmt, &spec); - - fmt += read; - - switch (spec.type) { - case FORMAT_TYPE_NONE: { - int copy = read; - if (str < end) { - if (copy > end - str) - copy = end - str; - memcpy(str, old_fmt, copy); - } - str += read; - break; - } - - case FORMAT_TYPE_WIDTH: - spec.field_width = get_arg(int); - break; - - case FORMAT_TYPE_PRECISION: - spec.precision = get_arg(int); - break; - - case FORMAT_TYPE_CHAR: - if (!(spec.flags & LEFT)) { - while (--spec.field_width > 0) { - if (str < end) - *str = ' '; - ++str; - } - } - c = (unsigned char) get_arg(char); - if (str < end) - *str = c; - ++str; - while (--spec.field_width > 0) { - if (str < end) - *str = ' '; - ++str; - } - break; - - case FORMAT_TYPE_STR: { - const char *str_arg = args; - size_t len = strlen(str_arg); - args += len + 1; - str = string(str, end, (char *)str_arg, spec); - break; - } - - case FORMAT_TYPE_PTR: - str = pointer(fmt+1, str, end, get_arg(void *), spec); - while (isalnum(*fmt)) - fmt++; - break; - - case FORMAT_TYPE_PERCENT_CHAR: - if (str < end) - *str = '%'; - ++str; - break; - - case FORMAT_TYPE_INVALID: - if (str < end) - *str = '%'; - ++str; - break; - - case FORMAT_TYPE_NRCHARS: - /* skip */ - break; - - default: - switch (spec.type) { - - case FORMAT_TYPE_LONG_LONG: - num = get_arg(long long); - break; - case FORMAT_TYPE_ULONG: - num = get_arg(unsigned long); - break; - case FORMAT_TYPE_LONG: - num = get_arg(unsigned long); - break; - case FORMAT_TYPE_SIZE_T: - num = get_arg(size_t); - break; - case FORMAT_TYPE_PTRDIFF: - num = get_arg(ptrdiff_t); - break; - case FORMAT_TYPE_UBYTE: - num = get_arg(unsigned char); - break; - case FORMAT_TYPE_BYTE: - num = get_arg(signed char); - break; - case FORMAT_TYPE_USHORT: - num = get_arg(unsigned short); - break; - case FORMAT_TYPE_SHORT: - num = get_arg(short); - break; - case FORMAT_TYPE_UINT: - num = get_arg(unsigned int); - break; - default: - num = get_arg(int); - } - - str = number(str, end, num, spec); - } - } - - if (size > 0) { - if (str < end) - *str = '\0'; - else - end[-1] = '\0'; - } - -#undef get_arg - - /* the trailing null byte doesn't count towards the total */ - return str - buf; -} -EXPORT_SYMBOL_GPL(bstr_printf); - -/** - * bprintf - Parse a format string and place args' binary value in a buffer - * @bin_buf: The buffer to place args' binary value - * @size: The size of the buffer(by words(32bits), not characters) - * @fmt: The format string to use - * @...: Arguments for the format string - * - * The function returns the number of words(u32) written - * into @bin_buf. - */ -int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) -{ - va_list args; - int ret; - - va_start(args, fmt); - ret = vbin_printf(bin_buf, size, fmt, args); - va_end(args); - return ret; -} -EXPORT_SYMBOL_GPL(bprintf); - -#endif /* CONFIG_BINARY_PRINTF */ - -/** - * vsscanf - Unformat a buffer into a list of arguments - * @buf: input buffer - * @fmt: format of buffer - * @args: arguments - */ -int vsscanf(const char * buf, const char * fmt, va_list args) -{ - const char *str = buf; - char *next; - char digit; - int num = 0; - int qualifier; - int base; - int field_width; - int is_sign = 0; - - while(*fmt && *str) { - /* skip any white space in format */ - /* white space in format matchs any amount of - * white space, including none, in the input. - */ - if (isspace(*fmt)) { - while (isspace(*fmt)) - ++fmt; - while (isspace(*str)) - ++str; - } - - /* anything that is not a conversion must match exactly */ - if (*fmt != '%' && *fmt) { - if (*fmt++ != *str++) - break; - continue; - } - - if (!*fmt) - break; - ++fmt; - - /* skip this conversion. - * advance both strings to next white space - */ - if (*fmt == '*') { - while (!isspace(*fmt) && *fmt) - fmt++; - while (!isspace(*str) && *str) - str++; - continue; - } - - /* get field width */ - field_width = -1; - if (isdigit(*fmt)) - field_width = skip_atoi(&fmt); - - /* get conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || - *fmt == 'Z' || *fmt == 'z') { - qualifier = *fmt++; - if (unlikely(qualifier == *fmt)) { - if (qualifier == 'h') { - qualifier = 'H'; - fmt++; - } else if (qualifier == 'l') { - qualifier = 'L'; - fmt++; - } - } - } - base = 10; - is_sign = 0; - - if (!*fmt || !*str) - break; - - switch(*fmt++) { - case 'c': - { - char *s = (char *) va_arg(args,char*); - if (field_width == -1) - field_width = 1; - do { - *s++ = *str++; - } while (--field_width > 0 && *str); - num++; - } - continue; - case 's': - { - char *s = (char *) va_arg(args, char *); - if(field_width == -1) - field_width = INT_MAX; - /* first, skip leading white space in buffer */ - while (isspace(*str)) - str++; - - /* now copy until next white space */ - while (*str && !isspace(*str) && field_width--) { - *s++ = *str++; - } - *s = '\0'; - num++; - } - continue; - case 'n': - /* return number of characters read so far */ - { - int *i = (int *)va_arg(args,int*); - *i = str - buf; - } - continue; - case 'o': - base = 8; - break; - case 'x': - case 'X': - base = 16; - break; - case 'i': - base = 0; - case 'd': - is_sign = 1; - case 'u': - break; - case '%': - /* looking for '%' in str */ - if (*str++ != '%') - return num; - continue; - default: - /* invalid format; stop here */ - return num; - } - - /* have some sort of integer conversion. - * first, skip white space in buffer. - */ - while (isspace(*str)) - str++; - - digit = *str; - if (is_sign && digit == '-') - digit = *(str + 1); - - if (!digit - || (base == 16 && !isxdigit(digit)) - || (base == 10 && !isdigit(digit)) - || (base == 8 && (!isdigit(digit) || digit > '7')) - || (base == 0 && !isdigit(digit))) - break; - - switch(qualifier) { - case 'H': /* that's 'hh' in format */ - if (is_sign) { - signed char *s = (signed char *) va_arg(args,signed char *); - *s = (signed char) simple_strtol(str,&next,base); - } else { - unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); - *s = (unsigned char) simple_strtoul(str, &next, base); - } - break; - case 'h': - if (is_sign) { - short *s = (short *) va_arg(args,short *); - *s = (short) simple_strtol(str,&next,base); - } else { - unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); - *s = (unsigned short) simple_strtoul(str, &next, base); - } - break; - case 'l': - if (is_sign) { - long *l = (long *) va_arg(args,long *); - *l = simple_strtol(str,&next,base); - } else { - unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); - *l = simple_strtoul(str,&next,base); - } - break; - case 'L': - if (is_sign) { - long long *l = (long long*) va_arg(args,long long *); - *l = simple_strtoll(str,&next,base); - } else { - unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); - *l = simple_strtoull(str,&next,base); - } - break; - case 'Z': - case 'z': - { - size_t *s = (size_t*) va_arg(args,size_t*); - *s = (size_t) simple_strtoul(str,&next,base); - } - break; - default: - if (is_sign) { - int *i = (int *) va_arg(args, int*); - *i = (int) simple_strtol(str,&next,base); - } else { - unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); - *i = (unsigned int) simple_strtoul(str,&next,base); - } - break; - } - num++; - - if (!next) - break; - str = next; - } - - /* - * Now we've come all the way through so either the input string or the - * format ended. In the former case, there can be a %n at the current - * position in the format that needs to be filled. - */ - if (*fmt == '%' && *(fmt + 1) == 'n') { - int *p = (int *)va_arg(args, int *); - *p = str - buf; - } - - return num; -} -EXPORT_SYMBOL(vsscanf); - -/** - * sscanf - Unformat a buffer into a list of arguments - * @buf: input buffer - * @fmt: formatting of buffer - * @...: resulting arguments - */ -int sscanf(const char * buf, const char * fmt, ...) -{ - va_list args; - int i; - - va_start(args,fmt); - i = vsscanf(buf,fmt,args); - va_end(args); - return i; -} -EXPORT_SYMBOL(sscanf); diff --git a/lib/am18x-lib/prj/am1808exp.c b/lib/am18x-lib/prj/am1808exp.c index 0f9b4856b..22357518c 100644 --- a/lib/am18x-lib/prj/am1808exp.c +++ b/lib/am18x-lib/prj/am1808exp.c @@ -5,11 +5,12 @@ #include "auxlib.h" #include "tps6507x.h" #include "am1808exp.h" +#include "am18x_type.h" #define SYSTICK_PERIOD 10/* milli seconds */ -static const ddr_conf_t mt46h64m16_6 = { +const ddr_conf_t mt46h64m16_6 = { .ddr2_not_mddr = AM18X_FALSE, .page_size = 10, .row_size = 9, @@ -71,7 +72,7 @@ int low_level_init(void) { // ddr_initialize(DDR0, &mt46h64m16_6); if (AM18X_OK != (r = systick_init(SYSTICK_PERIOD))) { - printk("systick_init() error\n"); + // printk("systick_init() error\n"); return r; } @@ -89,7 +90,7 @@ int low_level_init(void) { // tps6507x_conf(); - printk("ARM CLK: %9d Hz\n", dev_get_freq(DCLK_ID_ARM)); + // printk("ARM CLK: %9d Hz\n", dev_get_freq(DCLK_ID_ARM)); return AM18X_OK; } diff --git a/lib/am18x-lib/prj/am18x_conf.c b/lib/am18x-lib/prj/am18x_conf.c index 954891810..b860c6210 100644 --- a/lib/am18x-lib/prj/am18x_conf.c +++ b/lib/am18x-lib/prj/am18x_conf.c @@ -130,7 +130,7 @@ static none_arg_handler_t isr_vector[] = { }; int isr_set_handler(int intr_nr, none_arg_handler_t handle) { - if (intr_nr >= countof(isr_vector)) { + if (intr_nr >= (int) countof(isr_vector)) { return -1; } isr_vector[intr_nr] = handle; diff --git a/lib/am18x-lib/src/am18x_dclk.c b/lib/am18x-lib/src/am18x_dclk.c index ce820cfc8..f0e0c940c 100644 --- a/lib/am18x-lib/src/am18x_dclk.c +++ b/lib/am18x-lib/src/am18x_dclk.c @@ -25,6 +25,7 @@ static uint32_t do_change_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ uint32_t reg, divider; \ \ divider = clk_nodes[id].divider; \ + (void)divider; \ reg = PLL##pll_nr->PLLDIVxA[PLLDIVxA_IDX_##s_nr]; \ if (clk_nodes[id].parent == CLK_NODE_PLL##pll_nr##_PLLEN) { \ reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); \ @@ -56,6 +57,7 @@ static uint32_t do_change_PLL##pll_nr##_SYSCLK##s_nr (uint32_t parent) { \ uint32_t reg, divider; \ \ divider = clk_nodes[id].divider; \ + (void)divider; \ reg = PLL##pll_nr->PLLDIVxB[PLLDIVxB_IDX_##s_nr]; \ if (clk_nodes[id].parent == CLK_NODE_PLL##pll_nr##_PLLEN) { \ reg = FIELD_SET(reg, msk, XXXDIVx_DxEN_enable); \ @@ -312,43 +314,43 @@ static uint32_t do_change_OCSEL1_OCSRC (uint32_t parent) { #define RECALC CN_FLAG_RECALC static clk_node_t clk_nodes[] = { - // ID PARENT, FLAG, MULT, DIV, CALC_FREQ, DO_CHANGE, PARENT_LIST - { cnm(INVALID), cm(INVALID), 0, 0, 0, }, - { cnm(PLL0_SYSCLK1), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK1), }, - { cnm(PLL0_SYSCLK2), cm(PLL0_PLLEN), REREAD, 0, 2, cfdc(PLL0_SYSCLK2), }, - { cnm(PLL0_SYSCLK3), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK3), }, - { cnm(PLL0_SYSCLK4), cm(PLL0_PLLEN), REREAD, 0, 4, cfdc(PLL0_SYSCLK4), }, - { cnm(PLL0_SYSCLK5), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK5), }, - { cnm(PLL0_SYSCLK6), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK6), }, - { cnm(PLL0_SYSCLK7), cm(PLL0_PLLEN), REREAD, 0, 6, cfdc(PLL0_SYSCLK7), }, - { cnm(EMA_CLKSRC), cm(PLL0_SYSCLK3), CFMUX, 0, 0, cfdc(EMA_CLKSRC), }, - { cnm(PLL0_AUXCLK), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL0_AUXCLK), }, - { cnm(PLL0_OBSCLK), cm(OSCDIV0), CFMUX, 0, 0, cfdc(PLL0_OBSCLK), }, - { cnm(PLL1_SYSCLK1), cm(PLL1_PLLEN), REREAD, 0, 1, cfdc(PLL1_SYSCLK1), }, - { cnm(PLL1_SYSCLK2), cm(PLL1_PLLEN), REREAD, 0, 2, cfdc(PLL1_SYSCLK2), }, - { cnm(PLL1_SYSCLK3), cm(PLL1_PLLEN), REREAD, 0, 3, cfdc(PLL1_SYSCLK3), }, - { cnm(PLL1_OBSCLK), cm(OSCDIV1), CFMUX, 0, 0, cfdc(PLL1_OBSCLK), }, - { cnm(ASYNC3), cm(PLL0_SYSCLK2), CFMUX, 0, 0, cfdc(ASYNC3), }, - { cnm(PLL0_PLLEN), cm(PLL_EXTSRC), CFMUX, 0, 0, cfdc(PLL0_PLLEN), }, - { cnm(PLL_EXTSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL_EXTSRC), }, - { cnm(POSTDIV0), cm(PLLM0), REREAD, 0, 0, cfdc(POSTDIV0), }, - { cnm(PLLM0), cm(PREDIV0), REREAD, 0, 0, cfdc(PLLM0), }, - { cnm(PREDIV0), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PREDIV0), }, - { cnm(PLL_CLKMODE), cm(OSCIN), 0, 1, 0, }, - { cnm(DIV4_5X), cm(DIV4_5), CFMUX, 0, 0, cfdc(DIV4_5X), }, - { cnm(DIV4_5), cm(PLLM0), 0, 2, 9, }, - { cnm(OSCDIV0), cm(OCSEL0_OCSRC),REREAD, 0, 0, cfdc(OSCDIV0), }, - { cnm(OCSEL0_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL0_OCSRC), }, - { cnm(PLL1_PLLEN), cm(POSTDIV1), CFMUX, 0, 0, cfdc(PLL1_PLLEN), }, - { cnm(POSTDIV1), cm(PLLM1), REREAD, 0, 0, cfdc(POSTDIV1), }, - { cnm(PLLM1), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PLLM1), }, - { cnm(OSCDIV1), cm(OCSEL1_OCSRC),REREAD, 0, 0, cfdc(OSCDIV1), }, - { cnm(OCSEL1_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL1_OCSRC), }, - { cnm(OSCIN), cm(INVALID), 0, 0, 0, }, + // ID PARENT, FLAG, MULT,DIV, CALC_FREQ, DO_CHANGE, PARENT_LIST + { cnm(INVALID), cm(INVALID), 0, 0, 0, NULL, NULL , NULL, 0}, + { cnm(PLL0_SYSCLK1), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK1), NULL, 0}, + { cnm(PLL0_SYSCLK2), cm(PLL0_PLLEN), REREAD, 0, 2, cfdc(PLL0_SYSCLK2), NULL, 0}, + { cnm(PLL0_SYSCLK3), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK3), NULL, 0}, + { cnm(PLL0_SYSCLK4), cm(PLL0_PLLEN), REREAD, 0, 4, cfdc(PLL0_SYSCLK4), NULL, 0}, + { cnm(PLL0_SYSCLK5), cm(PLL0_PLLEN), REREAD, 0, 3, cfdc(PLL0_SYSCLK5), NULL, 0}, + { cnm(PLL0_SYSCLK6), cm(PLL0_PLLEN), REREAD, 0, 1, cfdc(PLL0_SYSCLK6), NULL, 0}, + { cnm(PLL0_SYSCLK7), cm(PLL0_PLLEN), REREAD, 0, 6, cfdc(PLL0_SYSCLK7), NULL, 0}, + { cnm(EMA_CLKSRC), cm(PLL0_SYSCLK3), CFMUX, 0, 0, cfdc(EMA_CLKSRC), NULL, 0}, + { cnm(PLL0_AUXCLK), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL0_AUXCLK), NULL, 0}, + { cnm(PLL0_OBSCLK), cm(OSCDIV0), CFMUX, 0, 0, cfdc(PLL0_OBSCLK), NULL, 0}, + { cnm(PLL1_SYSCLK1), cm(PLL1_PLLEN), REREAD, 0, 1, cfdc(PLL1_SYSCLK1), NULL, 0}, + { cnm(PLL1_SYSCLK2), cm(PLL1_PLLEN), REREAD, 0, 2, cfdc(PLL1_SYSCLK2), NULL, 0}, + { cnm(PLL1_SYSCLK3), cm(PLL1_PLLEN), REREAD, 0, 3, cfdc(PLL1_SYSCLK3), NULL, 0}, + { cnm(PLL1_OBSCLK), cm(OSCDIV1), CFMUX, 0, 0, cfdc(PLL1_OBSCLK), NULL, 0}, + { cnm(ASYNC3), cm(PLL0_SYSCLK2), CFMUX, 0, 0, cfdc(ASYNC3), NULL, 0}, + { cnm(PLL0_PLLEN), cm(PLL_EXTSRC), CFMUX, 0, 0, cfdc(PLL0_PLLEN), NULL, 0}, + { cnm(PLL_EXTSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(PLL_EXTSRC), NULL, 0}, + { cnm(POSTDIV0), cm(PLLM0), REREAD, 0, 0, cfdc(POSTDIV0), NULL, 0}, + { cnm(PLLM0), cm(PREDIV0), REREAD, 0, 0, cfdc(PLLM0), NULL, 0}, + { cnm(PREDIV0), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PREDIV0), NULL, 0}, + { cnm(PLL_CLKMODE), cm(OSCIN), 0, 1, 0, NULL, NULL , NULL, 0}, + { cnm(DIV4_5X), cm(DIV4_5), CFMUX, 0, 0, cfdc(DIV4_5X), NULL, 0}, + { cnm(DIV4_5), cm(PLLM0), 0, 2, 9, NULL, NULL , NULL, 0}, + { cnm(OSCDIV0), cm(OCSEL0_OCSRC),REREAD, 0, 0, cfdc(OSCDIV0), NULL, 0}, + { cnm(OCSEL0_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL0_OCSRC), NULL, 0}, + { cnm(PLL1_PLLEN), cm(POSTDIV1), CFMUX, 0, 0, cfdc(PLL1_PLLEN), NULL, 0}, + { cnm(POSTDIV1), cm(PLLM1), REREAD, 0, 0, cfdc(POSTDIV1), NULL, 0}, + { cnm(PLLM1), cm(PLL_CLKMODE), REREAD, 0, 0, cfdc(PLLM1), NULL, 0}, + { cnm(OSCDIV1), cm(OCSEL1_OCSRC),REREAD, 0, 0, cfdc(OSCDIV1), NULL, 0}, + { cnm(OCSEL1_OCSRC), cm(PLL_CLKMODE), CFMUX, 0, 0, cfdc(OCSEL1_OCSRC), NULL, 0}, + { cnm(OSCIN), cm(INVALID), 0, 0, 0, NULL, NULL , NULL, 0}, }; am18x_rt clk_node_init(void) { - int i; + uint32_t i; for (i = 0; i < countof(clk_nodes); i++) { clk_node_t* cni = clk_nodes + i; @@ -451,7 +453,7 @@ static uint32_t clk_node_tree_innner(uint32_t id, int level) { freq = clk_node_get_freq(id); sprintf(line0 + LINE_UNIT * level, "[%12s]", clk_nodes[id].name); - sprintf(line1 + LINE_UNIT * level, " %4dMhz ", freq / ONE_MEGA); + sprintf(line1 + LINE_UNIT * level, " %4dMhz ", (int)(freq / ONE_MEGA)); for (i = CLK_NODE_INVALID + 1; i < CLK_NODE_CNT; i++) { if (clk_nodes[i].parent == id) { diff --git a/lib/am18x-lib/src/am18x_ddr.c b/lib/am18x-lib/src/am18x_ddr.c index 8e57cbf00..97b53751e 100644 --- a/lib/am18x-lib/src/am18x_ddr.c +++ b/lib/am18x-lib/src/am18x_ddr.c @@ -214,7 +214,7 @@ am18x_rt ddr_clock_off(DDR_con_t* dcon) { dcon->SDRCR = reg; // 4. Wait 150 CPU clock cycles to allow MCLK to stop - for (v = 0; v < 150; v++) asm volatile("nop"); + for (v = 0; v < 150; v++) __asm volatile("nop"); // 5. Program the PSC to disable the DDR2/mDDR memory controller VCLK psc_state_transition(PSC_DDR2, PSC_STATE_DISABLE); @@ -244,7 +244,7 @@ am18x_rt ddr_clock_on(DDR_con_t* dcon) { clk_node_recalc(); // 2. Once 2X_CLK is stable, program the PSC to enable VCLK - for (v = 0; v < 150; v++) asm volatile("nop"); + for (v = 0; v < 150; v++) __asm volatile("nop"); psc_state_transition(PSC_DDR2, PSC_STATE_ENABLE); // 3. Set the RESET_PHY bit in the DRPYRCR to 1 diff --git a/lib/am18x-lib/src/am18x_edma.c b/lib/am18x-lib/src/am18x_edma.c index b3ca42abb..cafc7042a 100644 --- a/lib/am18x-lib/src/am18x_edma.c +++ b/lib/am18x-lib/src/am18x_edma.c @@ -34,14 +34,14 @@ static am18x_bool is_qchannel(const edma_conf_t* conf) { return AM18X_TRUE; } -static am18x_bool is_null_pa_entry(const pa_conf_t* pa) { +am18x_bool is_null_pa_entry(const pa_conf_t* pa) { if (pa->a_cnt == 0 && pa->b_cnt == 0 && pa->c_cnt == 0) { return AM18X_TRUE; } return AM18X_FALSE; } -static am18x_bool is_dummy_pa_entry(const pa_conf_t* pa) { +am18x_bool is_dummy_pa_entry(const pa_conf_t* pa) { if ((pa->a_cnt == 0 || pa->b_cnt == 0 || pa->c_cnt == 0) && (pa->a_cnt != 0 || pa->b_cnt != 0 || pa->c_cnt != 0) ) { diff --git a/lib/am18x-lib/src/am18x_gpio.c b/lib/am18x-lib/src/am18x_gpio.c index f56448d1d..ad42f589f 100644 --- a/lib/am18x-lib/src/am18x_gpio.c +++ b/lib/am18x-lib/src/am18x_gpio.c @@ -56,7 +56,7 @@ am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir) { val = 4; } else // PINMUX04[7..0] = (GP1[0..7], value = 4) - if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_7) { + if (pin <= GPIO_PIN_7) { mux = 4; pos = GPIO_PIN_7 - pin; val = 4; @@ -123,7 +123,7 @@ am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir) { pos = GPIO_PIN_6 - pin; } else // PINMUX19[6..2] = (GP6[0..4], value = 8) - if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_4) { + if (pin <= GPIO_PIN_4) { mux = 19; pos = GPIO_PIN_6 - pin; } @@ -140,7 +140,7 @@ am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir) { pos = GPIO_PIN_9 - pin; } else // PINMUX18[1..0] = (GP7[0..1], value = 8) - if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_1) { + if (pin <= GPIO_PIN_1) { mux = 18; pos = GPIO_PIN_1 - pin; } @@ -169,7 +169,7 @@ am18x_rt gpio_set_mux(gpio_bank_t bank, gpio_pin_t pin, gpio_dir_t dir) { val = 4; } else // PINMUX19[7..7] = (GP8[0], value = 8) - if (GPIO_PIN_0 <= pin && pin <= GPIO_PIN_0) { + if (pin <= GPIO_PIN_0) { mux = 19; pos = GPIO_PIN_7 - pin; } diff --git a/lib/am18x-lib/src/am18x_pll.c b/lib/am18x-lib/src/am18x_pll.c index 878ae04b5..fd03043ad 100644 --- a/lib/am18x-lib/src/am18x_pll.c +++ b/lib/am18x-lib/src/am18x_pll.c @@ -118,7 +118,7 @@ am18x_rt pll_set_conf(PLL_con_t* pcon, const pll_conf_t* conf) { // d) Wait for 4 OSCIN cycles to ensure that // the PLLC has switch to bypass mode for (v = 0; v < 456 * 4 / 12; v++) { - asm volatile ("nop"); + __asm volatile ("nop"); } // 3. Clear PLLRST in PLLCTL to 0 @@ -159,7 +159,7 @@ am18x_rt pll_set_conf(PLL_con_t* pcon, const pll_conf_t* conf) { // N = Pre-Divider Ratio // M = PLL Multiplier for (v = 0; v < 456 * ( 2000 * conf->prediv / 2) / 12; v++) { - asm volatile ("nop"); + __asm volatile ("nop"); } // 9. Set the PLLEN bit in PLLCTL to 1 (removes PLL from bypass mode) @@ -171,7 +171,7 @@ am18x_rt pll_set_conf(PLL_con_t* pcon, const pll_conf_t* conf) { am18x_rt pll_cmd(PLL_con_t* pcon, uint32_t cmd, uint32_t arg) { uint32_t reg, msk; - int i; + uint32_t i; switch (cmd) { case PLL_CMD_SOFT_RESET: @@ -204,14 +204,14 @@ am18x_rt pll_cmd(PLL_con_t* pcon, uint32_t cmd, uint32_t arg) { msk = PLLCTL_PLLEN_MASK; pcon->PLLCTL = FIELD_SET(pcon->PLLCTL, msk, PLLCTL_PLLEN_no); for (i = 0; i < 456 * 4 / 12; i++) { - asm volatile ("nop"); + __asm volatile ("nop"); } break; case PLL_CMD_CHG_MULT: pcon->PLLM = FIELD_SET(0, PLLM_MASK, PLLM_WR(arg)); for (i = 0; i < 456 * ( 2000 * (pcon->PREDIV + 1) / 2) / 12; i++) { - asm volatile ("nop"); + __asm volatile ("nop"); } break; diff --git a/lib/am18x-lib/src/am18x_pru.c b/lib/am18x-lib/src/am18x_pru.c index 99a434ac6..d87c4f0cf 100644 --- a/lib/am18x-lib/src/am18x_pru.c +++ b/lib/am18x-lib/src/am18x_pru.c @@ -4,7 +4,7 @@ am18x_rt pru_load(PRU_con_t* pcon, const uint32_t* inst, uint32_t count) { uint32_t* pram; - int i; + uint32_t i; pram = (uint32_t*)PRU_InstRAM0_BASE; if (pcon == PRU1) { @@ -79,7 +79,7 @@ static kv_t of_regs[] = { am18x_rt pru_dump_regs(PRU_con_t* pcon) { uint32_t* ptr; - int i; + uint32_t i; for (i = 0; i < countof(of_regs); i++) { int of; diff --git a/lib/am18x-lib/src/am18x_psc.c b/lib/am18x-lib/src/am18x_psc.c index c6258d7ff..ee886a77c 100644 --- a/lib/am18x-lib/src/am18x_psc.c +++ b/lib/am18x-lib/src/am18x_psc.c @@ -127,7 +127,7 @@ static kv_t of_regs[] = { am18x_rt psc_dump_regs(PSC_con_t* pcon) { uint32_t* ptr; - int i, s; + uint32_t i, s; for (i = 0; i < countof(of_regs) - 2; i++) { int of; @@ -139,11 +139,11 @@ am18x_rt psc_dump_regs(PSC_con_t* pcon) { s = MODULE_NR_PER_PSC; if (pcon == PSC0) s = s / 2; - ptr = &pcon->MDSTATx; + ptr = (uint32_t*) &pcon->MDSTATx; for (i = 0; i < s; i++) { printk("MDSTAT%-2d[0x%.8X] = 0x%.8X\n", i, ptr + i, ptr[i]); } - ptr = &pcon->MDCTLx; + ptr = (uint32_t*) &pcon->MDCTLx; for (i = 0; i < s; i++) { printk("MDCTL%-3d[0x%.8X] = 0x%.8X\n", i, ptr + i, ptr[i]); } diff --git a/lib/am18x-lib/src/am18x_syscfg.c b/lib/am18x-lib/src/am18x_syscfg.c index 9fce62490..53cc2c51b 100644 --- a/lib/am18x-lib/src/am18x_syscfg.c +++ b/lib/am18x-lib/src/am18x_syscfg.c @@ -136,7 +136,7 @@ static uint32_t freq_table[][2] = { // USB#0 (USB2.0 subsystem) am18x_rt syscfg_set_usb0phy(am18x_bool y_on_n_off, uint32_t freq) { uint32_t reg, msk, v; - int i; + uint32_t i; reg = SYSCFG0->CFGCHIP2; @@ -151,7 +151,7 @@ am18x_rt syscfg_set_usb0phy(am18x_bool y_on_n_off, uint32_t freq) { SYSCFG0->CFGCHIP2 = reg; // Drive Reset for few clock cycles for (v = 0; v < 50; v++) { - asm volatile ("nop"); + __asm volatile ("nop"); } if (!y_on_n_off) { From 6c71d4cef55fec34467018d13ef158fc3704f902 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 10 Jun 2024 19:51:19 +0200 Subject: [PATCH 3/6] pbio/platform/ev3: Use am18x-lib for startup and linker script. --- bricks/_common/arm_none_eabi.mk | 3 +- lib/am18x-lib/prj/am18x.ld | 78 ---------------------- lib/am18x-lib/prj/am18x_conf.c | 4 ++ lib/am18x-lib/prj/start.S | 4 ++ lib/pbio/platform/ev3/platform.ld | 107 +++++++++++++++++++----------- lib/pbio/platform/ev3/startup.s | 40 +---------- 6 files changed, 80 insertions(+), 156 deletions(-) delete mode 100644 lib/am18x-lib/prj/am18x.ld diff --git a/bricks/_common/arm_none_eabi.mk b/bricks/_common/arm_none_eabi.mk index 8e38e37a6..36c7d93c2 100644 --- a/bricks/_common/arm_none_eabi.mk +++ b/bricks/_common/arm_none_eabi.mk @@ -305,9 +305,10 @@ AM18X_LIB_LIB_SRC_C = $(addprefix lib/am18x-lib/lib/,\ AM18X_LIB_PRJ_SRC_S = $(addprefix lib/am18x-lib/prj/,\ abt_handler.S \ + start.S \ uart_dbg.S \ undef_handler.S \ - ) # excluding start.S for now since it conflics with start.s in platform/startup.s + ) AM18X_LIB_LIB_SRC_S = $(addprefix lib/am18x-lib/lib/,\ arm920t_s.S \ diff --git a/lib/am18x-lib/prj/am18x.ld b/lib/am18x-lib/prj/am18x.ld deleted file mode 100644 index 73e6fb943..000000000 --- a/lib/am18x-lib/prj/am18x.ld +++ /dev/null @@ -1,78 +0,0 @@ -/* tary, 1:09 2012/12/23 */ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SEARCH_DIR("=/usr/local/lib"); -SEARCH_DIR("=/lib"); -SEARCH_DIR("=/usr/lib"); -SECTIONS { - . = 0xc0008000; - . = ALIGN(0x4); - PROVIDE (__text_start = .); - .text : { - *(.init); - *(.text); - . = ALIGN(0x10); - - *(.rodata .rodata.*); - . = ALIGN(0x10); - - PROVIDE (__lds_got_start = .); - *(.got.plt); - *(.got); - . = ALIGN(0x10); - PROVIDE (__lds_got_end = .); - PROVIDE (__lds_got_size = __lds_got_end - __lds_got_start); - . = ALIGN(0x10); - } = 0 - PROVIDE (__text_end = .); - - PROVIDE (__data_start = .); - .data : { - *(.data); - . = ALIGN(0x10); - - *(.data.rel .data.rel.*); - . = ALIGN(0x10); - - PROVIDE (__lds_rel_start = .); - *(.rel.*); - . = ALIGN(0x10); - PROVIDE (__lds_rel_end = .); - PROVIDE (__lds_rel_size = __lds_rel_end - __lds_rel_start); - } = 0 - . = ALIGN(0x10); - PROVIDE (__data_end = .); - - /* - .rel __data_end : { - } = 0 - */ - - .bss __lds_rel_start (NOLOAD): { - PROVIDE (__lds_bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(0x10); - PROVIDE (__lds_bss_end = .); - } = 0 - - . = ALIGN(0x10); - .stack : { - *(.stack) - . = ALIGN(0x10); - } - PROVIDE (end = .); - - /DISCARD/ : { - *(.note.GNU-stack) - *(.gnu_debuglink) - *(.gnu.lto_*) - /*(.debug*)*/ - *(.ARM.attributes) - *(.comment) - *(.interp) - *(.dyn*) - *(.hash) - } -} diff --git a/lib/am18x-lib/prj/am18x_conf.c b/lib/am18x-lib/prj/am18x_conf.c index b860c6210..ebd604b73 100644 --- a/lib/am18x-lib/prj/am18x_conf.c +++ b/lib/am18x-lib/prj/am18x_conf.c @@ -2,6 +2,10 @@ #include "am18x_lib.h" #include "auxlib.h" +int printk(const char* s, ...) { + return 0; +} + extern int output_a_char(int); static none_arg_handler_t isr_vector[] = { diff --git a/lib/am18x-lib/prj/start.S b/lib/am18x-lib/prj/start.S index 5cc1db3ac..ff853822d 100644 --- a/lib/am18x-lib/prj/start.S +++ b/lib/am18x-lib/prj/start.S @@ -143,6 +143,10 @@ HandleReset: .extern low_level_init BL low_level_init + @ call to SystemInit + .extern SystemInit + bl SystemInit + @ call to main entry point .extern main bl main diff --git a/lib/pbio/platform/ev3/platform.ld b/lib/pbio/platform/ev3/platform.ld index a3baf186f..73e6fb943 100644 --- a/lib/pbio/platform/ev3/platform.ld +++ b/lib/pbio/platform/ev3/platform.ld @@ -1,47 +1,78 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ +/* tary, 1:09 2012/12/23 */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) ENTRY(_start) +SEARCH_DIR("=/usr/local/lib"); +SEARCH_DIR("=/lib"); +SEARCH_DIR("=/usr/lib"); +SECTIONS { + . = 0xc0008000; + . = ALIGN(0x4); + PROVIDE (__text_start = .); + .text : { + *(.init); + *(.text); + . = ALIGN(0x10); -/* Tell where the various sections of the object files will be put in the final - kernel image. */ -SECTIONS -{ - /* Begin putting sections at this number, taken from U-boot env */ - . = 0xC0008000; - /* Begin putting sections at this number, for use with qemu */ - /*. = 0x00010000;*/ - - /* First put the multiboot header, as it is required to be put very early - early in the image or the bootloader won't recognize the file format. - Next we'll put the .text section. */ - .text BLOCK(4K) : ALIGN(4K) - { - KEEP(*(.text.boot)) - *(.text) - } + *(.rodata .rodata.*); + . = ALIGN(0x10); - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } + PROVIDE (__lds_got_start = .); + *(.got.plt); + *(.got); + . = ALIGN(0x10); + PROVIDE (__lds_got_end = .); + PROVIDE (__lds_got_size = __lds_got_end - __lds_got_start); + . = ALIGN(0x10); + } = 0 + PROVIDE (__text_end = .); - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } + PROVIDE (__data_start = .); + .data : { + *(.data); + . = ALIGN(0x10); - /* Read-write data (uninitialized) and stack */ - __bss_start = .; - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) + *(.data.rel .data.rel.*); + . = ALIGN(0x10); + + PROVIDE (__lds_rel_start = .); + *(.rel.*); + . = ALIGN(0x10); + PROVIDE (__lds_rel_end = .); + PROVIDE (__lds_rel_size = __lds_rel_end - __lds_rel_start); + } = 0 + . = ALIGN(0x10); + PROVIDE (__data_end = .); + + /* + .rel __data_end : { + } = 0 + */ + + .bss __lds_rel_start (NOLOAD): { + PROVIDE (__lds_bss_start = .); *(.bss) - . += 8K; + *(COMMON) + . = ALIGN(0x10); + PROVIDE (__lds_bss_end = .); + } = 0 + + . = ALIGN(0x10); + .stack : { + *(.stack) + . = ALIGN(0x10); } - __bss_end = .; + PROVIDE (end = .); - /* The compiler may produce other sections, by default it will put them in - a segment with the same name. Simply add stuff here as needed. */ + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.gnu.lto_*) + /*(.debug*)*/ + *(.ARM.attributes) + *(.comment) + *(.interp) + *(.dyn*) + *(.hash) + } } diff --git a/lib/pbio/platform/ev3/startup.s b/lib/pbio/platform/ev3/startup.s index 502f58359..796d9a745 100644 --- a/lib/pbio/platform/ev3/startup.s +++ b/lib/pbio/platform/ev3/startup.s @@ -1,39 +1 @@ -// To keep this in the first portion of the binary. -.section .text.boot - -// Make _start global. -.globl _start - -_start: - // Setup the stack. - ldr sp, =__bss_end - - // Clear out bss. - ldr r4, =__bss_start - ldr r9, =__bss_end - mov r5, #0 - mov r6, #0 - mov r7, #0 - mov r8, #0 - b 2f - -1: - // store multiple at r4. - stmia r4!, {r5-r8} - - // If we are still below bss_end, loop. -2: - cmp r4, r9 - blo 1b - - // Call SystemInit - ldr r3, =SystemInit - blx r3 - - // Call main - ldr r3, =main - blx r3 - -halt: - wfe - b halt +@* Using startup from am18x-lib From 9bc9f1ba1fdfcc65853602adb81c34687608e0f2 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 10 Jun 2024 20:07:40 +0200 Subject: [PATCH 4/6] lib/am18x-lib: Use printf. --- bricks/_common/arm_none_eabi.mk | 3 +++ lib/am18x-lib/lib/auxlib.h | 6 +++++- lib/am18x-lib/prj/abt_handler.S | 4 ++-- lib/am18x-lib/prj/am18x_conf.c | 4 ---- lib/am18x-lib/prj/undef_handler.S | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/bricks/_common/arm_none_eabi.mk b/bricks/_common/arm_none_eabi.mk index 36c7d93c2..96c494e83 100644 --- a/bricks/_common/arm_none_eabi.mk +++ b/bricks/_common/arm_none_eabi.mk @@ -535,6 +535,9 @@ ifeq ($(PB_MCU_FAMILY),TIAM1808) OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_SRC_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_C:.c=.o)) +$(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_C:.c=.o)): CFLAGS += -Wno-error=format= -Wno-format +$(addprefix $(BUILD)/, $(AM18X_LIB_SRC_SRC_C:.c=.o)): CFLAGS += -Wno-error=format= -Wno-format +$(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_C:.c=.o)): CFLAGS += -Wno-error=format= -Wno-format OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_PRJ_SRC_S:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(AM18X_LIB_LIB_SRC_S:.S=.o)) diff --git a/lib/am18x-lib/lib/auxlib.h b/lib/am18x-lib/lib/auxlib.h index 31571d15c..8e513c161 100644 --- a/lib/am18x-lib/lib/auxlib.h +++ b/lib/am18x-lib/lib/auxlib.h @@ -32,11 +32,15 @@ typedef struct { #define __HAS_STRING_H__ +#include + int delay(int d); #ifndef __HAS_STRING_H__ int puts(const char* s); #endif -int printk(const char* s, ...); + +#define printk printf + int sscanf(const char* buf, const char* fmt, ...); int sprintf(char * buf, const char *fmt, ...); size_t strlen(const char* s); diff --git a/lib/am18x-lib/prj/abt_handler.S b/lib/am18x-lib/prj/abt_handler.S index 97bbc24bb..259547ada 100644 --- a/lib/am18x-lib/prj/abt_handler.S +++ b/lib/am18x-lib/prj/abt_handler.S @@ -25,7 +25,7 @@ HandlePrefetchAbort: LDRNE R1, =__thumb_mode_fmt SUBNE V2, LR, #4 - LDR V1, =printk + LDR V1, =printf LDR R0, =__pabt_fmt MOV LR, PC @@ -68,7 +68,7 @@ HandleDataAbort: LDRNE R1, =__thumb_mode_fmt SUBNE V2, LR, #8 - LDR V1, =printk + LDR V1, =printf ADR R0, __dabt_fmt MOV LR, PC diff --git a/lib/am18x-lib/prj/am18x_conf.c b/lib/am18x-lib/prj/am18x_conf.c index ebd604b73..b860c6210 100644 --- a/lib/am18x-lib/prj/am18x_conf.c +++ b/lib/am18x-lib/prj/am18x_conf.c @@ -2,10 +2,6 @@ #include "am18x_lib.h" #include "auxlib.h" -int printk(const char* s, ...) { - return 0; -} - extern int output_a_char(int); static none_arg_handler_t isr_vector[] = { diff --git a/lib/am18x-lib/prj/undef_handler.S b/lib/am18x-lib/prj/undef_handler.S index f1bd7a9b1..69636df19 100644 --- a/lib/am18x-lib/prj/undef_handler.S +++ b/lib/am18x-lib/prj/undef_handler.S @@ -25,7 +25,7 @@ HandleUndef: LDRNE R1, =__thumb_mode_fmt SUBNE V2, LR, #2 ADR R0, __undef_fmt - LDR V1, =printk + LDR V1, =printf MOV LR, PC BX V1 From 9ebae24006a43a3ba44b5e5be2daccd2d44b5666 Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Mon, 10 Jun 2024 20:30:04 +0200 Subject: [PATCH 5/6] .vscode: Add am18x-lib c_cpp_properties. --- .vscode/c_cpp_properties.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 52cc6551a..ffdd6e0cf 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -67,6 +67,9 @@ "${workspaceFolder}/bricks/ev3", "${workspaceFolder}/bricks/ev3/build", "${workspaceFolder}/micropython", + "${workspaceFolder}/lib/am18x-lib/inc", + "${workspaceFolder}/lib/am18x-lib/lib", + "${workspaceFolder}/lib/am18x-lib/prj", ], "defines": [ "MICROPY_MODULE_FROZEN_MPY", From a5b91ee2d96e6b788d53258be3ba9376d3237b4f Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 11 Jun 2024 10:26:21 +0200 Subject: [PATCH 6/6] bricks/ev3: Implement clock, systick, and wait for interrupt sleep. --- bricks/ev3/mpconfigport.h | 8 ++++---- bricks/ev3/mphalport.c | 25 +++++++++++-------------- lib/am18x-lib/prj/am1808exp.c | 11 +++++------ lib/am18x-lib/prj/am18x_conf.h | 2 ++ lib/pbio/drv/clock/clock_tiam1808.c | 16 ++++++++++++++-- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/bricks/ev3/mpconfigport.h b/bricks/ev3/mpconfigport.h index db2068c33..63fdbbb0c 100644 --- a/bricks/ev3/mpconfigport.h +++ b/bricks/ev3/mpconfigport.h @@ -78,14 +78,14 @@ typedef long mp_off_t; // value from disable_irq back to enable_irq. If you really need // to know the machine-specific values, see irq.h. +#include + static inline void enable_irq(mp_uint_t state) { - // __set_PRIMASK(state); + arm_intr_enable(); } static inline mp_uint_t disable_irq(void) { - // mp_uint_t state = __get_PRIMASK(); - // __disable_irq(); - // return state; + arm_intr_disable(); return 0; } diff --git a/bricks/ev3/mphalport.c b/bricks/ev3/mphalport.c index c9aa373b5..842eeed3b 100644 --- a/bricks/ev3/mphalport.c +++ b/bricks/ev3/mphalport.c @@ -16,6 +16,10 @@ #include "py/mpconfig.h" #include "py/stream.h" +#include +#include +#include + void pb_stack_get_info(char **sstack, char **estack) { volatile int stack_dummy; @@ -31,24 +35,17 @@ void pb_event_poll_hook_leave(void) { // have a critical section where we disable interrupts and check see if there // are any last second events. If not, we can call __WFI(), which still wakes // up the CPU on interrupt even though interrupts are otherwise disabled. - - - // TODO: TIAM1808 Implement commented out parts - - // mp_uint_t state = disable_irq(); + arm_intr_disable(); if (!process_nevents()) { - // __WFI(); + arm_wfi(); } - // enable_irq(state); + arm_intr_enable(); } // Core delay function that does an efficient sleep and may switch thread context. // If IRQs are enabled then we must have the GIL. void mp_hal_delay_ms(mp_uint_t Delay) { - - // TODO: TIAM1808 implement IRQ enabled check - - if (/*__get_PRIMASK() == 0*/ 0) { + if (aintc_get_active() != AINTC_INVALID_ACTIVE) { // IRQs enabled, so can use systick counter to do the delay uint32_t start = pbdrv_clock_get_ms(); // Wraparound of tick is taken care of by 2's complement arithmetic. @@ -60,7 +57,7 @@ void mp_hal_delay_ms(mp_uint_t Delay) { } while (pbdrv_clock_get_ms() - start < Delay); } else { // IRQs disabled, so need to use a busy loop for the delay. - // TODO: TIAM1808 + systick_sleep(Delay); } } @@ -80,7 +77,7 @@ typedef struct { } pb_hal_uart_t; // Sensor port 1 -static pb_hal_uart_t UART0 = { .thr = (volatile uint8_t *)0x01D0C000, .lsr = (volatile uint8_t *)0x01D0C014 }; +static pb_hal_uart_t DBG_UART = { .thr = (volatile uint8_t *)0x01D0C000, .lsr = (volatile uint8_t *)0x01D0C014 }; static void debug(pb_hal_uart_t *uart, const char *s) { while (*s) { @@ -91,7 +88,7 @@ static void debug(pb_hal_uart_t *uart, const char *s) { } void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { - debug(&UART0, str); + debug(&DBG_UART, str); // MICROPY_EVENT_POLL_HOOK } diff --git a/lib/am18x-lib/prj/am1808exp.c b/lib/am18x-lib/prj/am1808exp.c index 22357518c..69beab442 100644 --- a/lib/am18x-lib/prj/am1808exp.c +++ b/lib/am18x-lib/prj/am1808exp.c @@ -7,7 +7,7 @@ #include "am1808exp.h" #include "am18x_type.h" -#define SYSTICK_PERIOD 10/* milli seconds */ +#define SYSTICK_PERIOD_MS (1) const ddr_conf_t mt46h64m16_6 = { @@ -71,16 +71,15 @@ int low_level_init(void) { // ddr_initialize(DDR0, &mt46h64m16_6); - if (AM18X_OK != (r = systick_init(SYSTICK_PERIOD))) { - // printk("systick_init() error\n"); + if (AM18X_OK != (r = systick_init(SYSTICK_PERIOD_MS))) { + printk("systick_init() error\n"); return r; } -/* if (AM18X_OK != (r = systick_start())) { + if (AM18X_OK != (r = systick_start())) { printk("systick_start() error\n"); return r; } -*/ // invalid operation ? sata_100m_clk_enable(AM18X_FALSE); @@ -90,7 +89,7 @@ int low_level_init(void) { // tps6507x_conf(); - // printk("ARM CLK: %9d Hz\n", dev_get_freq(DCLK_ID_ARM)); + printk("ARM CLK: %9d Hz\n", dev_get_freq(DCLK_ID_ARM)); return AM18X_OK; } diff --git a/lib/am18x-lib/prj/am18x_conf.h b/lib/am18x-lib/prj/am18x_conf.h index 389ae8be8..4c857f9a0 100644 --- a/lib/am18x-lib/prj/am18x_conf.h +++ b/lib/am18x-lib/prj/am18x_conf.h @@ -76,7 +76,9 @@ extern const uint32_t f_osc; #define assert(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) void assert_failed(uint8_t* file, uint32_t line); #else +#ifndef assert #define assert(expr) ((void)0) +#endif #endif // DEBUG typedef void (*none_arg_handler_t)(void); diff --git a/lib/pbio/drv/clock/clock_tiam1808.c b/lib/pbio/drv/clock/clock_tiam1808.c index 3a51bb877..5b674b403 100644 --- a/lib/pbio/drv/clock/clock_tiam1808.c +++ b/lib/pbio/drv/clock/clock_tiam1808.c @@ -7,10 +7,23 @@ #include +#include + +#include +#include + +/* High priority handler, called 1000 times a second */ +static int systick_isr(int ticks) { + etimer_request_poll(); + return 0; +} + void pbdrv_clock_init(void) { // Actual low level clocks should probably be configured at the very // start of in SystemInit in platform.c instead. // But optionally, additional things can be initialized here. + systick_set_handler(systick_isr); + arm_intr_enable(); } uint32_t pbdrv_clock_get_us(void) { @@ -19,8 +32,7 @@ uint32_t pbdrv_clock_get_us(void) { } uint32_t pbdrv_clock_get_ms(void) { - // TODO: TIAM1808 implementation. - return 0; + return systick_elapsed(); } uint32_t pbdrv_clock_get_100us(void) {