diff --git a/fusee/src/bpmp.h b/fusee/src/bpmp.h new file mode 100644 index 000000000..56c377d3b --- /dev/null +++ b/fusee/src/bpmp.h @@ -0,0 +1,19 @@ +#ifndef FUSEE_BPMP_H +#define FUSEE_BPMP_H + +#include "utils.h" + +#define BPMP_VECTOR_BASE 0x6000F000 + +#define EVP_CPU_RESET_VECTOR_0 MAKE_REG32(BPMP_VECTOR_BASE + 0x100) + +#define BPMP_VECTOR_RESET MAKE_REG32(BPMP_VECTOR_BASE + 0x200) +#define BPMP_VECTOR_UNDEF MAKE_REG32(BPMP_VECTOR_BASE + 0x204) +#define BPMP_VECTOR_SWI MAKE_REG32(BPMP_VECTOR_BASE + 0x208) +#define BPMP_VECTOR_PREFETCH_ABORT MAKE_REG32(BPMP_VECTOR_BASE + 0x20C) +#define BPMP_VECTOR_DATA_ABORT MAKE_REG32(BPMP_VECTOR_BASE + 0x210) +#define BPMP_VECTOR_UNK MAKE_REG32(BPMP_VECTOR_BASE + 0x214) +#define BPMP_VECTOR_IRQ MAKE_REG32(BPMP_VECTOR_BASE + 0x218) +#define BPMP_VECTOR_FIQ MAKE_REG32(BPMP_VECTOR_BASE + 0x21C) + +#endif diff --git a/fusee/src/flow.h b/fusee/src/flow.h new file mode 100644 index 000000000..65b9a2359 --- /dev/null +++ b/fusee/src/flow.h @@ -0,0 +1,44 @@ +#ifndef FUSEE_FLOW_CTLR_H +#define FUSEE_FLOW_CTLR_H + +#include "utils.h" + +#define FLOW_BASE 0x60007000 + +#define MAKE_FLOW_REG(ofs) MAKE_REG32(FLOW_BASE + ofs) + +#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004) +#define FLOW_CTLR_FLOW_DBG_QUAL_0 MAKE_FLOW_REG(0x050) +#define FLOW_CTLR_L2FLUSH_CONTROL_0 MAKE_FLOW_REG(0x094) +#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098) + + +static const struct { + unsigned int CPUN_CSR_OFS; + unsigned int HALT_CPUN_EVENTS_OFS; + unsigned int CC4_COREN_CTRL_OFS; +} g_flow_core_offsets[NUM_CPU_CORES] = { + {0x008, 0x000, 0x06C}, + {0x018, 0x014, 0x070}, + {0x020, 0x01C, 0x074}, + {0x028, 0x024, 0x078}, +}; + +static inline void flow_set_cc4_ctrl(uint32_t core, uint32_t cc4_ctrl) { + MAKE_FLOW_REG(g_flow_core_offsets[core].CC4_COREN_CTRL_OFS) = cc4_ctrl; +} + +static inline void flow_set_halt_events(uint32_t core, bool halt_events) { + MAKE_FLOW_REG(g_flow_core_offsets[core].HALT_CPUN_EVENTS_OFS) = (halt_events ? 0x40000F00 : 0x40000000); +} + +static inline void flow_set_csr(uint32_t core, uint32_t csr) { + MAKE_FLOW_REG(g_flow_core_offsets[core].CPUN_CSR_OFS) = (0x100 << core) | (csr << 12) | 0xC001; +} + +static inline void flow_clear_csr0_and_events(uint32_t core) { + MAKE_FLOW_REG(g_flow_core_offsets[core].CPUN_CSR_OFS) = 0; + MAKE_FLOW_REG(g_flow_core_offsets[core].HALT_CPUN_EVENTS_OFS) = 0; +} + +#endif diff --git a/fusee/src/fuse.c b/fusee/src/fuse.c new file mode 100644 index 000000000..0999fc672 --- /dev/null +++ b/fusee/src/fuse.c @@ -0,0 +1,235 @@ +#include + +#include "hwinit.h" +#include "fuse.h" +#include "timers.h" + +/* Prototypes for internal commands. */ +void fuse_make_regs_visible(void); + +void fuse_enable_power(void); +void fuse_disable_power(void); +void fuse_wait_idle(void); + +/* Initialize the FUSE driver */ +void fuse_init(void) +{ + /* + Already done by hwinit, except maybe fuse_secondary_private_key_disable (?) + fuse_make_regs_visible(); + fuse_secondary_private_key_disable(); + fuse_disable_programming(); + */ + + /* TODO: Overrides (iROM patches) and various reads happen here */ +} + +/* Make all fuse registers visible */ +void fuse_make_regs_visible(void) +{ + clock_enable_fuse(1); +} + +/* Enable power to the fuse hardware array */ +void fuse_enable_power(void) +{ + FUSE_REGS->FUSE_PWR_GOOD_SW = 1; + wait(1); +} + +/* Disable power to the fuse hardware array */ +void fuse_disable_power(void) +{ + FUSE_REGS->FUSE_PWR_GOOD_SW = 0; + wait(1); +} + +/* Wait for the fuse driver to go idle */ +void fuse_wait_idle(void) +{ + uint32_t ctrl_val = 0; + + /* Wait for STATE_IDLE */ + while ((ctrl_val & (0xF0000)) != 0x40000) + { + wait(1); + ctrl_val = FUSE_REGS->FUSE_CTRL; + } +} + +/* Read a fuse from the hardware array */ +uint32_t fuse_hw_read(uint32_t addr) +{ + fuse_wait_idle(); + + /* Program the target address */ + FUSE_REGS->FUSE_REG_ADDR = addr; + + /* Enable read operation in control register */ + uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x1; /* Set FUSE_READ command */ + FUSE_REGS->FUSE_CTRL = ctrl_val; + + fuse_wait_idle(); + + return FUSE_REGS->FUSE_REG_READ; +} + +/* Write a fuse in the hardware array */ +void fuse_hw_write(uint32_t value, uint32_t addr) +{ + fuse_wait_idle(); + + /* Program the target address and value */ + FUSE_REGS->FUSE_REG_ADDR = addr; + FUSE_REGS->FUSE_REG_WRITE = value; + + /* Enable write operation in control register */ + uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x2; /* Set FUSE_WRITE command */ + FUSE_REGS->FUSE_CTRL = ctrl_val; + + fuse_wait_idle(); +} + +/* Sense the fuse hardware array into the shadow cache */ +void fuse_hw_sense(void) +{ + fuse_wait_idle(); + + /* Enable sense operation in control register */ + uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL; + ctrl_val &= ~0x3; + ctrl_val |= 0x3; /* Set FUSE_SENSE command */ + FUSE_REGS->FUSE_CTRL = ctrl_val; + + fuse_wait_idle(); +} + +/* Disables all fuse programming. */ +void fuse_disable_programming(void) { + FUSE_REGS->FUSE_DIS_PGM = 1; +} + +/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */ +void fuse_secondary_private_key_disable(void) { + FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10; +} + + +/* Read the SKU info register from the shadow cache */ +uint32_t fuse_get_sku_info(void) +{ + return FUSE_CHIP_REGS->FUSE_SKU_INFO; +} + +/* Read the bootrom patch version from a register in the shadow cache */ +uint32_t fuse_get_bootrom_patch_version(void) +{ + return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1; +} + +/* Read a spare bit register from the shadow cache */ +uint32_t fuse_get_spare_bit(uint32_t idx) +{ + if (idx >= 32) { + return 0; + } + + return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx]; +} + +/* Read a reserved ODM register from the shadow cache */ +uint32_t fuse_get_reserved_odm(uint32_t idx) +{ + if (idx >= 8) { + return 0; + } + + return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx]; +} + +/* Derive the Device ID using values in the shadow cache */ +uint64_t fuse_get_device_id(void) { + uint64_t device_id = 0; + uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF; + uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF; + uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F; + uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0; + uint64_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F; + uint64_t derived_lot_code = 0; + for (unsigned int i = 0; i < 5; i++) { + derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F); + } + derived_lot_code &= 0x03FFFFFF; + + device_id |= y_coord << 0; + device_id |= x_coord << 9; + device_id |= wafer_id << 18; + device_id |= derived_lot_code << 24; + device_id |= fab_code << 50; + return device_id; +} + +/* Get the DRAM ID using values in the shadow cache */ +uint32_t fuse_get_dram_id(void) { + return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7; +} + +/* Derive the Hardware Type using values in the shadow cache */ +uint32_t fuse_get_hardware_type(void) { + /* This function is very different between 4.x and < 4.x */ + uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1); + + /* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { + static const uint32_t types[] = {0,1,4,3}; + + hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C; + hardware_type--; + return hardware_type > 3 ? 4 : types[hardware_type]; + } else {*/ + if (hardware_type >= 1) { + return hardware_type > 2 ? 3 : hardware_type - 1; + } else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) { + return 0; + } else { + return 3; + } +// } +} + +/* Derive the Retail Type using values in the shadow cache */ +uint32_t fuse_get_retail_type(void) { + /* Retail type = IS_RETAIL | UNIT_TYPE */ + uint32_t retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] & 3); + if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */ + return 1; + } else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */ + return 0; + } + return 2; /* IS_RETAIL | DEV_UNIT */ +} + +/* Derive the 16-byte Hardware Info using values in the shadow cache, and copy to output buffer. */ +void fuse_get_hardware_info(void *dst) { + uint32_t hw_info[0x4]; + + uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F; + uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF; + uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF; + uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F; + uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0; + uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF; + uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F; + uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF; + + /* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */ + hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse)); + hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2)); + hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6)); + hw_info[3] = (uint32_t)(vendor_code); + + memcpy(dst, hw_info, 0x10); +} diff --git a/fusee/src/fuse.h b/fusee/src/fuse.h new file mode 100644 index 000000000..1dcbc8d60 --- /dev/null +++ b/fusee/src/fuse.h @@ -0,0 +1,197 @@ +#ifndef FUSEE_FUSE_H +#define FUSEE_FUSE_H + +#include +#include + +typedef struct { + uint32_t FUSE_CTRL; + uint32_t FUSE_REG_ADDR; + uint32_t FUSE_REG_READ; + uint32_t FUSE_REG_WRITE; + uint32_t FUSE_TIME_RD1; + uint32_t FUSE_TIME_RD2; + uint32_t FUSE_TIME_PGM1; + uint32_t FUSE_TIME_PGM2; + uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSEBYPASS; + uint32_t FUSE_PRIVATEKEYDISABLE; + uint32_t FUSE_DIS_PGM; + uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_PWR_GOOD_SW; + uint32_t _0x38[0x32]; +} fuse_registers_t; + +typedef struct { + uint32_t FUSE_PRODUCTION_MODE; + uint32_t _0x4; + uint32_t _0x8; + uint32_t _0xC; + uint32_t FUSE_SKU_INFO; + uint32_t FUSE_CPU_SPEEDO_0; + uint32_t FUSE_CPU_IDDQ; + uint32_t _0x1C; + uint32_t _0x20; + uint32_t _0x24; + uint32_t FUSE_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1; + uint32_t FUSE_CPU_SPEEDO_2; + uint32_t FUSE_SOC_SPEEDO_0; + uint32_t FUSE_SOC_SPEEDO_1; + uint32_t FUSE_SOC_SPEEDO_2; + uint32_t FUSE_SOC_IDDQ; + uint32_t _0x44; + uint32_t FUSE_FA; + uint32_t _0x4C; + uint32_t _0x50; + uint32_t _0x54; + uint32_t _0x58; + uint32_t _0x5C; + uint32_t _0x60; + uint32_t FUSE_PUBLIC_KEY[0x8]; + uint32_t FUSE_TSENSOR_1; + uint32_t FUSE_TSENSOR_2; + uint32_t _0x8C; + uint32_t FUSE_CP_REV; + uint32_t _0x94; + uint32_t FUSE_TSENSOR_0; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_SECURITY_MODE; + uint32_t FUSE_PRIVATE_KEY[0x4]; + uint32_t FUSE_DEVICE_KEY; + uint32_t _0xB8; + uint32_t _0xBC; + uint32_t FUSE_RESERVED_SW; + uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_RESERVED_ODM[0x8]; + uint32_t _0xE8; + uint32_t _0xEC; + uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_SKU_DIRECT_CONFIG; + uint32_t _0xF8; + uint32_t _0xFC; + uint32_t FUSE_VENDOR_CODE; + uint32_t FUSE_FAB_CODE; + uint32_t FUSE_LOT_CODE_0; + uint32_t FUSE_LOT_CODE_1; + uint32_t FUSE_WAFER_ID; + uint32_t FUSE_X_COORDINATE; + uint32_t FUSE_Y_COORDINATE; + uint32_t _0x11C; + uint32_t _0x120; + uint32_t FUSE_SATA_CALIB; + uint32_t FUSE_GPU_IDDQ; + uint32_t FUSE_TSENSOR_3; + uint32_t _0x130; + uint32_t _0x134; + uint32_t _0x138; + uint32_t _0x13C; + uint32_t _0x140; + uint32_t _0x144; + uint32_t FUSE_OPT_SUBREVISION; + uint32_t _0x14C; + uint32_t _0x150; + uint32_t FUSE_TSENSOR_4; + uint32_t FUSE_TSENSOR_5; + uint32_t FUSE_TSENSOR_6; + uint32_t FUSE_TSENSOR_7; + uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_PKC_DISABLE; + uint32_t _0x16C; + uint32_t _0x170; + uint32_t _0x174; + uint32_t _0x178; + uint32_t _0x17C; + uint32_t FUSE_TSENSOR_COMMON; + uint32_t _0x184; + uint32_t _0x188; + uint32_t _0x18C; + uint32_t _0x190; + uint32_t _0x194; + uint32_t _0x198; + uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t _0x1A0; + uint32_t _0x1A4; + uint32_t _0x1A8; + uint32_t _0x1AC; + uint32_t _0x1B0; + uint32_t _0x1B4; + uint32_t _0x1B8; + uint32_t _0x1BC; + uint32_t _0x1D0; + uint32_t FUSE_TSENSOR_8; + uint32_t _0x1D8; + uint32_t _0x1DC; + uint32_t _0x1E0; + uint32_t _0x1E4; + uint32_t _0x1E8; + uint32_t _0x1EC; + uint32_t _0x1F0; + uint32_t _0x1F4; + uint32_t _0x1F8; + uint32_t _0x1FC; + uint32_t _0x200; + uint32_t FUSE_RESERVED_CALIB; + uint32_t _0x208; + uint32_t _0x20C; + uint32_t _0x210; + uint32_t _0x214; + uint32_t _0x218; + uint32_t FUSE_TSENSOR_9; + uint32_t _0x220; + uint32_t _0x224; + uint32_t _0x228; + uint32_t _0x22C; + uint32_t _0x230; + uint32_t _0x234; + uint32_t _0x238; + uint32_t _0x23C; + uint32_t _0x240; + uint32_t _0x244; + uint32_t _0x248; + uint32_t _0x24C; + uint32_t FUSE_USB_CALIB_EXT; + uint32_t _0x254; + uint32_t _0x258; + uint32_t _0x25C; + uint32_t _0x260; + uint32_t _0x264; + uint32_t _0x268; + uint32_t _0x26C; + uint32_t _0x270; + uint32_t _0x274; + uint32_t _0x278; + uint32_t _0x27C; + uint32_t FUSE_SPARE_BIT[0x20]; +} fuse_chip_registers_t; + +static inline volatile fuse_registers_t *get_fuse_regs(void) { + return (volatile fuse_registers_t *)(0x7000F000 + 0x800); +} + +static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) { + return (volatile fuse_chip_registers_t *)(0x7000F000 + 0x900); +} +#define FUSE_REGS (get_fuse_regs()) +#define FUSE_CHIP_REGS (get_fuse_chip_regs()) + +void fuse_init(void); + +uint32_t fuse_hw_read(uint32_t addr); +void fuse_hw_write(uint32_t value, uint32_t addr); +void fuse_hw_sense(void); +void fuse_disable_programming(void); +void fuse_secondary_private_key_disable(void); + +uint32_t fuse_get_sku_info(void); +uint32_t fuse_get_spare_bit(uint32_t idx); +uint32_t fuse_get_reserved_odm(uint32_t idx); + +uint32_t fuse_get_bootrom_patch_version(void); +uint64_t fuse_get_device_id(void); +uint32_t fuse_get_dram_id(void); +uint32_t fuse_get_hardware_type(void); +uint32_t fuse_get_retail_type(void); +void fuse_get_hardware_info(void *dst); + +#endif diff --git a/fusee/src/hwinit.h b/fusee/src/hwinit.h new file mode 100644 index 000000000..543c9638d --- /dev/null +++ b/fusee/src/hwinit.h @@ -0,0 +1,33 @@ +#ifndef FUSEE_HWINIT_H +#define FUSEE_HWINIT_H + +/* Symbols from hwinit that we're using, but w/o importing macro definitions that may clash with ours */ + +#include "hwinit/types.h" +#include "hwinit/hwinit.h" +#include "hwinit/i2c.h" + +#define UART_A 0 +#define UART_B 1 +#define UART_C 2 +#define BAUD_115200 115200 + +void uart_init(u32 idx, u32 baud); +void uart_wait_idle(u32 idx, u32 which); +void uart_send(u32 idx, u8 *buf, u32 len); +void uart_recv(u32 idx, u8 *buf, u32 len); + +void display_init(); +void display_end(); + +void clock_enable_fuse(u32 enable); + +/*! Show one single color on the display. */ +void display_color_screen(u32 color); + +/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */ +u32 *display_init_framebuffer(); + +void cluster_boot_cpu0(u64 entry, u32 ns_disable); + +#endif diff --git a/fusee/src/hwinit/btn.c b/fusee/src/hwinit/btn.c new file mode 100644 index 000000000..50bf1b37d --- /dev/null +++ b/fusee/src/hwinit/btn.c @@ -0,0 +1,25 @@ +#include "btn.h" +#include "i2c.h" +#include "t210.h" + +u32 btn_read() +{ + u32 res = 0; + if(!(GPIO_6(0x3C) & 0x80)) + res |= BTN_VOL_DOWN; + if(!(GPIO_6(0x3C) & 0x40)) + res |= BTN_VOL_UP; + if(i2c_recv_byte(4, 0x3C, 0x15) & 0x4) + res |= BTN_POWER; + return res; +} + +u32 btn_wait() +{ + u32 res = 0, btn = btn_read(); + do + { + res = btn_read(); + } while (btn == res); + return res; +} diff --git a/fusee/src/hwinit/btn.h b/fusee/src/hwinit/btn.h new file mode 100644 index 000000000..7ae7af9e7 --- /dev/null +++ b/fusee/src/hwinit/btn.h @@ -0,0 +1,13 @@ +#ifndef _BTN_H_ +#define _BTN_H_ + +#include "types.h" + +#define BTN_POWER 0x1 +#define BTN_VOL_DOWN 0x2 +#define BTN_VOL_UP 0x4 + +u32 btn_read(); +u32 btn_wait(); + +#endif diff --git a/fusee/src/hwinit/clock.c b/fusee/src/hwinit/clock.c new file mode 100644 index 000000000..b0b4ab93b --- /dev/null +++ b/fusee/src/hwinit/clock.c @@ -0,0 +1,145 @@ +#include "clock.h" +#include "t210.h" +#include "util.h" + +static const clock_t _clock_uart[] = { + /* UART A */ { 4, 0x10, 0x178, 6, 0, 0 }, + /* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 }, + /* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 }, + /* UART D */ { 0 }, + /* UART E */ { 0 } +}; + +static const clock_t _clock_i2c[] = { + /* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 }, + /* I2C2 */ { 0 }, + /* I2C3 */ { 0 }, + /* I2C4 */ { 0 }, + /* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 }, + /* I2C6 */ { 0 } +}; + +static clock_t _clock_se = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 }; + +static clock_t _clock_host1x = { 4, 0x10, 0x180, 0x1C, 4, 3 }; +static clock_t _clock_tsec = { 0xC, 0x18, 0x1F4, 0x13, 0, 2 }; +static clock_t _clock_sor_safe = { 0x2A4, 0x298, 0, 0x1E, 0, 0 }; +static clock_t _clock_sor0 = { 0x28C, 0x280, 0, 0x16, 0, 0 }; +static clock_t _clock_sor1 = { 0x28C, 0x280, 0x410, 0x17, 0, 2 }; +static clock_t _clock_kfuse = { 8, 0x14, 0, 8, 0, 0 }; + +static clock_t _clock_coresight = { 0xC, 0x18, 0x1D4, 9, 0, 4}; + +void clock_enable(const clock_t *clk) +{ + //Put clock into reset. + CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index); + //Disable. + CLOCK(clk->enable) &= ~(1 << clk->index); + //Configure clock source if required. + if (clk->source) + CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29); + //Enable. + CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index); + //Take clock off reset. + CLOCK(clk->reset) &= ~(1 << clk->index); +} + +void clock_disable(const clock_t *clk) +{ + //Put clock into reset. + CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index); + //Disable. + CLOCK(clk->enable) &= ~(1 << clk->index); +} + +void clock_enable_fuse(u32 enable) +{ + CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000; +} + +void clock_enable_uart(u32 idx) +{ + clock_enable(&_clock_uart[idx]); +} + +void clock_enable_i2c(u32 idx) +{ + clock_enable(&_clock_i2c[idx]); +} + +void clock_enable_se() +{ + clock_enable(&_clock_se); +} + +void clock_enable_host1x() +{ + clock_enable(&_clock_host1x); +} + +void clock_enable_tsec() +{ + clock_enable(&_clock_tsec); +} + +void clock_enable_sor_safe() +{ + clock_enable(&_clock_sor_safe); +} + +void clock_enable_sor0() +{ + clock_enable(&_clock_sor0); +} + +void clock_enable_sor1() +{ + clock_enable(&_clock_sor1); +} + +void clock_enable_kfuse() +{ + //clock_enable(&_clock_kfuse); + CLOCK(0x8) = CLOCK(0x8) & 0xFFFFFEFF | 0x100; + CLOCK(0x14) &= 0xFFFFFEFF; + CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100; + sleep(10); + CLOCK(0x8) &= 0xFFFFFEFF; + sleep(20); +} + +void clock_disable_host1x() +{ + clock_disable(&_clock_host1x); +} + +void clock_disable_tsec() +{ + clock_disable(&_clock_tsec); +} + +void clock_disable_sor_safe() +{ + clock_disable(&_clock_sor_safe); +} + +void clock_disable_sor0() +{ + clock_disable(&_clock_sor0); +} + +void clock_disable_sor1() +{ + clock_disable(&_clock_sor1); +} + +void clock_disable_kfuse() +{ + clock_disable(&_clock_kfuse); +} + +void clock_enable_coresight() +{ + clock_enable(&_clock_coresight); +} diff --git a/fusee/src/hwinit/clock.h b/fusee/src/hwinit/clock.h new file mode 100644 index 000000000..027fd4b26 --- /dev/null +++ b/fusee/src/hwinit/clock.h @@ -0,0 +1,51 @@ +#ifndef _CLOCK_H_ +#define _CLOCK_H_ + +#include "types.h" + +/*! Clock registers. */ +#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28 +#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C +#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30 +#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48 +#define CLK_RST_CONTROLLER_OSC_CTRL 0x50 +#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C +#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284 +#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308 +#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328 +#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358 +#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454 +#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C +#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8 + +typedef struct _clock_t +{ + u32 reset; + u32 enable; + u32 source; + u8 index; + u8 clk_src; + u8 clk_div; +} clock_t; + +void clock_enable(const clock_t *clk); +void clock_disable(const clock_t *clk); +void clock_enable_fuse(u32 enable); +void clock_enable_uart(u32 idx); +void clock_enable_i2c(u32 idx); +void clock_enable_se(); +void clock_enable_host1x(); +void clock_enable_tsec(); +void clock_enable_sor_safe(); +void clock_enable_sor0(); +void clock_enable_sor1(); +void clock_enable_kfuse(); +void clock_disable_host1x(); +void clock_disable_tsec(); +void clock_disable_sor_safe(); +void clock_disable_sor0(); +void clock_disable_sor1(); +void clock_disable_kfuse(); +void clock_enable_coresight(); + +#endif diff --git a/fusee/src/hwinit/cluster.c b/fusee/src/hwinit/cluster.c new file mode 100644 index 000000000..90015205f --- /dev/null +++ b/fusee/src/hwinit/cluster.c @@ -0,0 +1,114 @@ +#include "cluster.h" +#include "i2c.h" +#include "clock.h" +#include "util.h" +#include "pmc.h" +#include "t210.h" + +void _cluster_enable_power() +{ + u8 tmp; + + if (i2c_recv_buf_small(&tmp, 1, I2C_5, 0x3C, 0x40)) + { + tmp &= 0xDFu; + i2c_send_byte(I2C_5, 0x3C, 0x40, tmp); + } + i2c_send_byte(I2C_5, 0x3C, 0x3B, 0x09); + + //Enable cores power. + i2c_send_byte(I2C_5, 0x1B, 0x02, 0x20); + i2c_send_byte(I2C_5, 0x1B, 0x03, 0x8D); + i2c_send_byte(I2C_5, 0x1B, 0x00, 0xB7); + i2c_send_byte(I2C_5, 0x1B, 0x01, 0xB7); +} + +int _cluster_pmc_enable_partition(u32 part, u32 toggle) +{ + //Check if the partition has already been turned on. + if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part) + return 0; + + u32 i = 5001; + while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100) + { + sleep(1); + i--; + if (i < 1) + return 0; + } + + PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | 0x100; + + i = 5001; + while (i > 0) + { + if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part) + break; + sleep(1); + i--; + } + + return 1; +} + +void cluster_enable_cpu0(u64 entry, u32 ns_disable) +{ + //Set ACTIVE_CLUSER to FAST. + FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE; + + _cluster_enable_power(); + + if (!(CLOCK(0xE0) & 0x40000000)) + { + CLOCK(0x518) &= 0xFFFFFFF7; + sleep(2); + CLOCK(0xE4) = CLOCK(0xE4) & 0xFFFBFFFF | 0x40000; + CLOCK(0xE0) = 0x40404E02; + } + while (!(CLOCK(0xE0) & 0x8000000)) + ; + + CLOCK(0x3B4) = CLOCK(0x3B4) & 0x1FFFFF00 | 6; + CLOCK(0x360) = CLOCK(0x360) & 0xFFFFFFF7 | 8; + CLOCK(0x20) = 0x20008888; + CLOCK(0x24) = 0x80000000; + CLOCK(0x440) = 1; + + clock_enable_coresight(); + + CLOCK(0x388) = CLOCK(0x388) & 0xFFFFE000; + + //Enable CPU rail. + _cluster_pmc_enable_partition(1, 0); + //Enable cluster 0 non-CPU. + _cluster_pmc_enable_partition(0x8000, 15); + //Enable CE0. + _cluster_pmc_enable_partition(0x4000, 14); + + //Request and wait for RAM repair. + FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1; + while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2)) + ; + + EXCP_VEC(0x100) = 0; + + if(ns_disable) + { + //Set reset vectors. + SB(SB_AA64_RESET_LOW) = (u32)entry | 1; + SB(SB_AA64_RESET_HIGH) = (u32)(entry >> 32); + //Non-secure reset vector write disable. + SB(SB_CSR_0) = 2; + } + else + { + //Set reset vectors. + SB(SB_AA64_RESET_LOW) = (u32)entry; + SB(SB_AA64_RESET_HIGH) = (u32)(entry >> 32); + } + + //Until here the CPU was in reset, this kicks execution. + CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7; + CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F; +} diff --git a/fusee/src/hwinit/cluster.h b/fusee/src/hwinit/cluster.h new file mode 100644 index 000000000..2a2d7e18c --- /dev/null +++ b/fusee/src/hwinit/cluster.h @@ -0,0 +1,12 @@ +#ifndef _CLUSTER_H_ +#define _CLUSTER_H_ + +#include "types.h" + +/*! Flow controller registers. */ +#define FLOW_CTLR_RAM_REPAIR 0x40 +#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98 + +void cluster_boot_cpu0(u64 entry, u32 ns_disable); + +#endif diff --git a/fusee/src/hwinit/di.c b/fusee/src/hwinit/di.c new file mode 100644 index 000000000..3e4431ead --- /dev/null +++ b/fusee/src/hwinit/di.c @@ -0,0 +1,196 @@ +#include "di.h" +#include "t210.h" +#include "util.h" +#include "i2c.h" +#include "pmc.h" + +#include "di.inl" + +static u32 _display_ver = 0; + +static void _display_dsi_wait(u32 timeout, u32 off, u32 mask) +{ + u32 end = TMR(0x10) + timeout; + while (TMR(0x10) < end && DSI(off) & mask) + ; + sleep(5); +} + +void display_init() +{ + //Power on. + i2c_send_byte(I2C_5, 0x3C, 0x23, 0xD0); + i2c_send_byte(I2C_5, 0x3C, 0x3D, 0x09); + + //Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. + CLOCK(0x30C) = 0x1010000; + CLOCK(0x328) = 0x1010000; + CLOCK(0x304) = 0x18000000; + CLOCK(0x320) = 0x18000000; + CLOCK(0x284) = 0x20000; + CLOCK(0x66C) = 0xA; + CLOCK(0x448) = 0x80000; + CLOCK(0x620) = 0xA; + + //DPD idle. + PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000; + PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000; + + //Config pins. + PINMUX_AUX(0x1D0) &= 0xFFFFFFEF; + PINMUX_AUX(0x1D4) &= 0xFFFFFFEF; + PINMUX_AUX(0x1FC) &= 0xFFFFFFEF; + PINMUX_AUX(0x200) &= 0xFFFFFFEF; + PINMUX_AUX(0x204) &= 0xFFFFFFEF; + + GPIO_3(0x00) = GPIO_3(0x00) & 0xFFFFFFFC | 0x3; + GPIO_3(0x10) = GPIO_3(0x10) & 0xFFFFFFFC | 0x3; + GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFE | 0x1; + + sleep(10000u); + + GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFD | 0x2; + + sleep(10000); + + GPIO_6(0x04) = GPIO_6(0x04) & 0xFFFFFFF8 | 0x7; + GPIO_6(0x14) = GPIO_6(0x14) & 0xFFFFFFF8 | 0x7; + GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFD | 0x2; + + //Config display interface and display. + MIPI_CAL(0x60) = 0; + + exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4); + exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94); + exec_cfg((u32 *)DSI_BASE, _display_config_3, 60); + + sleep(10000); + + GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFB | 0x4; + + sleep(60000); + + DSI(_DSIREG(DSI_DSI_BTA_TIMING)) = 0x50204; + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x337; + DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2; + _display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3); + + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x406; + DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2; + _display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3); + + DSI(_DSIREG(DSI_HOST_DSI_CONTROL)) = 0x200B; + _display_dsi_wait(150000, _DSIREG(DSI_HOST_DSI_CONTROL), 8); + + sleep(5000); + + _display_ver = DSI(_DSIREG(DSI_DSI_RD_DATA)); + if (_display_ver == 0x10) + exec_cfg((u32 *)DSI_BASE, _display_config_4, 43); + + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1105; + DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2; + + sleep(180000); + + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2905; + DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2; + + sleep(20000); + + exec_cfg((u32 *)DSI_BASE, _display_config_5, 21); + exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3); + DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; + exec_cfg((u32 *)DSI_BASE, _display_config_7, 10); + + sleep(10000); + + exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6); + exec_cfg((u32 *)DSI_BASE, _display_config_9, 4); + exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16); + + sleep(10000); + + exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113); +} + +void display_end() +{ + GPIO_6(0x24) &= 0xFFFFFFFE; + DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 1; + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2805; + + u32 end = HOST1X(0x30A4) + 5; + while (HOST1X(0x30A4) < end) + ; + + DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = 5; + DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 0; + + exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17); + exec_cfg((u32 *)DSI_BASE, _display_config_13, 16); + + sleep(10000); + + if (_display_ver == 0x10) + exec_cfg((u32 *)DSI_BASE, _display_config_14, 22); + + DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1005; + DSI(_DSIREG(DSI_DSI_TRIGGER)) = 2; + + sleep(50000); + + GPIO_6(0x24) &= 0xFFFFFFFB; + + sleep(10000); + + GPIO_3(0x20) &= 0xFFFFFFFD; + + sleep(10000); + + GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1; + + sleep(10000); + + //Disable clocks. + CLOCK(0x308) = 0x1010000; + CLOCK(0x32C) = 0x1010000; + CLOCK(0x300) = 0x18000000; + CLOCK(0x324) = 0x18000000; + + DSI(_DSIREG(DSI_PAD_CONTROL)) = 0x10F010F; + DSI(_DSIREG(DSI_DSI_POWER_CONTROL)) = 0; + + GPIO_6(0x04) &= 0xFFFFFFFE; + + PINMUX_AUX(0x1FC) = PINMUX_AUX(0x1FC) & 0xFFFFFFEF | 0x10; + PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1; +} + +void display_color_screen(u32 color) +{ + exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8); + + //Configure display to show single color. + DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0; + DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0; + DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0; + DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color; + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE | 1; + + sleep(35000); + + GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1; +} + +u32 *display_init_framebuffer(u32 *fb) +{ + //This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 768). + exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32); + + sleep(35000); + + GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1; + + return (u32 *)0xC0000000; +} diff --git a/fusee/src/hwinit/di.h b/fusee/src/hwinit/di.h new file mode 100644 index 000000000..aacf7340f --- /dev/null +++ b/fusee/src/hwinit/di.h @@ -0,0 +1,56 @@ +#ifndef _DI_H_ +#define _DI_H_ + +#include "types.h" + +/*! Display registers. */ +#define _DIREG(reg) ((reg) * 4) +#define DC_CMD_DISPLAY_COMMAND 0x32 +#define DC_CMD_STATE_ACCESS 0x40 +#define DC_CMD_STATE_CONTROL 0x41 +#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42 +#define DC_DISP_DISP_WIN_OPTIONS 0x402 +#define DC_DISP_DISP_CLOCK_CONTROL 0x42E +#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4 +#define DC_WIN_AD_WIN_OPTIONS 0xB80 +#define DC_WIN_BD_WIN_OPTIONS 0xD80 +#define DC_WIN_CD_WIN_OPTIONS 0xF80 + +//The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). +#define DC_X_WIN_XD_WIN_OPTIONS 0x700 +#define DC_X_WIN_XD_COLOR_DEPTH 0x703 +#define DC_X_WIN_XD_POSITION 0x704 +#define DC_X_WIN_XD_SIZE 0x705 +#define DC_X_WIN_XD_PRESCALED_SIZE 0x706 +#define DC_X_WIN_XD_H_INITIAL_DDA 0x707 +#define DC_X_WIN_XD_V_INITIAL_DDA 0x708 +#define DC_X_WIN_XD_DDA_INCREMENT 0x709 +#define DC_X_WIN_XD_LINE_STRIDE 0x70A + +//The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). +#define DC_X_WINBUF_XD_START_ADDR 0x800 +#define DC_X_WINBUF_XD_ADDR_H_OFFSET 0x806 +#define DC_X_WINBUF_XD_ADDR_V_OFFSET 0x808 +#define DC_X_WINBUF_XD_SURFACE_KIND 0x80B + +/*! Display serial interface registers. */ +#define _DSIREG(reg) ((reg) * 4) +#define DSI_DSI_RD_DATA 0x9 +#define DSI_DSI_WR_DATA 0xA +#define DSI_DSI_POWER_CONTROL 0xB +#define DSI_HOST_DSI_CONTROL 0xF +#define DSI_DSI_TRIGGER 0x13 +#define DSI_DSI_BTA_TIMING 0x3F +#define DSI_PAD_CONTROL 0x4B +#define DSI_DSI_VID_MODE_CONTROL 0x4E + +void display_init(); +void display_end(); + +/*! Show one single color on the display. */ +void display_color_screen(u32 color); + +/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */ +u32 *display_init_framebuffer(); + +#endif diff --git a/fusee/src/hwinit/di.inl b/fusee/src/hwinit/di.inl new file mode 100644 index 000000000..b2e6d1533 --- /dev/null +++ b/fusee/src/hwinit/di.inl @@ -0,0 +1,532 @@ +//Clock config. +static const cfg_op_t _display_config_1[4] = { + {0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 + {0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE + {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1 + {0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC +}; + +//Display A config. +static const cfg_op_t _display_config_2[94] = { + {0x40, 0}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0x43, 0x54}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0x42, 0x10}, + {0x42, 0x20}, + {0x42, 0x40}, + {0x480, 0}, + {0x403, 0}, + {0x404, 0}, + {0x36, 0x50155}, + {1, 0x100}, + {0x28, 0x109}, + {DC_CMD_STATE_CONTROL, 0xF00}, + {DC_CMD_STATE_CONTROL, 0xF}, + {0x40, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x10}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x10}, + {0x42, 0x10}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x20}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x20}, + {0x42, 0x20}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x42, 0x40}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x40}, + {0x42, 0x40}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x430, 8}, + {0x42F, 0}, + {0x307, 0x1000000}, + {0x309, 0}, + {0x4E4, 0}, + {0x300, 0}, + {DC_CMD_STATE_CONTROL, 0xF00}, + {DC_CMD_STATE_CONTROL, 0xF}, + {0x42, 0x10}, + {0x716, 0x10000FF}, + {0x42, 0x20}, + {0x716, 0x10000FF}, + {0x42, 0x40}, + {0x716, 0x10000FF}, + {0x31, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x402, 0}, + {0x32, 0}, + {DC_CMD_STATE_CONTROL, 0xF00}, + {DC_CMD_STATE_CONTROL, 0xF} +}; + +//DSI config. +static const cfg_op_t _display_config_3[60] = { + {0xA, 0}, + {0xC, 0}, + {0xD, 0}, + {0xE, 0}, + {0x1B, 0}, + {0x1C, 0}, + {0x1D, 0}, + {0x1E, 0}, + {0x33, 0}, + {0x23, 0}, + {0x25, 0}, + {0x27, 0}, + {0x29, 0}, + {0x2B, 0}, + {0x2D, 0}, + {0x24, 0}, + {0x26, 0}, + {0x28, 0}, + {0x2A, 0}, + {0x2C, 0}, + {0x2E, 0}, + {0x10, 0}, + {0x4C, 0}, + {0x11, 0x18}, + {0x12, 0x1E0}, + {0x13, 0}, + {0x1A, 0}, + {0x34, 0}, + {0x35, 0}, + {0x36, 0}, + {0x37, 0}, + {0x4F, 0}, + {0x3C, 0x6070601}, + {0x3D, 0x40A0E05}, + {0x3E, 0x30109}, + {0x3F, 0x190A14}, + {0x44, 0x2000FFFF}, + {0x45, 0x7652000}, + {0x46, 0}, + {0x4B, 0}, + {DSI_DSI_POWER_CONTROL, 1}, + {DSI_DSI_POWER_CONTROL, 1}, + {DSI_DSI_POWER_CONTROL, 0}, + {DSI_DSI_POWER_CONTROL, 0}, + {0x4F, 0}, + {0x3C, 0x6070601}, + {0x3D, 0x40A0E05}, + {0x3E, 0x30118}, + {0x3F, 0x190A14}, + {0x44, 0x2000FFFF}, + {0x45, 0x13432000}, + {0x46, 0}, + {0xF, 0x102003}, + {0x10, 0x31}, + {DSI_DSI_POWER_CONTROL, 1}, + {DSI_DSI_POWER_CONTROL, 1}, + {0x12, 0x40}, + {0x13, 0}, + {0x14, 0}, + {0x1A, 0} +}; + +//DSI config (if ver == 0x10). +static const cfg_op_t _display_config_4[43] = { + {DSI_DSI_WR_DATA, 0x439}, + {DSI_DSI_WR_DATA, 0x9483FFB9}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0xBD15}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x1939}, + {DSI_DSI_WR_DATA, 0xAAAAAAD8}, + {DSI_DSI_WR_DATA, 0xAAAAAAEB}, + {DSI_DSI_WR_DATA, 0xAAEBAAAA}, + {DSI_DSI_WR_DATA, 0xAAAAAAAA}, + {DSI_DSI_WR_DATA, 0xAAAAAAEB}, + {DSI_DSI_WR_DATA, 0xAAEBAAAA}, + {DSI_DSI_WR_DATA, 0xAA}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x1BD15}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x2739}, + {DSI_DSI_WR_DATA, 0xFFFFFFD8}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFF}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x2BD15}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0xF39}, + {DSI_DSI_WR_DATA, 0xFFFFFFD8}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFFFF}, + {DSI_DSI_WR_DATA, 0xFFFFFF}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0xBD15}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x6D915}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x439}, + {DSI_DSI_WR_DATA, 0xB9}, + {DSI_DSI_TRIGGER, 2} +}; + +//DSI config. +static const cfg_op_t _display_config_5[21] = { + {0x4F, 0}, + {0x3C, 0x6070601}, + {0x3D, 0x40A0E05}, + {0x3E, 0x30172}, + {0x3F, 0x190A14}, + {0x44, 0x20000A40}, + {0x45, 0x5A2F2000}, + {0x46, 0}, + {0x23, 0x40000208}, + {0x27, 0x40000308}, + {0x2B, 0x40000308}, + {0x25, 0x40000308}, + {0x29, 0x3F3B2B08}, + {0x2A, 0x2CC}, + {0x2D, 0x3F3B2B08}, + {0x2E, 0x2CC}, + {0x34, 0xCE0000}, + {0x35, 0x87001A2}, + {0x36, 0x190}, + {0x37, 0x190}, + {0xF, 0}, +}; + +//Clock config. +static const cfg_op_t _display_config_6[3] = { + {0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE + {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1 + {0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC +}; + +//DSI config. +static const cfg_op_t _display_config_7[10] = { + {0x13, 0}, + {0x10, 0}, + {0x11, 6}, + {0x12, 0x1E0}, + {DSI_DSI_POWER_CONTROL, 1}, + {0x10, 0x103032}, + {0xF, 0x33}, + {0x10, 0x103032}, + {0xF, 3}, + {0xF, 0x23} +}; + +//MIPI CAL config. +static const cfg_op_t _display_config_8[6] = { + {0x18, 0}, + {2, 0xF3F10000}, + {0x16, 1}, + {0x18, 0}, + {0x18, 0x10010}, + {0x17, 0x300} +}; + +//DSI config. +static const cfg_op_t _display_config_9[4] = { + {0x4F, 0}, + {0x50, 0}, + {0x51, 0x3333}, + {0x52, 0} +}; + +//MIPI CAL config. +static const cfg_op_t _display_config_10[16] = { + {0xE, 0x200200}, + {0xF, 0x200200}, + {0x19, 0x200002}, + {0x1A, 0x200002}, + {5, 0}, + {6, 0}, + {7, 0}, + {8, 0}, + {9, 0}, + {0xA, 0}, + {0x10, 0}, + {0x11, 0}, + {0x1A, 0}, + {0x1C, 0}, + {0x1D, 0}, + {0, 0x2A000001} +}; + +//Display A config. +static const cfg_op_t _display_config_11[113] = { + {0x40, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x10}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x10}, + {0x42, 0x10}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x20}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x20}, + {0x42, 0x20}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x42, 0x40}, + {0x70E, 0}, + {0x700, 0}, + {0x42, 0x40}, + {0x42, 0x40}, + {0x611, 0xF0}, + {0x612, 0x12A}, + {0x613, 0}, + {0x614, 0x198}, + {0x615, 0x39B}, + {0x616, 0x32F}, + {0x617, 0x204}, + {0x618, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x430, 8}, + {0x42F, 0}, + {0x307, 0x1000000}, + {0x309, 0}, + {0x4E4, 0}, + {0x300, 0}, + {DC_CMD_STATE_CONTROL, 0xF00}, + {DC_CMD_STATE_CONTROL, 0xF}, + {0x42, 0x10}, + {0x716, 0x10000FF}, + {0x42, 0x20}, + {0x716, 0x10000FF}, + {0x42, 0x40}, + {0x716, 0x10000FF}, + {0x31, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x402, 0}, + {0x32, 0}, + {DC_CMD_STATE_CONTROL, 0xF00}, + {DC_CMD_STATE_CONTROL, 0xF}, + {0x40, 0}, + {0x405, 0}, + {0x406, 0x10000}, + {0x407, 0x10048}, + {0x408, 0x90048}, + {0x409, 0x50002D0}, + {0x40A, 0xA0088}, + {0x431, 0x10001}, + {0x303, 0}, + {0x432, 5}, + {0x42F, 0}, + {0x42E, 0}, + {0x31, 0}, + {0x42, 0x10}, + {0x700, 0}, + {0x42, 0x20}, + {0x700, 0}, + {0x42, 0x40}, + {0x700, 0}, + {0x402, 0}, + {0x32, 0x20}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0x40, 5}, + {0x40A, 0xA0088}, + {0x40, 0}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0, 0x301}, + {0, 0x301}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0x40, 0}, + {0x42E, 4}, + {0x430, 8}, + {0x31, 0} +}; + +////Display A config. +static const cfg_op_t _display_config_12[17] = { + {0x40A, 0xA0088}, + {0x38, 0}, + {0x40, 0}, + {0x39, 0}, + {0x28, 0}, + {0x32, 0}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0, 0x301}, + {0, 0x301}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1}, + {0x36, 0}, + {DC_CMD_STATE_CONTROL, 0x100}, + {DC_CMD_STATE_CONTROL, 1} +}; + +//DSI config. +static const cfg_op_t _display_config_13[16] = { + {DSI_DSI_POWER_CONTROL, 0}, + {0x4F, 0}, + {0x3C, 0x6070601}, + {0x3D, 0x40A0E05}, + {0x3E, 0x30109}, + {0x3F, 0x190A14}, + {0x44, 0x2000FFFF}, + {0x45, 0x7652000}, + {0x46, 0}, + {0xF, 0x102003}, + {0x10, 0x31}, + {DSI_DSI_POWER_CONTROL, 1}, + {0x12, 0x40}, + {0x13, 0}, + {0x14, 0}, + {0x1A, 0} +}; + +//DSI config (if ver == 0x10). +static const cfg_op_t _display_config_14[22] = { + {DSI_DSI_WR_DATA, 0x439}, + {DSI_DSI_WR_DATA, 0x9483FFB9}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x2139}, + {DSI_DSI_WR_DATA, 0x191919D5}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19191919}, + {DSI_DSI_WR_DATA, 0x19}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0xB39}, + {DSI_DSI_WR_DATA, 0x4F0F41B1}, + {DSI_DSI_WR_DATA, 0xF179A433}, + {DSI_DSI_WR_DATA, 0x2D81}, + {DSI_DSI_TRIGGER, 2}, + {DSI_DSI_WR_DATA, 0x439}, + {DSI_DSI_WR_DATA, 0xB9}, + {DSI_DSI_TRIGGER, 2} +}; + +//Display A config. +static const cfg_op_t cfg_display_one_color[8] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE + {DC_CMD_DISPLAY_COMMAND, 0x20} //DISPLAY_CTRL_MODE: continuous display. +}; + +//Display A config. +static const cfg_op_t cfg_display_framebuffer[32] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A. + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE + {DC_X_WIN_XD_COLOR_DEPTH, 0xD}, //T_A8B8G8R8 + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_X_WIN_XD_POSITION, 0}, //(0,0) + {DC_X_WIN_XD_H_INITIAL_DDA, 0}, + {DC_X_WIN_XD_V_INITIAL_DDA, 0}, + {DC_X_WIN_XD_PRESCALED_SIZE, 0x5000B40}, //Pre-scaled size: 1280x2880 bytes (= 0x500 vertical lines x 0xB40 bytes). + {DC_X_WIN_XD_DDA_INCREMENT, 0x10001000}, + {DC_X_WIN_XD_SIZE, 0x50002D0}, //Window size: 1280x720 (= 0x500 vertical lines x 0x2D0 horizontal pixels). + {DC_X_WIN_XD_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {0x702, 0}, + {DC_X_WINBUF_XD_SURFACE_KIND, 0}, //Regular surface. + {DC_X_WINBUF_XD_START_ADDR, 0xC0000000}, //Framebuffer address. + {DC_X_WINBUF_XD_ADDR_H_OFFSET, 0}, + {DC_X_WINBUF_XD_ADDR_V_OFFSET, 0}, + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE + {DC_X_WIN_XD_WIN_OPTIONS, 0}, + {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE + {DC_X_WIN_XD_WIN_OPTIONS, 0x40000000}, //Enable window AD. + {DC_CMD_DISPLAY_COMMAND, 0x20}, //DISPLAY_CTRL_MODE: continuous display. + {DC_CMD_STATE_CONTROL, 0x300}, //General update; window A update. + {DC_CMD_STATE_CONTROL, 3} //General activation request; window A activation request. +}; diff --git a/fusee/src/hwinit/emc.h b/fusee/src/hwinit/emc.h new file mode 100644 index 000000000..ce134c2fe --- /dev/null +++ b/fusee/src/hwinit/emc.h @@ -0,0 +1,665 @@ +/* +* arch/arm/mach-tegra/tegra21_emc.h +* +* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +*/ + +#ifndef _EMC_H_ +#define _EMC_H_ + +#define EMC_CONFIG_SAMPLE_DELAY 0x5f0 +#define EMC_CFG_UPDATE 0x5f4 +#define EMC_ADR_CFG 0x10 +#define EMC_REFCTRL 0x20 +#define EMC_PIN 0x24 +#define EMC_TIMING_CONTROL 0x28 +#define EMC_RC 0x2c +#define EMC_RFC 0x30 +#define EMC_RFCPB 0x590 +#define EMC_RAS 0x34 +#define EMC_RP 0x38 +#define EMC_R2W 0x3c +#define EMC_W2R 0x40 +#define EMC_R2P 0x44 +#define EMC_W2P 0x48 +#define EMC_CCDMW 0x5c0 +#define EMC_RD_RCD 0x4c +#define EMC_WR_RCD 0x50 +#define EMC_RRD 0x54 +#define EMC_REXT 0x58 +#define EMC_WDV 0x5c +#define EMC_QUSE 0x60 +#define EMC_QRST 0x64 +#define EMC_ISSUE_QRST 0x428 +#define EMC_QSAFE 0x68 +#define EMC_RDV 0x6c +#define EMC_REFRESH 0x70 +#define EMC_BURST_REFRESH_NUM 0x74 +#define EMC_PDEX2WR 0x78 +#define EMC_PDEX2RD 0x7c +#define EMC_PDEX2CKE 0x118 +#define EMC_PCHG2PDEN 0x80 +#define EMC_ACT2PDEN 0x84 +#define EMC_AR2PDEN 0x88 +#define EMC_RW2PDEN 0x8c +#define EMC_CKE2PDEN 0x11c +#define EMC_TXSR 0x90 +#define EMC_TCKE 0x94 +#define EMC_TFAW 0x98 +#define EMC_TRPAB 0x9c +#define EMC_TCLKSTABLE 0xa0 +#define EMC_TCLKSTOP 0xa4 +#define EMC_TREFBW 0xa8 +#define EMC_TPPD 0xac +#define EMC_PDEX2MRR 0xb4 +#define EMC_ODT_WRITE 0xb0 +#define EMC_WEXT 0xb8 +#define EMC_RFC_SLR 0xc0 +#define EMC_MRS_WAIT_CNT2 0xc4 +#define EMC_MRS_WAIT_CNT 0xc8 +#define EMC_MRS 0xcc +#define EMC_EMRS 0xd0 +#define EMC_REF 0xd4 +#define EMC_PRE 0xd8 +#define EMC_NOP 0xdc +#define EMC_SELF_REF 0xe0 +#define EMC_DPD 0xe4 +#define EMC_MRW 0xe8 +#define EMC_MRR 0xec +#define EMC_CMDQ 0xf0 +#define EMC_MC2EMCQ 0xf4 +#define EMC_FBIO_SPARE 0x100 +#define EMC_FBIO_CFG5 0x104 +#define EMC_CFG_RSV 0x120 +#define EMC_ACPD_CONTROL 0x124 +#define EMC_MPC 0x128 +#define EMC_EMRS2 0x12c +#define EMC_EMRS3 0x130 +#define EMC_MRW2 0x134 +#define EMC_MRW3 0x138 +#define EMC_MRW4 0x13c +#define EMC_MRW5 0x4a0 +#define EMC_MRW6 0x4a4 +#define EMC_MRW7 0x4a8 +#define EMC_MRW8 0x4ac +#define EMC_MRW9 0x4b0 +#define EMC_MRW10 0x4b4 +#define EMC_MRW11 0x4b8 +#define EMC_MRW12 0x4bc +#define EMC_MRW13 0x4c0 +#define EMC_MRW14 0x4c4 +#define EMC_MRW15 0x4d0 +#define EMC_CFG_SYNC 0x4d4 +#define EMC_CLKEN_OVERRIDE 0x140 +#define EMC_R2R 0x144 +#define EMC_W2W 0x148 +#define EMC_EINPUT 0x14c +#define EMC_EINPUT_DURATION 0x150 +#define EMC_PUTERM_EXTRA 0x154 +#define EMC_TCKESR 0x158 +#define EMC_TPD 0x15c +#define EMC_STAT_CONTROL 0x160 +#define EMC_STAT_STATUS 0x164 +#define EMC_STAT_DRAM_CLOCK_LIMIT_LO 0x19c +#define EMC_STAT_DRAM_CLOCK_LIMIT_HI 0x1a0 +#define EMC_STAT_DRAM_CLOCKS_LO 0x1a4 +#define EMC_STAT_DRAM_CLOCKS_HI 0x1a8 +#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO 0x1ac +#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI 0x1b0 +#define EMC_STAT_DRAM_DEV0_READ_CNT_LO 0x1b4 +#define EMC_STAT_DRAM_DEV0_READ_CNT_HI 0x1b8 +#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO 0x1bc +#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI 0x1c0 +#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO 0x1c4 +#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI 0x1c8 +#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO 0x1cc +#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI 0x1d0 +#define EMC_STAT_DRAM_DEV0_REF_CNT_LO 0x1d4 +#define EMC_STAT_DRAM_DEV0_REF_CNT_HI 0x1d8 +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1dc +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e0 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1e4 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e8 +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1ec +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f0 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1f4 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f8 +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x1fc +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x200 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x204 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x208 +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x20c +#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x210 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x214 +#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x218 +#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO 0x21c +#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI 0x220 +#define EMC_STAT_DRAM_DEV0_DSR 0x224 +#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO 0x228 +#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI 0x22c +#define EMC_STAT_DRAM_DEV1_READ_CNT_LO 0x230 +#define EMC_STAT_DRAM_DEV1_READ_CNT_HI 0x234 +#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO 0x238 +#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI 0x23c +#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO 0x240 +#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI 0x244 +#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO 0x248 +#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI 0x24c +#define EMC_STAT_DRAM_DEV1_REF_CNT_LO 0x250 +#define EMC_STAT_DRAM_DEV1_REF_CNT_HI 0x254 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x258 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x25c +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x260 +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x264 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x268 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x26c +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x270 +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x274 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x278 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x27c +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x280 +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x284 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x288 +#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x28c +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x290 +#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x294 +#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO 0x298 +#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI 0x29c +#define EMC_STAT_DRAM_DEV1_DSR 0x2a0 +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc8c +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc90 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc94 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc98 +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xc9c +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca0 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xca4 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca8 +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcac +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb0 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcb4 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb8 +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcbc +#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc0 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcc4 +#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc8 +#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO 0xccc +#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0 +#define EMC_STAT_DRAM_IO_DSR 0xcd4 +#define EMC_AUTO_CAL_CONFIG 0x2a4 +#define EMC_AUTO_CAL_CONFIG2 0x458 +#define EMC_AUTO_CAL_CONFIG3 0x45c +#define EMC_AUTO_CAL_CONFIG4 0x5b0 +#define EMC_AUTO_CAL_CONFIG5 0x5b4 +#define EMC_AUTO_CAL_CONFIG6 0x5cc +#define EMC_AUTO_CAL_CONFIG7 0x574 +#define EMC_AUTO_CAL_CONFIG8 0x2dc +#define EMC_AUTO_CAL_VREF_SEL_0 0x2f8 +#define EMC_AUTO_CAL_VREF_SEL_1 0x300 +#define EMC_AUTO_CAL_INTERVAL 0x2a8 +#define EMC_AUTO_CAL_STATUS 0x2ac +#define EMC_AUTO_CAL_STATUS2 0x3d4 +#define EMC_AUTO_CAL_CHANNEL 0x464 +#define EMC_PMACRO_RX_TERM 0xc48 +#define EMC_PMACRO_DQ_TX_DRV 0xc70 +#define EMC_PMACRO_CA_TX_DRV 0xc74 +#define EMC_PMACRO_CMD_TX_DRV 0xc4c +#define EMC_PMACRO_AUTOCAL_CFG_0 0x700 +#define EMC_PMACRO_AUTOCAL_CFG_1 0x704 +#define EMC_PMACRO_AUTOCAL_CFG_2 0x708 +#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78 +#define EMC_PMACRO_ZCTRL 0xc44 +#define EMC_XM2COMPPADCTRL 0x30c +#define EMC_XM2COMPPADCTRL2 0x578 +#define EMC_XM2COMPPADCTRL3 0x2f4 +#define EMC_COMP_PAD_SW_CTRL 0x57c +#define EMC_REQ_CTRL 0x2b0 +#define EMC_EMC_STATUS 0x2b4 +#define EMC_CFG_2 0x2b8 +#define EMC_CFG_DIG_DLL 0x2bc +#define EMC_CFG_DIG_DLL_PERIOD 0x2c0 +#define EMC_DIG_DLL_STATUS 0x2c4 +#define EMC_CFG_DIG_DLL_1 0x2c8 +#define EMC_RDV_MASK 0x2cc +#define EMC_WDV_MASK 0x2d0 +#define EMC_RDV_EARLY_MASK 0x2d4 +#define EMC_RDV_EARLY 0x2d8 +#define EMC_WDV_CHK 0x4e0 +#define EMC_ZCAL_INTERVAL 0x2e0 +#define EMC_ZCAL_WAIT_CNT 0x2e4 +#define EMC_ZCAL_MRW_CMD 0x2e8 +#define EMC_ZQ_CAL 0x2ec +#define EMC_SCRATCH0 0x324 +#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8 +#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc +#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0 +#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8 +#define EMC_SEL_DPD_CTRL 0x3d8 +#define EMC_FDPD_CTRL_DQ 0x310 +#define EMC_FDPD_CTRL_CMD 0x314 +#define EMC_PRE_REFRESH_REQ_CNT 0x3dc +#define EMC_REFCTRL2 0x580 +#define EMC_FBIO_CFG7 0x584 +#define EMC_DATA_BRLSHFT_0 0x588 +#define EMC_DATA_BRLSHFT_1 0x58c +#define EMC_DQS_BRLSHFT_0 0x594 +#define EMC_DQS_BRLSHFT_1 0x598 +#define EMC_CMD_BRLSHFT_0 0x59c +#define EMC_CMD_BRLSHFT_1 0x5a0 +#define EMC_CMD_BRLSHFT_2 0x5a4 +#define EMC_CMD_BRLSHFT_3 0x5a8 +#define EMC_QUSE_BRLSHFT_0 0x5ac +#define EMC_QUSE_BRLSHFT_1 0x5b8 +#define EMC_QUSE_BRLSHFT_2 0x5bc +#define EMC_QUSE_BRLSHFT_3 0x5c4 +#define EMC_FBIO_CFG8 0x5c8 +#define EMC_CMD_MAPPING_CMD0_0 0x380 +#define EMC_CMD_MAPPING_CMD0_1 0x384 +#define EMC_CMD_MAPPING_CMD0_2 0x388 +#define EMC_CMD_MAPPING_CMD1_0 0x38c +#define EMC_CMD_MAPPING_CMD1_1 0x390 +#define EMC_CMD_MAPPING_CMD1_2 0x394 +#define EMC_CMD_MAPPING_CMD2_0 0x398 +#define EMC_CMD_MAPPING_CMD2_1 0x39c +#define EMC_CMD_MAPPING_CMD2_2 0x3a0 +#define EMC_CMD_MAPPING_CMD3_0 0x3a4 +#define EMC_CMD_MAPPING_CMD3_1 0x3a8 +#define EMC_CMD_MAPPING_CMD3_2 0x3ac +#define EMC_CMD_MAPPING_BYTE 0x3b0 +#define EMC_DYN_SELF_REF_CONTROL 0x3e0 +#define EMC_TXSRDLL 0x3e4 +#define EMC_CCFIFO_ADDR 0x3e8 +#define EMC_CCFIFO_DATA 0x3ec +#define EMC_CCFIFO_STATUS 0x3f0 +#define EMC_SWIZZLE_RANK0_BYTE0 0x404 +#define EMC_SWIZZLE_RANK0_BYTE1 0x408 +#define EMC_SWIZZLE_RANK0_BYTE2 0x40c +#define EMC_SWIZZLE_RANK0_BYTE3 0x410 +#define EMC_SWIZZLE_RANK1_BYTE0 0x418 +#define EMC_SWIZZLE_RANK1_BYTE1 0x41c +#define EMC_SWIZZLE_RANK1_BYTE2 0x420 +#define EMC_SWIZZLE_RANK1_BYTE3 0x424 +#define EMC_TR_TIMING_0 0x3b4 +#define EMC_TR_CTRL_0 0x3b8 +#define EMC_TR_CTRL_1 0x3bc +#define EMC_TR_DVFS 0x460 +#define EMC_SWITCH_BACK_CTRL 0x3c0 +#define EMC_TR_RDV 0x3c4 +#define EMC_TR_QPOP 0x3f4 +#define EMC_TR_RDV_MASK 0x3f8 +#define EMC_TR_QSAFE 0x3fc +#define EMC_TR_QRST 0x400 +#define EMC_IBDLY 0x468 +#define EMC_OBDLY 0x46c +#define EMC_TXDSRVTTGEN 0x480 +#define EMC_WE_DURATION 0x48c +#define EMC_WS_DURATION 0x490 +#define EMC_WEV 0x494 +#define EMC_WSV 0x498 +#define EMC_CFG_3 0x49c +#define EMC_CFG_PIPE_2 0x554 +#define EMC_CFG_PIPE_CLK 0x558 +#define EMC_CFG_PIPE_1 0x55c +#define EMC_CFG_PIPE 0x560 +#define EMC_QPOP 0x564 +#define EMC_QUSE_WIDTH 0x568 +#define EMC_PUTERM_WIDTH 0x56c +#define EMC_PROTOBIST_CONFIG_ADR_1 0x5d0 +#define EMC_PROTOBIST_CONFIG_ADR_2 0x5d4 +#define EMC_PROTOBIST_MISC 0x5d8 +#define EMC_PROTOBIST_WDATA_LOWER 0x5dc +#define EMC_PROTOBIST_WDATA_UPPER 0x5e0 +#define EMC_PROTOBIST_RDATA 0x5ec +#define EMC_DLL_CFG_0 0x5e4 +#define EMC_DLL_CFG_1 0x5e8 +#define EMC_TRAINING_CMD 0xe00 +#define EMC_TRAINING_CTRL 0xe04 +#define EMC_TRAINING_STATUS 0xe08 +#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c +#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10 +#define EMC_TRAINING_QUSE_CTRL_MISC 0xe14 +#define EMC_TRAINING_WRITE_FINE_CTRL 0xe18 +#define EMC_TRAINING_WRITE_CTRL_MISC 0xe1c +#define EMC_TRAINING_WRITE_VREF_CTRL 0xe20 +#define EMC_TRAINING_READ_FINE_CTRL 0xe24 +#define EMC_TRAINING_READ_CTRL_MISC 0xe28 +#define EMC_TRAINING_READ_VREF_CTRL 0xe2c +#define EMC_TRAINING_CA_FINE_CTRL 0xe30 +#define EMC_TRAINING_CA_CTRL_MISC 0xe34 +#define EMC_TRAINING_CA_CTRL_MISC1 0xe38 +#define EMC_TRAINING_CA_VREF_CTRL 0xe3c +#define EMC_TRAINING_CA_TADR_CTRL 0xe40 +#define EMC_TRAINING_SETTLE 0xe44 +#define EMC_TRAINING_DEBUG_CTRL 0xe48 +#define EMC_TRAINING_DEBUG_DQ0 0xe4c +#define EMC_TRAINING_DEBUG_DQ1 0xe50 +#define EMC_TRAINING_DEBUG_DQ2 0xe54 +#define EMC_TRAINING_DEBUG_DQ3 0xe58 +#define EMC_TRAINING_MPC 0xe5c +#define EMC_TRAINING_PATRAM_CTRL 0xe60 +#define EMC_TRAINING_PATRAM_DQ 0xe64 +#define EMC_TRAINING_PATRAM_DMI 0xe68 +#define EMC_TRAINING_VREF_SETTLE 0xe6c +#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0 0xe70 +#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1 0xe74 +#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2 0xe78 +#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3 0xe7c +#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC 0xe80 +#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0 0xe84 +#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1 0xe88 +#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2 0xe8c +#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3 0xe90 +#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC 0xe94 +#define EMC_TRAINING_RW_OFFSET_IB_BYTE0 0xe98 +#define EMC_TRAINING_RW_OFFSET_IB_BYTE1 0xe9c +#define EMC_TRAINING_RW_OFFSET_IB_BYTE2 0xea0 +#define EMC_TRAINING_RW_OFFSET_IB_BYTE3 0xea4 +#define EMC_TRAINING_RW_OFFSET_IB_MISC 0xea8 +#define EMC_TRAINING_RW_OFFSET_OB_BYTE0 0xeac +#define EMC_TRAINING_RW_OFFSET_OB_BYTE1 0xeb0 +#define EMC_TRAINING_RW_OFFSET_OB_BYTE2 0xeb4 +#define EMC_TRAINING_RW_OFFSET_OB_BYTE3 0xeb8 +#define EMC_TRAINING_RW_OFFSET_OB_MISC 0xebc +#define EMC_TRAINING_OPT_CA_VREF 0xec0 +#define EMC_TRAINING_OPT_DQ_OB_VREF 0xec4 +#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0 0xec8 +#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1 0xecc +#define EMC_TRAINING_QUSE_VREF_CTRL 0xed0 +#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4 +#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8 +#define EMC_TRAINING_DRAMC_TIMING 0xedc +#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600 +#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604 +#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608 +#define EMC_PMACRO_QUSE_DDLL_RANK0_3 0x60c +#define EMC_PMACRO_QUSE_DDLL_RANK0_4 0x610 +#define EMC_PMACRO_QUSE_DDLL_RANK0_5 0x614 +#define EMC_PMACRO_QUSE_DDLL_RANK1_0 0x620 +#define EMC_PMACRO_QUSE_DDLL_RANK1_1 0x624 +#define EMC_PMACRO_QUSE_DDLL_RANK1_2 0x628 +#define EMC_PMACRO_QUSE_DDLL_RANK1_3 0x62c +#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630 +#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670 +#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 0x684 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 0x688 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 0x68c +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 0x690 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 0x694 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 0x6a0 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 0x6a4 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 0x6a8 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 0x6ac +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 0x6b0 +#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 0x6b4 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 0x6c0 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 0x6c4 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 0x6c8 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 0x6cc +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4 0x6d0 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5 0x6d4 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 0x6e0 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 0x6e4 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 0x6e8 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 0x6ec +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4 0x6f0 +#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5 0x6f4 +#define EMC_PMACRO_TX_PWRD_0 0x720 +#define EMC_PMACRO_TX_PWRD_1 0x724 +#define EMC_PMACRO_TX_PWRD_2 0x728 +#define EMC_PMACRO_TX_PWRD_3 0x72c +#define EMC_PMACRO_TX_PWRD_4 0x730 +#define EMC_PMACRO_TX_PWRD_5 0x734 +#define EMC_PMACRO_TX_SEL_CLK_SRC_0 0x740 +#define EMC_PMACRO_TX_SEL_CLK_SRC_1 0x744 +#define EMC_PMACRO_TX_SEL_CLK_SRC_3 0x74c +#define EMC_PMACRO_TX_SEL_CLK_SRC_2 0x748 +#define EMC_PMACRO_TX_SEL_CLK_SRC_4 0x750 +#define EMC_PMACRO_TX_SEL_CLK_SRC_5 0x754 +#define EMC_PMACRO_DDLL_BYPASS 0x760 +#define EMC_PMACRO_DDLL_PWRD_0 0x770 +#define EMC_PMACRO_DDLL_PWRD_1 0x774 +#define EMC_PMACRO_DDLL_PWRD_2 0x778 +#define EMC_PMACRO_CMD_CTRL_0 0x780 +#define EMC_PMACRO_CMD_CTRL_1 0x784 +#define EMC_PMACRO_CMD_CTRL_2 0x788 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0x800 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0x804 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0x808 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 0x80c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0x810 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0x814 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0x818 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 0x81c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0x820 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0x824 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0x828 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 0x82c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0x830 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0x834 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0x838 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 0x83c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0x840 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0x844 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0x848 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 0x84c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0x850 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0x854 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0x858 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 0x85c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0x860 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0x864 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0x868 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 0x86c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0x870 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0x874 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0x878 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 0x87c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 0x880 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 0x884 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 0x888 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 0x88c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 0x890 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 0x894 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 0x898 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 0x89c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 0x8a0 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 0x8a4 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 0x8a8 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 0x8ac +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 0x8b0 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 0x8b4 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 0x8b8 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 0x8bc +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0x900 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0x904 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0x908 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 0x90c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0x910 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0x914 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0x918 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 0x91c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0x920 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0x924 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0x928 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 0x92c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0x930 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0x934 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0x938 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 0x93c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0x940 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0x944 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0x948 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 0x94c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0x950 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0x954 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0x958 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 0x95c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0x960 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0x964 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0x968 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 0x96c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0x970 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0x974 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0x978 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 0x97c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 0x980 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 0x984 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 0x988 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 0x98c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 0x990 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 0x994 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 0x998 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 0x99c +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 0x9a0 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 0x9a4 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 0x9a8 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 0x9ac +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 0x9b0 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 0x9b4 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 0x9b8 +#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 0x9bc +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0xa00 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0xa04 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0xa08 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0xa10 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0xa14 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0xa18 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0xa20 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0xa24 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0xa28 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0xa30 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0xa34 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0xa38 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0xa40 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0xa44 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0xa48 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0xa50 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0xa54 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0xa58 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0xa60 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0xa64 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0xa68 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0xa70 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0xa74 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0xa78 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0 0xa80 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1 0xa84 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2 0xa88 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0 0xa90 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1 0xa94 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2 0xa98 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0 0xaa0 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1 0xaa4 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2 0xaa8 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0 0xab0 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1 0xab4 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2 0xab8 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0xb00 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0xb04 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0xb08 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0xb10 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0xb14 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0xb18 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0xb20 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0xb24 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0xb28 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0xb30 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0xb34 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0xb38 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0xb40 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0xb44 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0xb48 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0xb50 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0xb54 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0xb58 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0xb60 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0xb64 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0xb68 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0xb70 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0xb74 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0xb78 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0 0xb80 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1 0xb84 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2 0xb88 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0 0xb90 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1 0xb94 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2 0xb98 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0 0xba0 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1 0xba4 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2 0xba8 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0 0xbb0 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1 0xbb4 +#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2 0xbb8 +#define EMC_PMACRO_IB_VREF_DQ_0 0xbe0 +#define EMC_PMACRO_IB_VREF_DQ_1 0xbe4 +#define EMC_PMACRO_IB_VREF_DQ_2 0xbe8 +#define EMC_PMACRO_IB_VREF_DQS_0 0xbf0 +#define EMC_PMACRO_IB_VREF_DQS_1 0xbf4 +#define EMC_PMACRO_IB_VREF_DQS_2 0xbf8 +#define EMC_PMACRO_IB_RXRT 0xcf4 +#define EMC_PMACRO_DDLL_LONG_CMD_0 0xc00 +#define EMC_PMACRO_DDLL_LONG_CMD_1 0xc04 +#define EMC_PMACRO_DDLL_LONG_CMD_2 0xc08 +#define EMC_PMACRO_DDLL_LONG_CMD_3 0xc0c +#define EMC_PMACRO_DDLL_LONG_CMD_4 0xc10 +#define EMC_PMACRO_DDLL_LONG_CMD_5 0xc14 +#define EMC_PMACRO_DDLL_SHORT_CMD_0 0xc20 +#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24 +#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28 +#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30 +#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34 +#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38 +#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0 +#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c +#define EMC_PMACRO_PAD_CFG_CTRL 0xc40 +#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50 +#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54 +#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58 +#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c +#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60 +#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64 +#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68 +#define EMC_PMACRO_BRICK_MAPPING_0 0xc80 +#define EMC_PMACRO_BRICK_MAPPING_1 0xc84 +#define EMC_PMACRO_BRICK_MAPPING_2 0xc88 +#define EMC_PMACRO_DDLLCAL_CAL 0xce0 +#define EMC_PMACRO_DDLL_OFFSET 0xce4 +#define EMC_PMACRO_DDLL_PERIODIC_OFFSET 0xce8 +#define EMC_PMACRO_BRICK_CTRL_RFU1 0x330 +#define EMC_PMACRO_BRICK_CTRL_RFU2 0x334 +#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318 +#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c +#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8 +#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc +#define EMC_PMC_SCRATCH1 0x440 +#define EMC_PMC_SCRATCH2 0x444 +#define EMC_PMC_SCRATCH3 0x448 + +#endif diff --git a/fusee/src/hwinit/fuse.c b/fusee/src/hwinit/fuse.c new file mode 100644 index 000000000..8d35d6dbd --- /dev/null +++ b/fusee/src/hwinit/fuse.c @@ -0,0 +1,12 @@ +#include "fuse.h" +#include "t210.h" + +void fuse_disable_program() +{ + FUSE(FUSE_DISABLEREGPROGRAM) = 1; +} + +u32 fuse_read_odm(u32 idx) +{ + return FUSE(FUSE_RESERVED_ODMX(idx)); +} diff --git a/fusee/src/hwinit/fuse.h b/fusee/src/hwinit/fuse.h new file mode 100644 index 000000000..47e398426 --- /dev/null +++ b/fusee/src/hwinit/fuse.h @@ -0,0 +1,28 @@ +#ifndef _FUSE_H_ +#define _FUSE_H_ + +#include "types.h" + +/*! Fuse registers. */ +#define FUSE_CTRL 0x0 +#define FUSE_ADDR 0x4 +#define FUSE_RDATA 0x8 +#define FUSE_WDATA 0xC +#define FUSE_TIME_RD1 0x10 +#define FUSE_TIME_RD2 0x14 +#define FUSE_TIME_PGM1 0x18 +#define FUSE_TIME_PGM2 0x1C +#define FUSE_PRIV2INTFC 0x20 +#define FUSE_FUSEBYPASS 0x24 +#define FUSE_PRIVATEKEYDISABLE 0x28 +#define FUSE_DISABLEREGPROGRAM 0x2C +#define FUSE_WRITE_ACCESS_SW 0x30 +#define FUSE_PWR_GOOD_SW 0x34 + +/*! Fuse cache registers. */ +#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x)) + +void fuse_disable_program(); +u32 fuse_read_odm(u32 idx); + +#endif diff --git a/fusee/src/hwinit/hwinit.c b/fusee/src/hwinit/hwinit.c new file mode 100644 index 000000000..9e5352fd0 --- /dev/null +++ b/fusee/src/hwinit/hwinit.c @@ -0,0 +1,280 @@ +#include "clock.h" +#include "uart.h" +#include "i2c.h" +#include "sdram.h" +#include "di.h" +#include "mc.h" +#include "t210.h" +#include "pmc.h" +#include "pinmux.h" +#include "fuse.h" +#include "util.h" + +void config_oscillators() +{ + CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4; + SYSCTR0(SYSCTR0_CNTFID0) = 19200000; + TMR(0x14) = 0x45F; + CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; + PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE; + PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000; + PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000; + PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000; + CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; + PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz) + CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; + CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; + CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; +} + +void config_gpios() +{ + PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; + PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; + + PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = 0x40; + PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = 0x40; + + GPIO_2(0x8) = GPIO_2(0x8) & 0xFFFFFFFE | 1; + GPIO_1(0xC) = GPIO_1(0xC) & 0xFFFFFFFD | 2; + GPIO_2(0x0) = GPIO_2(0x0) & 0xFFFFFFBF | 0x40; + GPIO_2(0xC) = GPIO_2(0xC) & 0xFFFFFFBF | 0x40; + GPIO_2(0x18) &= 0xFFFFFFFE; + GPIO_1(0x1C) &= 0xFFFFFFFD; + GPIO_2(0x10) &= 0xFFFFFFBF; + GPIO_2(0x1C) &= 0xFFFFFFBF; + + pinmux_config_i2c(I2C_1); + pinmux_config_i2c(I2C_5); + pinmux_config_uart(UART_A); + + GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFFBF | 0x40; + GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFF7F | 0x80; + GPIO_6(0x1C) &= 0xFFFFFFBF; + GPIO_6(0x1C) &= 0xFFFFFF7F; +} + +void config_pmc_scratch() +{ + PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; + PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; + PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10; +} + +void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock) +{ + MC(0x670) = 0x90000000; + MC(0x674) = 1; + if (lock) + MC(0x678) = 1; +} + +void mc_config_carveout() +{ + *(vu32 *)0x8005FFFC = 0xC0EDBBCC; + MC(0x984) = 1; + MC(0x988) = 0; + MC(0x648) = 0; + MC(0x64C) = 0; + MC(0x650) = 1; + + //Official code disables and locks the carveout here. + //mc_config_tsec_carveout(0, 0, 1); + + MC(0x9A0) = 0; + MC(0x9A4) = 0; + MC(0x9A8) = 0; + MC(0x9AC) = 1; + MC(0xC0C) = 0; + MC(0xC10) = 0; + MC(0xC14) = 0; + MC(0xC18) = 0; + MC(0xC1C) = 0; + MC(0xC20) = 0; + MC(0xC24) = 0; + MC(0xC28) = 0; + MC(0xC2C) = 0; + MC(0xC30) = 0; + MC(0xC34) = 0; + MC(0xC38) = 0; + MC(0xC3C) = 0; + MC(0xC08) = 0x4000006; + MC(0xC5C) = 0x80020000; + MC(0xC60) = 0; + MC(0xC64) = 2; + MC(0xC68) = 0; + MC(0xC6C) = 0; + MC(0xC70) = 0x3000000; + MC(0xC74) = 0; + MC(0xC78) = 0x300; + MC(0xC7C) = 0; + MC(0xC80) = 0; + MC(0xC84) = 0; + MC(0xC88) = 0; + MC(0xC8C) = 0; + MC(0xC58) = 0x440167E; + MC(0xCAC) = 0; + MC(0xCB0) = 0; + MC(0xCB4) = 0; + MC(0xCB8) = 0; + MC(0xCBC) = 0; + MC(0xCC0) = 0x3000000; + MC(0xCC4) = 0; + MC(0xCC8) = 0x300; + MC(0xCCC) = 0; + MC(0xCD0) = 0; + MC(0xCD4) = 0; + MC(0xCD8) = 0; + MC(0xCDC) = 0; + MC(0xCA8) = 0x4401E7E; + MC(0xCFC) = 0; + MC(0xD00) = 0; + MC(0xD04) = 0; + MC(0xD08) = 0; + MC(0xD0C) = 0; + MC(0xD10) = 0; + MC(0xD14) = 0; + MC(0xD18) = 0; + MC(0xD1C) = 0; + MC(0xD20) = 0; + MC(0xD24) = 0; + MC(0xD28) = 0; + MC(0xD2C) = 0; + MC(0xCF8) = 0x8F; + MC(0xD4C) = 0; + MC(0xD50) = 0; + MC(0xD54) = 0; + MC(0xD58) = 0; + MC(0xD5C) = 0; + MC(0xD60) = 0; + MC(0xD64) = 0; + MC(0xD68) = 0; + MC(0xD6C) = 0; + MC(0xD70) = 0; + MC(0xD74) = 0; + MC(0xD78) = 0; + MC(0xD7C) = 0; + MC(0xD48) = 0x8F; +} + +void enable_clocks() +{ + CLOCK(0x410) = (CLOCK(0x410) | 0x8000) & 0xFFFFBFFF; + CLOCK(0xD0) |= 0x40800000u; + CLOCK(0x2AC) = 64; + CLOCK(0x294) = 0x40000; + CLOCK(0x304) = 0x18000000; + sleep(2); + + I2S(0x0A0) |= 0x400; + I2S(0x088) &= 0xFFFFFFFE; + I2S(0x1A0) |= 0x400; + I2S(0x188) &= 0xFFFFFFFE; + I2S(0x2A0) |= 0x400; + I2S(0x288) &= 0xFFFFFFFE; + I2S(0x3A0) |= 0x400; + I2S(0x388) &= 0xFFFFFFFE; + I2S(0x4A0) |= 0x400; + I2S(0x488) &= 0xFFFFFFFE; + DISPLAY_A(0xCF8) |= 4; + VIC(0x8C) = 0xFFFFFFFF; + sleep(2); + + CLOCK(0x2A8) = 0x40; + CLOCK(0x300) = 0x18000000; + CLOCK(0x290) = 0x40000; + CLOCK(0x14) = 0xC0; + CLOCK(0x10) = 0x80000130; + CLOCK(0x18) = 0x1F00200; + CLOCK(0x360) = 0x80400808; + CLOCK(0x364) = 0x402000FC; + CLOCK(0x280) = 0x23000780; + CLOCK(0x298) = 0x300; + CLOCK(0xF8) = 0; + CLOCK(0xFC) = 0; + CLOCK(0x3A0) = 0; + CLOCK(0x3A4) = 0; + CLOCK(0x554) = 0; + CLOCK(0xD0) &= 0x1F7FFFFFu; + CLOCK(0x410) &= 0xFFFF3FFF; + CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000; + CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000; + CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000; +} + +void mc_enable_ahb_redirect() +{ + CLOCK(0x3A4) = CLOCK(0x3A4) & 0xFFF7FFFF | 0x80000; + //MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE; + MC(MC_IRAM_BOM) = 0x40000000; + MC(MC_IRAM_TOM) = 0x4003F000; +} + +void mc_disable_ahb_redirect() +{ + MC(MC_IRAM_BOM) = 0xFFFFF000; + MC(MC_IRAM_TOM) = 0; + //Disable IRAM_CFG_WRITE_ACCESS (sticky). + //MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1; + CLOCK(0x3A4) &= 0xFFF7FFFF; +} + +void mc_enable() +{ + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000; + //Enable MIPI CAL clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF | 0x2000000; + //Enable MC clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1; + //Enable EMC DLL clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000; + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset. + sleep(5); +} + +clock_t clock_unk1 = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 }; +clock_t clock_unk2 = { 0x358, 0x360, 0, 0x1E, 0, 0 }; + +void nx_hwinit() +{ + enable_clocks(); + clock_enable_se(); + clock_enable_fuse(1); + fuse_disable_program(); + + mc_enable(); + + config_oscillators(); + _REG(0x70000000, 0x40) = 0; + + config_gpios(); + + clock_enable_i2c(I2C_1); + clock_enable_i2c(I2C_5); + clock_enable(&clock_unk1); + clock_enable(&clock_unk2); + + i2c_init(I2C_1); + i2c_init(I2C_5); + + //Config PMIC (TODO: use max77620.h) + i2c_send_byte(I2C_5, 0x3C, 4, 0x40); + i2c_send_byte(I2C_5, 0x3C, 0x41, 0x78); + i2c_send_byte(I2C_5, 0x3C, 0x43, 0x38); + i2c_send_byte(I2C_5, 0x3C, 0x44, 0x3A); + i2c_send_byte(I2C_5, 0x3C, 0x45, 0x38); + i2c_send_byte(I2C_5, 0x3C, 0x4A, 0xF); + i2c_send_byte(I2C_5, 0x3C, 0x4E, 0xC7); + i2c_send_byte(I2C_5, 0x3C, 0x4F, 0x4F); + i2c_send_byte(I2C_5, 0x3C, 0x50, 0x29); + i2c_send_byte(I2C_5, 0x3C, 0x52, 0x1B); + i2c_send_byte(I2C_5, 0x3C, 0x16, 42); //42 = (1000 * 1125 - 600000) / 12500 + + config_pmc_scratch(); + + CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333; + + mc_config_carveout(); + + sdram_init(); +} diff --git a/fusee/src/hwinit/hwinit.h b/fusee/src/hwinit/hwinit.h new file mode 100644 index 000000000..0ee196b0f --- /dev/null +++ b/fusee/src/hwinit/hwinit.h @@ -0,0 +1,9 @@ +#ifndef _HWINIT_H_ +#define _HWINIT_H_ + +void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock); +void mc_enable_ahb_redirect(); +void mc_disable_ahb_redirect(); +void nx_hwinit(); + +#endif diff --git a/fusee/src/hwinit/i2c.c b/fusee/src/hwinit/i2c.c new file mode 100644 index 000000000..b44b9ffa5 --- /dev/null +++ b/fusee/src/hwinit/i2c.c @@ -0,0 +1,116 @@ +#include + +#include "i2c.h" +#include "util.h" + +static u32 i2c_addrs[] = { 0x7000C000, 0x7000C400, 0x7000C500, 0x7000C700, 0x7000D000, 0x7000D100 }; + +static void _i2c_wait(vu32 *base) +{ + base[0x23] = 0x25; + for (u32 i = 0; i < 20; i++) + { + sleep(1); + if (!(base[0x23] & 1)) + break; + } +} + +static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size) +{ + if (size > 4) + return 0; + + u32 tmp = 0; + memcpy(&tmp, buf, size); + + vu32 *base = (vu32 *)i2c_addrs[idx]; + base[1] = x << 1; //Set x (send mode). + base[3] = tmp; //Set value. + base[0] = (2 * size - 2) | 0x2800; //Set size and send mode. + _i2c_wait(base); //Kick transaction. + + base[0] = base[0] & 0xFFFFFDFF | 0x200; + while (base[7] & 0x100) + ; + + if (base[7] << 28) + return 0; + + return 1; +} + +static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x) +{ + if (size > 4) + return 0; + + vu32 *base = (vu32 *)i2c_addrs[idx]; + base[1] = (x << 1) | 1; //Set x (recv mode). + base[0] = (2 * size - 2) | 0x2840; //Set size and recv mode. + _i2c_wait(base); //Kick transaction. + + base[0] = base[0] & 0xFFFFFDFF | 0x200; + while (base[7] & 0x100) + ; + + if (base[7] << 28) + return 0; + + u32 tmp = base[3]; //Get value. + memcpy(buf, &tmp, size); + + return 1; +} + +void i2c_init(u32 idx) +{ + vu32 *base = (vu32 *)i2c_addrs[idx]; + + base[0x1B] = 0x50001; + base[0x21] = 0x90003; + _i2c_wait(base); + + for (u32 i = 0; i < 10; i++) + { + sleep(20000); + if (base[0x1A] & 0x800) + break; + } + + vu32 dummy = base[0x22]; + base[0x1A] = base[0x1A]; +} + +int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size) +{ + u8 tmp[4]; + + if (size > 3) + return 0; + + tmp[0] = y; + memcpy(tmp + 1, buf, size); + + return _i2c_send_pkt(idx, x, tmp, size + 1); +} + +int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y) +{ + int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1); + if (res) + res = _i2c_recv_pkt(idx, buf, size, x); + return res; +} + +void i2c_send_byte(u32 idx, u32 x, u32 y, u8 b) +{ + i2c_send_buf_small(idx, x, y, &b, 1); +} + +u8 i2c_recv_byte(u32 idx, u32 x, u32 y) +{ + u8 tmp; + i2c_recv_buf_small(&tmp, 1, idx, x, y); + return tmp; +} diff --git a/fusee/src/hwinit/i2c.h b/fusee/src/hwinit/i2c.h new file mode 100644 index 000000000..921533d6b --- /dev/null +++ b/fusee/src/hwinit/i2c.h @@ -0,0 +1,19 @@ +#ifndef _I2C_H_ +#define _I2C_H_ + +#include "types.h" + +#define I2C_1 0 +#define I2C_2 1 +#define I2C_3 2 +#define I2C_4 3 +#define I2C_5 4 +#define I2C_6 5 + +void i2c_init(u32 idx); +int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size); +int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y); +void i2c_send_byte(u32 idx, u32 x, u32 y, u8 b); +u8 i2c_recv_byte(u32 idx, u32 x, u32 y); + +#endif diff --git a/fusee/src/hwinit/max77620.h b/fusee/src/hwinit/max77620.h new file mode 100644 index 000000000..6e7e1e8af --- /dev/null +++ b/fusee/src/hwinit/max77620.h @@ -0,0 +1,131 @@ +/* +* Defining registers address and its bit definitions of MAX77620 and MAX20024 +* +* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +*/ + +#ifndef _MAX77620_H_ +#define _MAX77620_H_ + +/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */ +#define MAX77620_REG_CNFGGLBL1 0x00 +#define MAX77620_REG_CNFGGLBL2 0x01 +#define MAX77620_REG_CNFGGLBL3 0x02 +#define MAX77620_REG_CNFG1_32K 0x03 +#define MAX77620_REG_CNFGBBC 0x04 +#define MAX77620_REG_IRQTOP 0x05 +#define MAX77620_REG_INTLBT 0x06 +#define MAX77620_REG_IRQSD 0x07 +#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 +#define MAX77620_REG_IRQ_LVL2_L8 0x09 +#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A +#define MAX77620_REG_ONOFFIRQ 0x0B +#define MAX77620_REG_NVERC 0x0C +#define MAX77620_REG_IRQTOPM 0x0D +#define MAX77620_REG_INTENLBT 0x0E +#define MAX77620_REG_IRQMASKSD 0x0F +#define MAX77620_REG_IRQ_MSK_L0_7 0x10 +#define MAX77620_REG_IRQ_MSK_L8 0x11 +#define MAX77620_REG_ONOFFIRQM 0x12 +#define MAX77620_REG_STATLBT 0x13 +#define MAX77620_REG_STATSD 0x14 +#define MAX77620_REG_ONOFFSTAT 0x15 + +/* SD and LDO Registers */ +#define MAX77620_REG_SD0 0x16 +#define MAX77620_REG_SD1 0x17 +#define MAX77620_REG_SD2 0x18 +#define MAX77620_REG_SD3 0x19 +#define MAX77620_REG_SD4 0x1A +#define MAX77620_REG_DVSSD0 0x1B +#define MAX77620_REG_DVSSD1 0x1C +#define MAX77620_REG_SD0_CFG 0x1D +#define MAX77620_REG_SD1_CFG 0x1E +#define MAX77620_REG_SD2_CFG 0x1F +#define MAX77620_REG_SD3_CFG 0x20 +#define MAX77620_REG_SD4_CFG 0x21 +#define MAX77620_REG_SD_CFG2 0x22 +#define MAX77620_REG_LDO0_CFG 0x23 +#define MAX77620_REG_LDO0_CFG2 0x24 +#define MAX77620_REG_LDO1_CFG 0x25 +#define MAX77620_REG_LDO1_CFG2 0x26 +#define MAX77620_REG_LDO2_CFG 0x27 +#define MAX77620_REG_LDO2_CFG2 0x28 +#define MAX77620_REG_LDO3_CFG 0x29 +#define MAX77620_REG_LDO3_CFG2 0x2A +#define MAX77620_REG_LDO4_CFG 0x2B +#define MAX77620_REG_LDO4_CFG2 0x2C +#define MAX77620_REG_LDO5_CFG 0x2D +#define MAX77620_REG_LDO5_CFG2 0x2E +#define MAX77620_REG_LDO6_CFG 0x2F +#define MAX77620_REG_LDO6_CFG2 0x30 +#define MAX77620_REG_LDO7_CFG 0x31 +#define MAX77620_REG_LDO7_CFG2 0x32 +#define MAX77620_REG_LDO8_CFG 0x33 +#define MAX77620_REG_LDO8_CFG2 0x34 +#define MAX77620_REG_LDO_CFG3 0x35 + +#define MAX77620_LDO_SLEW_RATE_MASK 0x1 + +/* LDO Configuration 3 */ +#define MAX77620_TRACK4_MASK BIT(5) +#define MAX77620_TRACK4_SHIFT 5 + +/* Voltage */ +#define MAX77620_SDX_VOLT_MASK 0xFF +#define MAX77620_SD0_VOLT_MASK 0x3F +#define MAX77620_SD1_VOLT_MASK 0x7F +#define MAX77620_LDO_VOLT_MASK 0x3F + +#define MAX77620_REG_GPIO0 0x36 +#define MAX77620_REG_GPIO1 0x37 +#define MAX77620_REG_GPIO2 0x38 +#define MAX77620_REG_GPIO3 0x39 +#define MAX77620_REG_GPIO4 0x3A +#define MAX77620_REG_GPIO5 0x3B +#define MAX77620_REG_GPIO6 0x3C +#define MAX77620_REG_GPIO7 0x3D +#define MAX77620_REG_PUE_GPIO 0x3E +#define MAX77620_REG_PDE_GPIO 0x3F +#define MAX77620_REG_AME_GPIO 0x40 +#define MAX77620_REG_ONOFFCNFG1 0x41 +#define MAX77620_REG_ONOFFCNFG2 0x42 + +/* FPS Registers */ +#define MAX77620_REG_FPS_CFG0 0x43 +#define MAX77620_REG_FPS_CFG1 0x44 +#define MAX77620_REG_FPS_CFG2 0x45 +#define MAX77620_REG_FPS_LDO0 0x46 +#define MAX77620_REG_FPS_LDO1 0x47 +#define MAX77620_REG_FPS_LDO2 0x48 +#define MAX77620_REG_FPS_LDO3 0x49 +#define MAX77620_REG_FPS_LDO4 0x4A +#define MAX77620_REG_FPS_LDO5 0x4B +#define MAX77620_REG_FPS_LDO6 0x4C +#define MAX77620_REG_FPS_LDO7 0x4D +#define MAX77620_REG_FPS_LDO8 0x4E +#define MAX77620_REG_FPS_SD0 0x4F +#define MAX77620_REG_FPS_SD1 0x50 +#define MAX77620_REG_FPS_SD2 0x51 +#define MAX77620_REG_FPS_SD3 0x52 +#define MAX77620_REG_FPS_SD4 0x53 + +#define MAX77620_REG_FPS_GPIO1 0x54 +#define MAX77620_REG_FPS_GPIO2 0x55 +#define MAX77620_REG_FPS_GPIO3 0x56 +#define MAX77620_REG_FPS_RSO 0x57 +#define MAX77620_REG_CID0 0x58 +#define MAX77620_REG_CID1 0x59 +#define MAX77620_REG_CID2 0x5A +#define MAX77620_REG_CID3 0x5B +#define MAX77620_REG_CID4 0x5C +#define MAX77620_REG_CID5 0x5D + +#define MAX77620_REG_DVSSD4 0x5E +#define MAX20024_REG_MAX_ADD 0x70 + +#endif diff --git a/fusee/src/hwinit/mc.h b/fusee/src/hwinit/mc.h new file mode 100644 index 000000000..7eebdf4e0 --- /dev/null +++ b/fusee/src/hwinit/mc.h @@ -0,0 +1,466 @@ +/* +* Copyright (c) 2014, NVIDIA Corporation. All rights reserved. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef _MC_H_ +#define _MC_ + +#define MC_INTSTATUS 0x0 +#define MC_INTMASK 0x4 +#define MC_ERR_STATUS 0x8 +#define MC_ERR_ADR 0xc +#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0 +#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4 +#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8 +#define MC_PCFIFO_CLIENT_CONFIG3 0xddc +#define MC_PCFIFO_CLIENT_CONFIG4 0xde0 +#define MC_EMEM_CFG 0x50 +#define MC_EMEM_ADR_CFG 0x54 +#define MC_EMEM_ADR_CFG_DEV0 0x58 +#define MC_EMEM_ADR_CFG_DEV1 0x5c +#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60 +#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64 +#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68 +#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c +#define MC_SECURITY_CFG0 0x70 +#define MC_SECURITY_CFG1 0x74 +#define MC_SECURITY_CFG3 0x9bc +#define MC_SECURITY_RSV 0x7c +#define MC_EMEM_ARB_CFG 0x90 +#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94 +#define MC_EMEM_ARB_TIMING_RCD 0x98 +#define MC_EMEM_ARB_TIMING_RP 0x9c +#define MC_EMEM_ARB_TIMING_RC 0xa0 +#define MC_EMEM_ARB_TIMING_RAS 0xa4 +#define MC_EMEM_ARB_TIMING_FAW 0xa8 +#define MC_EMEM_ARB_TIMING_RRD 0xac +#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0 +#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4 +#define MC_EMEM_ARB_TIMING_R2R 0xb8 +#define MC_EMEM_ARB_TIMING_W2W 0xbc +#define MC_EMEM_ARB_TIMING_R2W 0xc0 +#define MC_EMEM_ARB_TIMING_W2R 0xc4 +#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0 +#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4 +#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0 +#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4 +#define MC_EMEM_ARB_DA_TURNS 0xd0 +#define MC_EMEM_ARB_DA_COVERS 0xd4 +#define MC_EMEM_ARB_MISC0 0xd8 +#define MC_EMEM_ARB_MISC1 0xdc +#define MC_EMEM_ARB_MISC2 0xc8 +#define MC_EMEM_ARB_RING1_THROTTLE 0xe0 +#define MC_EMEM_ARB_RING3_THROTTLE 0xe4 +#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0 +#define MC_EMEM_ARB_OVERRIDE 0xe8 +#define MC_EMEM_ARB_RSV 0xec +#define MC_CLKEN_OVERRIDE 0xf4 +#define MC_TIMING_CONTROL_DBG 0xf8 +#define MC_TIMING_CONTROL 0xfc +#define MC_STAT_CONTROL 0x100 +#define MC_STAT_STATUS 0x104 +#define MC_STAT_EMC_CLOCK_LIMIT 0x108 +#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c +#define MC_STAT_EMC_CLOCKS 0x110 +#define MC_STAT_EMC_CLOCKS_MSBS 0x114 +#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118 +#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158 +#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c +#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c +#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20 +#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24 +#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198 +#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8 +#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c +#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac +#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28 +#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c +#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0 +#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0 +#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120 +#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160 +#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128 +#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168 +#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c +#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c +#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130 +#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170 +#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134 +#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88 +#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174 +#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c +#define MC_STAT_EMC_SET0_COUNT 0x138 +#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c +#define MC_STAT_EMC_SET1_COUNT 0x178 +#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c +#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140 +#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144 +#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180 +#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184 +#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148 +#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c +#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188 +#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c +#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150 +#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190 +#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8 +#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc +#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8 +#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc +#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0 +#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0 +#define MC_CLIENT_HOTRESET_CTRL 0x200 +#define MC_CLIENT_HOTRESET_CTRL_1 0x970 +#define MC_CLIENT_HOTRESET_STATUS 0x204 +#define MC_CLIENT_HOTRESET_STATUS_1 0x974 +#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208 +#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c +#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210 +#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214 +#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94 +#define MC_EMEM_ARB_HYSTERESIS_0 0x218 +#define MC_EMEM_ARB_HYSTERESIS_1 0x21c +#define MC_EMEM_ARB_HYSTERESIS_2 0x220 +#define MC_EMEM_ARB_HYSTERESIS_3 0x224 +#define MC_EMEM_ARB_HYSTERESIS_4 0xb84 +#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0 +#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4 +#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8 +#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc +#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0 +#define MC_EMEM_ARB_DHYST_CTRL 0xbcc +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8 +#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec +#define MC_RESERVED_RSV 0x3fc +#define MC_DISB_EXTRA_SNAP_LEVELS 0x408 +#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4 +#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0 +#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18 +#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08 +#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10 +#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c +#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40 +#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414 +#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc +#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c +#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14 +#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0 +#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac +#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c +#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48 +#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8 +#define MC_USBX_EXTRA_SNAP_LEVELS 0x404 +#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8 +#define MC_SD_EXTRA_SNAP_LEVELS 0xa04 +#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c +#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8 +#define MC_GK_EXTRA_SNAP_LEVELS 0xa00 +#define MC_VE2_EXTRA_SNAP_LEVELS 0x410 +#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44 +#define MC_VIDEO_PROTECT_BOM 0x648 +#define MC_VIDEO_PROTECT_SIZE_MB 0x64c +#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978 +#define MC_VIDEO_PROTECT_REG_CTRL 0x650 +#define MC_ERR_VPR_STATUS 0x654 +#define MC_ERR_VPR_ADR 0x658 +#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418 +#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590 +#define MC_IRAM_BOM 0x65c +#define MC_IRAM_TOM 0x660 +#define MC_IRAM_ADR_HI 0x980 +#define MC_IRAM_REG_CTRL 0x964 +#define MC_EMEM_CFG_ACCESS_CTRL 0x664 +#define MC_TZ_SECURITY_CTRL 0x668 +#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c +#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4 +#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc +#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8 +#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80 +#define MC_SEC_CARVEOUT_BOM 0x670 +#define MC_SEC_CARVEOUT_SIZE_MB 0x674 +#define MC_SEC_CARVEOUT_ADR_HI 0x9d4 +#define MC_SEC_CARVEOUT_REG_CTRL 0x678 +#define MC_ERR_SEC_STATUS 0x67c +#define MC_ERR_SEC_ADR 0x680 +#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684 +#define MC_STUTTER_CONTROL 0x688 +#define MC_RESERVED_RSV_1 0x958 +#define MC_DVFS_PIPE_SELECT 0x95c +#define MC_AHB_PTSA_MIN 0x4e0 +#define MC_AUD_PTSA_MIN 0x54c +#define MC_MLL_MPCORER_PTSA_RATE 0x44c +#define MC_RING2_PTSA_RATE 0x440 +#define MC_USBD_PTSA_RATE 0x530 +#define MC_USBX_PTSA_MIN 0x528 +#define MC_USBD_PTSA_MIN 0x534 +#define MC_APB_PTSA_MAX 0x4f0 +#define MC_JPG_PTSA_RATE 0x584 +#define MC_DIS_PTSA_MIN 0x420 +#define MC_AVP_PTSA_MAX 0x4fc +#define MC_AVP_PTSA_RATE 0x4f4 +#define MC_RING1_PTSA_MIN 0x480 +#define MC_DIS_PTSA_MAX 0x424 +#define MC_SD_PTSA_MAX 0x4d8 +#define MC_MSE_PTSA_RATE 0x4c4 +#define MC_VICPC_PTSA_MIN 0x558 +#define MC_PCX_PTSA_MAX 0x4b4 +#define MC_ISP_PTSA_RATE 0x4a0 +#define MC_A9AVPPC_PTSA_MIN 0x48c +#define MC_RING2_PTSA_MAX 0x448 +#define MC_AUD_PTSA_RATE 0x548 +#define MC_HOST_PTSA_MIN 0x51c +#define MC_MLL_MPCORER_PTSA_MAX 0x454 +#define MC_SD_PTSA_MIN 0x4d4 +#define MC_RING1_PTSA_RATE 0x47c +#define MC_JPG_PTSA_MIN 0x588 +#define MC_HDAPC_PTSA_MIN 0x62c +#define MC_AVP_PTSA_MIN 0x4f8 +#define MC_JPG_PTSA_MAX 0x58c +#define MC_VE_PTSA_MAX 0x43c +#define MC_DFD_PTSA_MAX 0x63c +#define MC_VICPC_PTSA_RATE 0x554 +#define MC_GK_PTSA_MAX 0x544 +#define MC_VICPC_PTSA_MAX 0x55c +#define MC_SDM_PTSA_MAX 0x624 +#define MC_SAX_PTSA_RATE 0x4b8 +#define MC_PCX_PTSA_MIN 0x4b0 +#define MC_APB_PTSA_MIN 0x4ec +#define MC_GK2_PTSA_MIN 0x614 +#define MC_PCX_PTSA_RATE 0x4ac +#define MC_RING1_PTSA_MAX 0x484 +#define MC_HDAPC_PTSA_RATE 0x628 +#define MC_MLL_MPCORER_PTSA_MIN 0x450 +#define MC_GK2_PTSA_MAX 0x618 +#define MC_AUD_PTSA_MAX 0x550 +#define MC_GK2_PTSA_RATE 0x610 +#define MC_ISP_PTSA_MAX 0x4a8 +#define MC_DISB_PTSA_RATE 0x428 +#define MC_VE2_PTSA_MAX 0x49c +#define MC_DFD_PTSA_MIN 0x638 +#define MC_FTOP_PTSA_RATE 0x50c +#define MC_A9AVPPC_PTSA_RATE 0x488 +#define MC_VE2_PTSA_MIN 0x498 +#define MC_USBX_PTSA_MAX 0x52c +#define MC_DIS_PTSA_RATE 0x41c +#define MC_USBD_PTSA_MAX 0x538 +#define MC_A9AVPPC_PTSA_MAX 0x490 +#define MC_USBX_PTSA_RATE 0x524 +#define MC_FTOP_PTSA_MAX 0x514 +#define MC_HDAPC_PTSA_MAX 0x630 +#define MC_SD_PTSA_RATE 0x4d0 +#define MC_DFD_PTSA_RATE 0x634 +#define MC_FTOP_PTSA_MIN 0x510 +#define MC_SDM_PTSA_RATE 0x61c +#define MC_AHB_PTSA_RATE 0x4dc +#define MC_SMMU_SMMU_PTSA_MAX 0x460 +#define MC_RING2_PTSA_MIN 0x444 +#define MC_SDM_PTSA_MIN 0x620 +#define MC_APB_PTSA_RATE 0x4e8 +#define MC_MSE_PTSA_MIN 0x4c8 +#define MC_HOST_PTSA_RATE 0x518 +#define MC_VE_PTSA_RATE 0x434 +#define MC_AHB_PTSA_MAX 0x4e4 +#define MC_SAX_PTSA_MIN 0x4bc +#define MC_SMMU_SMMU_PTSA_MIN 0x45c +#define MC_ISP_PTSA_MIN 0x4a4 +#define MC_HOST_PTSA_MAX 0x520 +#define MC_SAX_PTSA_MAX 0x4c0 +#define MC_VE_PTSA_MIN 0x438 +#define MC_GK_PTSA_MIN 0x540 +#define MC_MSE_PTSA_MAX 0x4cc +#define MC_DISB_PTSA_MAX 0x430 +#define MC_DISB_PTSA_MIN 0x42c +#define MC_SMMU_SMMU_PTSA_RATE 0x458 +#define MC_VE2_PTSA_RATE 0x494 +#define MC_GK_PTSA_RATE 0x53c +#define MC_PTSA_GRANT_DECREMENT 0x960 +#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4 +#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0 +#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380 +#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384 +#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc +#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8 +#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370 +#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0 +#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374 +#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8 +#define MC_LATENCY_ALLOWANCE_VIC_0 0x394 +#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8 +#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8 +#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc +#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390 +#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0 +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694 +#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348 +#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c +#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344 +#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0 +#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0 +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698 +#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec +#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0 +#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4 +#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8 +#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4 +#define MC_LATENCY_ALLOWANCE_HC_1 0x314 +#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0 +#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4 +#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c +#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec +#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320 +#define MC_LATENCY_ALLOWANCE_VI2_0 0x398 +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4 +#define MC_LATENCY_ALLOWANCE_SATA_0 0x350 +#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690 +#define MC_LATENCY_ALLOWANCE_HC_0 0x310 +#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8 +#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac +#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4 +#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388 +#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328 +#define MC_LATENCY_ALLOWANCE_HDA_0 0x318 +#define MC_MIN_LENGTH_APE_0 0xb34 +#define MC_MIN_LENGTH_DCB_2 0x8a8 +#define MC_MIN_LENGTH_A9AVP_0 0x950 +#define MC_MIN_LENGTH_TSEC_0 0x93c +#define MC_MIN_LENGTH_DC_1 0x898 +#define MC_MIN_LENGTH_AXIAP_0 0x94c +#define MC_MIN_LENGTH_ISP2B_0 0x930 +#define MC_MIN_LENGTH_VI2_0 0x944 +#define MC_MIN_LENGTH_DCB_0 0x8a0 +#define MC_MIN_LENGTH_DCB_1 0x8a4 +#define MC_MIN_LENGTH_PPCS_1 0x8f4 +#define MC_MIN_LENGTH_NVJPG_0 0xb3c +#define MC_MIN_LENGTH_HDA_0 0x8c4 +#define MC_MIN_LENGTH_NVENC_0 0x8d4 +#define MC_MIN_LENGTH_SDMMC_0 0xb18 +#define MC_MIN_LENGTH_ISP2B_1 0x934 +#define MC_MIN_LENGTH_HC_1 0x8c0 +#define MC_MIN_LENGTH_DC_3 0xb20 +#define MC_MIN_LENGTH_AVPC_0 0x890 +#define MC_MIN_LENGTH_VIC_0 0x940 +#define MC_MIN_LENGTH_ISP2_0 0x91c +#define MC_MIN_LENGTH_HC_0 0x8bc +#define MC_MIN_LENGTH_SE_0 0xb38 +#define MC_MIN_LENGTH_NVDEC_0 0xb30 +#define MC_MIN_LENGTH_SATA_0 0x8fc +#define MC_MIN_LENGTH_DC_0 0x894 +#define MC_MIN_LENGTH_XUSB_1 0x92c +#define MC_MIN_LENGTH_DC_2 0x89c +#define MC_MIN_LENGTH_SDMMCAA_0 0xb14 +#define MC_MIN_LENGTH_GPU_0 0xb04 +#define MC_MIN_LENGTH_ETR_0 0xb44 +#define MC_MIN_LENGTH_AFI_0 0x88c +#define MC_MIN_LENGTH_PPCS_0 0x8f0 +#define MC_MIN_LENGTH_ISP2_1 0x920 +#define MC_MIN_LENGTH_XUSB_0 0x928 +#define MC_MIN_LENGTH_MPCORE_0 0x8cc +#define MC_MIN_LENGTH_TSECB_0 0xb48 +#define MC_MIN_LENGTH_SDMMCA_0 0xb10 +#define MC_MIN_LENGTH_GPU2_0 0xb40 +#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c +#define MC_MIN_LENGTH_PTC_0 0x8f8 +#define MC_EMEM_ARB_OVERRIDE_1 0x968 +#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984 +#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988 +#define MC_EMEM_ARB_STATS_0 0x990 +#define MC_EMEM_ARB_STATS_1 0x994 +#define MC_MTS_CARVEOUT_BOM 0x9a0 +#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4 +#define MC_MTS_CARVEOUT_ADR_HI 0x9a8 +#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac +#define MC_ERR_MTS_STATUS 0x9b0 +#define MC_ERR_MTS_ADR 0x9b4 +#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00 +#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04 +#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74 +#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8 +#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10 +#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04 +#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28 +#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30 +#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c +#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c +#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70 +#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c +#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c +#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4 +#define MC_SECURITY_CARVEOUT2_CFG0 0xc58 +#define MC_SECURITY_CARVEOUT1_CFG0 0xc08 +#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84 +#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68 +#define MC_SECURITY_CARVEOUT3_BOM 0xcac +#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70 +#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78 +#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c +#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18 +#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc +#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38 +#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34 +#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0 +#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60 +#define MC_SECURITY_CARVEOUT3_CFG0 0xca8 +#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8 +#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88 +#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64 +#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50 +#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14 +#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14 +#define MC_SECURITY_CARVEOUT1_BOM 0xc0c +#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c +#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68 +#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8 +#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58 +#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24 +#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4 +#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78 +#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c +#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18 +#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28 +#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c +#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0 +#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8 +#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60 +#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00 +#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64 +#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc +#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80 +#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54 +#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20 +#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4 +#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c +#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74 +#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc +#define MC_SECURITY_CARVEOUT4_BOM 0xcfc +#define MC_SECURITY_CARVEOUT5_CFG0 0xd48 +#define MC_SECURITY_CARVEOUT2_BOM 0xc5c +#define MC_SECURITY_CARVEOUT5_BOM 0xd4c +#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24 +#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c +#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0 +#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10 +#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20 +#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c +#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c +#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08 +#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0 +#define MC_DA_CONFIG0 0x9dc + +#endif diff --git a/fusee/src/hwinit/pinmux.c b/fusee/src/hwinit/pinmux.c new file mode 100644 index 000000000..d99155603 --- /dev/null +++ b/fusee/src/hwinit/pinmux.c @@ -0,0 +1,16 @@ +#include "pinmux.h" +#include "t210.h" + +void pinmux_config_uart(u32 idx) +{ + PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = 0; + PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0x48; + PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0; + PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = 0x44; +} + +void pinmux_config_i2c(u32 idx) +{ + PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = 0x40; + PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = 0x40; +} diff --git a/fusee/src/hwinit/pinmux.h b/fusee/src/hwinit/pinmux.h new file mode 100644 index 000000000..59bf506d8 --- /dev/null +++ b/fusee/src/hwinit/pinmux.h @@ -0,0 +1,23 @@ +#ifndef _PINMUX_H_ +#define _PINMUX_H_ + +#include "types.h" + +/*! Pinmux registers. */ +#define PINMUX_AUX_UART2_TX 0xF4 +#define PINMUX_AUX_UART3_TX 0x104 +#define PINMUX_AUX_GPIO_PE6 0x248 +#define PINMUX_AUX_GPIO_PH6 0x250 +/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */ +#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x)) +#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x)) +#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x)) +#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x)) +/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */ +#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x)) +#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x)) + +void pinmux_config_uart(u32 idx); +void pinmux_config_i2c(u32 idx); + +#endif diff --git a/fusee/src/hwinit/pmc.h b/fusee/src/hwinit/pmc.h new file mode 100644 index 000000000..4c8677239 --- /dev/null +++ b/fusee/src/hwinit/pmc.h @@ -0,0 +1,26 @@ +#ifndef _PMC_H_ +#define _PMC_H_ + +/*! PMC registers. */ +#define APBDEV_PMC_PWRGATE_TOGGLE 0x30 +#define APBDEV_PMC_PWRGATE_STATUS 0x38 +#define APBDEV_PMC_NO_IOPOWER 0x44 +#define APBDEV_PMC_SCRATCH20 0xA0 +#define APBDEV_PMC_DDR_PWR 0xE8 +#define APBDEV_PMC_CRYPTO_OP 0xF4 +#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4 +#define APBDEV_PMC_IO_DPD_REQ 0x1B8 +#define APBDEV_PMC_IO_DPD2_REQ 0x1C0 +#define APBDEV_PMC_VDDP_SEL 0x1CC +#define APBDEV_PMC_TSC_MULT 0x2B4 +#define APBDEV_PMC_REG_SHORT 0x2CC +#define APBDEV_PMC_WEAK_BIAS 0x2C8 +#define APBDEV_PMC_SECURE_SCRATCH21 0x334 +#define APBDEV_PMC_CNTRL2 0x440 +#define APBDEV_PMC_IO_DPD4_REQ 0x464 +#define APBDEV_PMC_DDR_CNTRL 0x4E4 +#define APBDEV_PMC_SCRATCH188 0x810 +#define APBDEV_PMC_SCRATCH190 0x818 +#define APBDEV_PMC_SCRATCH200 0x840 + +#endif diff --git a/fusee/src/hwinit/sdram.c b/fusee/src/hwinit/sdram.c new file mode 100644 index 000000000..e4e38af87 --- /dev/null +++ b/fusee/src/hwinit/sdram.c @@ -0,0 +1,488 @@ +#include "i2c.h" +#include "t210.h" +#include "mc.h" +//#include "emc.h" +#include "pmc.h" +#include "util.h" +#include "fuse.h" + +#include "sdram.inl" + +static u32 _get_sdram_id() +{ + return (fuse_read_odm(4) & 0x38) >> 3; +} + +static void _sdram_config(const u32 *_cfg) +{ + const u32 *_cfg_120 = _cfg + 0x120; + const u32 *_cfg_100 = _cfg + 0x100; + + PMC(0x45C) = (((4 * _cfg[0x12F] >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF; + sleep(_cfg[0x111]); + + u32 req = (4 * _cfg_120[0x10] >> 2) + 0x80000000; + PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0x3FFF0000) >> 16 << 16; + sleep(_cfg_100[0x12]); + PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF; + sleep(_cfg_100[0x12]); + PMC(APBDEV_PMC_WEAK_BIAS) = 0; + sleep(1); + + CLOCK(0x98) = _cfg[4]; + CLOCK(0x9C) = 0; + CLOCK(0x90) = (_cfg[2] << 8) | (*((u16 *)_cfg + 0xA) << 20) | _cfg[1] | 0x40000000; + + u32 wait_end = TMR(0x10) + 300; + while (!((CLOCK(0x90) >> 27) & 1)) + { + if (TMR(0x10) >= wait_end) + goto break_nosleep; + } + sleep(10); +break_nosleep: + + CLOCK(0x19C) = _cfg[0x16] & 0xFFFEFFFF | (_cfg[0x175] >> 11) & 0x10000; + if (_cfg[0x17]) + CLOCK(0x664) = _cfg[0x17]; + if (_cfg[0x1A]) + CLOCK(0x44C) = 0x40000000; + CLOCK(0x328) = 0x2000001; + CLOCK(0x284) = 0x4000; + CLOCK(0x30C) = 0x2000001; + EMC(0xC34) = _cfg_120[0x13]; + EMC(0xC38) = _cfg_120[0x14]; + EMC(0xCF0) = _cfg_120[0x15]; + EMC(0x28) = 1; + sleep(1); + EMC(0x8) = _cfg[0xA9] | 2 * _cfg[0xAA]; + if (_cfg[0xA]) + *(vu32 *)_cfg[0xA] = _cfg[0xB]; + EMC(0x584) = _cfg[0x7B]; + EMC(0x380) = _cfg[0x7D]; + EMC(0x384) = _cfg[0x7E]; + EMC(0x388) = _cfg[0x7F]; + EMC(0x38C) = _cfg[0x80]; + EMC(0x390) = _cfg[0x81]; + EMC(0x394) = _cfg[0x82]; + EMC(0x398) = _cfg[0x83]; + EMC(0x39C) = _cfg[0x84]; + EMC(0x3A0) = _cfg[0x85]; + EMC(0x3A4) = _cfg[0x86]; + EMC(0x3A8) = _cfg[0x87]; + EMC(0x3AC) = _cfg[0x88]; + EMC(0x3B0) = _cfg[0x89]; + EMC(0xC80) = _cfg[0x14A]; + EMC(0xC84) = _cfg[0x14B]; + EMC(0xC88) = _cfg[0x14C]; + EMC(0x330) = (_cfg_120[0x16] | 0xFEEDFEED) & 0x1FFF1FFF; + EMC(0x5F0) = _cfg[0x149]; + EMC(0x5C8) = _cfg[0x7C]; + EMC(0x404) = _cfg_100[0x18]; + EMC(0x408) = _cfg_100[0x19]; + EMC(0x40C) = _cfg_100[0x1A]; + EMC(0x410) = _cfg_100[0x1B]; + EMC(0x418) = _cfg_100[0x1C]; + EMC(0x41C) = _cfg_100[0x1D]; + EMC(0x420) = _cfg_100[0x1E]; + EMC(0x424) = _cfg_100[0x1F]; + if (_cfg[0xE]) + *(vu32 *)_cfg[0xE] = _cfg[0xF]; + EMC(0x30C) = _cfg[0x31]; + EMC(0x578) = _cfg[0x32]; + EMC(0x2F4) = _cfg[0x33]; + EMC(0x458) = _cfg[0x1D]; + EMC(0x45C) = _cfg[0x1E]; + EMC(0x5B0) = _cfg[0x1F]; + EMC(0x5B4) = _cfg[0x20]; + EMC(0x5CC) = _cfg[0x21]; + EMC(0x574) = _cfg[0x22]; + EMC(0x2DC) = _cfg[0x23]; + EMC(0xC48) = _cfg[0x2A]; + EMC(0xC70) = _cfg[0x2B]; + EMC(0xC74) = _cfg[0x2C]; + EMC(0xC4C) = _cfg[0x2D]; + EMC(0xC78) = _cfg[0x2E]; + EMC(0x464) = _cfg[0x26]; + EMC(0xC44) = _cfg[0x2F]; + EMC(0x5E4) = _cfg_120[0xD]; + EMC(0x5E8) = _cfg_120[0xE]; + EMC(0x2C8) = _cfg[0xB0]; + EMC(0x588) = _cfg_120[1]; + EMC(0x58C) = _cfg_120[2]; + EMC(0x594) = _cfg_120[3]; + EMC(0x598) = _cfg_120[4]; + EMC(0x59C) = _cfg_120[5]; + EMC(0x5A0) = _cfg_120[6]; + EMC(0x5A4) = _cfg_120[7]; + EMC(0x5A8) = _cfg_120[8]; + EMC(0x5AC) = _cfg_120[9]; + EMC(0x5B8) = _cfg_120[0xA]; + EMC(0x5BC) = _cfg_120[0xB]; + EMC(0x5C4) = _cfg_120[0xC]; + EMC(0x330) = (_cfg_120[0x16] | 0xFE40FE40) & 0x1FFF1FFF; + EMC(0xC40) = _cfg_120[0x12]; + EMC(0x318) = _cfg_120[0x17]; + EMC(0x334) = _cfg_120[0x18] & 0xFF7FFF7F; + EMC(0x31C) = _cfg_120[0x19]; + EMC(0xC3C) = _cfg_120[0x1A]; + EMC(0xC54) = _cfg_120[0x1B]; + EMC(0xC50) = _cfg_120[0x1C]; + EMC(0xC64) = _cfg_120[0x1F]; + EMC(0xC5C) = _cfg_120[0x1D]; + EMC(0xC58) = _cfg_120[0x1E]; + EMC(0xC60) = _cfg[0x141]; + EMC(0x49C) = _cfg[0x142]; + EMC(0x720) = _cfg[0x143]; + EMC(0x724) = _cfg[0x144]; + EMC(0x728) = _cfg[0x145]; + EMC(0x72C) = _cfg[0x146]; + EMC(0x730) = _cfg[0x147]; + EMC(0x734) = _cfg[0x148]; + EMC(0x740) = _cfg[0x14D]; + EMC(0x744) = _cfg[0x14E]; + EMC(0x748) = _cfg[0x14F]; + EMC(0x74C) = _cfg[0x150]; + EMC(0x750) = _cfg[0x151]; + EMC(0x754) = _cfg[0x152]; + EMC(0x760) = _cfg[0x153]; + EMC(0x770) = _cfg[0x154]; + EMC(0x774) = _cfg[0x155]; + EMC(0x778) = _cfg[0x156]; + EMC(0x780) = _cfg[0x157]; + EMC(0x784) = _cfg[0x158]; + EMC(0x788) = _cfg[0x159]; + EMC(0xBE0) = _cfg[0xB6]; + EMC(0xBE4) = _cfg[0xB7]; + EMC(0xBF0) = _cfg[0xB8]; + EMC(0xBF4) = _cfg[0xB9]; + EMC(0xCF4) = _cfg[0xBA]; + EMC(0x600) = _cfg[0xBD]; + EMC(0x604) = _cfg[0xBE]; + EMC(0x608) = _cfg[0xBF]; + EMC(0x60C) = _cfg[0xC0]; + EMC(0x610) = _cfg[0xC1]; + EMC(0x614) = _cfg[0xC2]; + EMC(0x620) = _cfg[0xC3]; + EMC(0x624) = _cfg[0xC4]; + EMC(0x628) = _cfg[0xC5]; + EMC(0x62C) = _cfg[0xC6]; + EMC(0x630) = _cfg[0xC7]; + EMC(0x634) = _cfg[0xC8]; + EMC(0x330) = _cfg_120[0x16]; + EMC(0x640) = _cfg[0xC9]; + EMC(0x644) = _cfg[0xCA]; + EMC(0x648) = _cfg[0xCB]; + EMC(0x64C) = _cfg[0xCC]; + EMC(0x650) = _cfg[0xCD]; + EMC(0x654) = _cfg[0xCE]; + EMC(0x660) = _cfg[0xCF]; + EMC(0x664) = _cfg[0xD0]; + EMC(0x668) = _cfg[0xD1]; + EMC(0x66C) = _cfg[0xD2]; + EMC(0x670) = _cfg[0xD3]; + EMC(0x674) = _cfg[0xD4]; + EMC(0x680) = _cfg[0xD5]; + EMC(0x684) = _cfg[0xD6]; + EMC(0x688) = _cfg[0xD7]; + EMC(0x68C) = _cfg[0xD8]; + EMC(0x690) = _cfg[0xD9]; + EMC(0x694) = _cfg[0xDA]; + EMC(0x6A0) = _cfg[0xDB]; + EMC(0x6A4) = _cfg[0xDC]; + EMC(0x6A8) = _cfg[0xDD]; + EMC(0x6AC) = _cfg[0xDE]; + EMC(0x6B0) = _cfg[0xDF]; + EMC(0x6B4) = _cfg[0xE0]; + EMC(0x6C0) = _cfg[0xE1]; + EMC(0x6C4) = _cfg[0xE2]; + EMC(0x6C8) = _cfg[0xE3]; + EMC(0x6CC) = _cfg[0xE4]; + EMC(0x6E0) = _cfg[0xE5]; + EMC(0x6E4) = _cfg[0xE6]; + EMC(0x6E8) = _cfg[0xE7]; + EMC(0x6EC) = _cfg[0xE8]; + EMC(0xC00) = _cfg[0xE9]; + EMC(0xC04) = _cfg[0xEA]; + EMC(0xC08) = _cfg[0xEB]; + EMC(0xC0C) = _cfg[0xEC]; + EMC(0xC10) = _cfg[0xED]; + EMC(0xC20) = _cfg[0xEE]; + EMC(0xC24) = _cfg[0xEF]; + EMC(0xC28) = _cfg[0xF0]; + EMC(0xC68) = (*((u8 *)_cfg + 0x500) | 0xFFFFFFFE) & 0xF; + if (_cfg[0xC]) + *(vu32 *)_cfg[0xC] = _cfg[0xD]; + EMC(0x28) = 1; + MC(0x648) = _cfg[0x180]; + MC(0x978) = _cfg[0x181]; + MC(0x64C) = _cfg[0x182]; + MC(0x418) = _cfg[0x183]; + MC(0x590) = _cfg[0x184]; + MC(0x984) = _cfg[0x185]; + MC(0x988) = _cfg[0x186]; + MC(0x54) = _cfg[0x15A]; + MC(0x58) = _cfg[0x15B]; + MC(0x5C) = _cfg[0x15C]; + MC(0x60) = _cfg[0x15D]; + MC(0x64) = _cfg[0x15E]; + MC(0x68) = _cfg[0x15F]; + MC(0x6C) = _cfg[0x160]; + MC(0x50) = _cfg[0x161]; + MC(0x670) = _cfg[0x187]; + MC(0x9D4) = _cfg[0x188]; + MC(0x674) = _cfg[0x189]; + MC(0x9A0) = _cfg[0x1D6]; + MC(0x9A8) = _cfg[0x1D7]; + MC(0x9A4) = _cfg[0x1D8]; + MC(0x90) = _cfg[0x162]; + MC(0x94) = _cfg[0x163]; + MC(0x6F0) = _cfg[0x164]; + MC(0x6F4) = _cfg[0x165]; + MC(0x98) = _cfg[0x166]; + MC(0x9C) = _cfg[0x167]; + MC(0xA0) = _cfg[0x168]; + MC(0xA4) = _cfg[0x169]; + MC(0xA8) = _cfg[0x16A]; + MC(0xAC) = _cfg[0x16B]; + MC(0xB0) = _cfg[0x16C]; + MC(0xB4) = _cfg[0x16D]; + MC(0xB8) = _cfg[0x16E]; + MC(0xBC) = _cfg[0x16F]; + MC(0x6C4) = _cfg[0x17D]; + MC(0xC0) = _cfg[0x170]; + MC(0xC4) = _cfg[0x171]; + MC(0x6C0) = _cfg[0x172]; + MC(0xD0) = _cfg[0x173]; + MC(0xD4) = _cfg[0x174]; + MC(0xD8) = _cfg[0x175]; + MC(0xDC) = _cfg[0x176]; + MC(0xC8) = _cfg[0x177]; + MC(0xE0) = _cfg[0x178]; + MC(0xE8) = _cfg[0x179]; + MC(0x968) = _cfg[0x17A]; + MC(0xEC) = _cfg[0x17B]; + MC(0x9DC) = _cfg[0x17C]; + MC(0xFC) = 1; + MC(0xF4) = _cfg[0x17E]; + MC(0x100) = _cfg[0x17F]; + EMC(0x10) = _cfg[0x34]; + EMC(0x140) = _cfg_100[7]; + EMC(0x700) = _cfg[0x27]; + EMC(0x704) = _cfg[0x28]; + EMC(0x708) = _cfg[0x29]; + EMC(0x2F8) = _cfg[0x24]; + EMC(0x300) = _cfg[0x25]; + EMC(0x2A8) = _cfg[0x1B]; + EMC(0x2A4) = _cfg[0x1C]; + sleep(_cfg[0x30]); + if (_cfg[0x10]) + *(vu32 *)_cfg[0x10] = _cfg[0x11]; + EMC(0x2B8) = _cfg[0xA4]; + EMC(0x560) = _cfg[0xA5]; + EMC(0x55C) = _cfg[0xBB]; + EMC(0x554) = _cfg[0xBC]; + EMC(0xF0) = _cfg[0xAB]; + EMC(0xF4) = _cfg[0xAC]; + EMC(0xC8) = _cfg[0xA1]; + EMC(0xC4) = _cfg[0xA2]; + EMC(0x104) = _cfg[0x7A]; + EMC(0x2C) = _cfg[0x3A]; + EMC(0x30) = _cfg[0x3B]; + EMC(0x590) = _cfg[0x3C]; + EMC(0x580) = _cfg[0x3D]; + EMC(0xC0) = _cfg[0x3E]; + EMC(0x34) = _cfg[0x3F]; + EMC(0x38) = _cfg[0x40]; + EMC(0xAC) = _cfg[0x47]; + EMC(0x144) = _cfg[0x41]; + EMC(0x148) = _cfg[0x42]; + EMC(0x3C) = _cfg[0x43]; + EMC(0x40) = _cfg[0x44]; + EMC(0x44) = _cfg[0x45]; + EMC(0x48) = _cfg[0x46]; + EMC(0x5C0) = _cfg[0x48]; + EMC(0x4C) = _cfg[0x49]; + EMC(0x50) = _cfg[0x4A]; + EMC(0x54) = _cfg[0x4B]; + EMC(0x58) = _cfg[0x4C]; + EMC(0xB8) = _cfg[0x4D]; + EMC(0x5C) = _cfg[0x4E]; + EMC(0x4E0) = _cfg[0x4F]; + EMC(0x498) = _cfg[0x50]; + EMC(0x494) = _cfg[0x51]; + EMC(0x2D0) = _cfg[0x52]; + EMC(0x490) = _cfg[0x53]; + EMC(0x48C) = _cfg[0x54]; + EMC(0x60) = _cfg[0x55]; + EMC(0x568) = _cfg[0x56]; + EMC(0x468) = _cfg[0x57]; + EMC(0x46C) = _cfg[0x58]; + EMC(0x14C) = _cfg[0x59]; + EMC(0x150) = _cfg[0x5A]; + EMC(0x154) = _cfg[0x5B]; + EMC(0x56C) = _cfg[0x5C]; + EMC(0xC68) = _cfg[0x140]; + EMC(0x8) = _cfg[0xA9]; + EMC(0x64) = _cfg[0x5D]; + EMC(0x428) = 0; + EMC(0x68) = _cfg[0x5E]; + EMC(0x6C) = _cfg[0x5F]; + EMC(0x2CC) = _cfg[0x60]; + EMC(0x2D8) = _cfg[0x61]; + EMC(0x2D4) = _cfg[0x62]; + EMC(0x564) = _cfg[0x63]; + EMC(0x70) = _cfg[0x64]; + EMC(0x74) = _cfg[0x65]; + EMC(0x3DC) = _cfg[0x66]; + EMC(0x78) = _cfg[0x67]; + EMC(0x7C) = _cfg[0x68]; + EMC(0x80) = _cfg[0x69]; + EMC(0x84) = _cfg[0x6A]; + EMC(0x88) = _cfg[0x6B]; + EMC(0x8C) = _cfg[0x6C]; + EMC(0x11C) = _cfg[0x6D]; + EMC(0x118) = _cfg[0x6E]; + EMC(0xB4) = _cfg[0x6F]; + EMC(0x90) = _cfg[0x70]; + EMC(0x3E4) = _cfg[0x71]; + EMC(0x94) = _cfg[0x72]; + EMC(0x158) = _cfg[0x73]; + EMC(0x15C) = _cfg[0x74]; + EMC(0x98) = _cfg[0x75]; + EMC(0x9C) = _cfg[0x76]; + EMC(0xA0) = _cfg[0x77]; + EMC(0xA4) = _cfg[0x78]; + EMC(0xA8) = _cfg[0x79]; + EMC(0xB0) = _cfg[0xF2]; + EMC(0x2BC) = _cfg[0xAF]; + EMC(0x2C0) = _cfg[0xB1]; + EMC(0x100) = _cfg[0x8A] & 0xFFFFFFFD; + EMC(0x120) = _cfg[0x8B]; + EMC(0x440) = _cfg_120[0xF]; + EMC(0x444) = _cfg_120[0x10]; + EMC(0x448) = _cfg_120[0x11]; + EMC(0x124) = _cfg_100[0x17]; + EMC(0x480) = *_cfg_120; + EMC(0xC) = ((_cfg[0xA3] & 4 | 0x3C00000) & 0xFFFFFFF7 | _cfg[0xA3] & 8) & 0xFFFFFFFD | _cfg[0xA3] & 2; + if ((_cfg[0x1D4] & 0x80000000) != 0) + { + *(vu32 *)(4 * _cfg[0x1D4] + 0x70000000) = _cfg[0x1D5]; + MC(0xFC) = 1; + } + PMC(0x45C) = ((4 * _cfg_120[0xF] >> 2) + 0x40000000) & 0xCFFF0000; + sleep(_cfg_100[0x11]); + if (!_cfg[0x1B]) + EMC(0x2A4) = _cfg[0x1C] | 0x200; + EMC(0x334) = _cfg_120[0x18]; + if (_cfg[0xFA] << 31) + { + if (*_cfg == 2) + EMC(0x2E4) = 8 * _cfg[0xF4]; + if (*_cfg == 3) + { + EMC(0x2E4) = _cfg[0xF4]; + EMC(0x2E8) = _cfg[0xF5]; + } + } + EMC(0x28) = 1; + sleep(_cfg[0x39]); + PMC(0x4E4) &= 0xFFF8007F; + sleep(_cfg_100[0x15]); + if (*_cfg == 2) + { + EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12); + sleep(_cfg[0x36] + 200); + EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100; + sleep(_cfg[0x36] + 500); + } + if (*_cfg == 3) + { + EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12); + sleep(_cfg[0x36] + 200); + EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100; + sleep(_cfg[0x36] + 2000); + } + EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x101; + sleep(_cfg[0x35]); + if (*_cfg != 3) + EMC(0xDC) = (_cfg[0xB2] << 30) + 1; + if (*_cfg == 1) + sleep(_cfg[0x36] + 200); + if (*_cfg == 3) + { + if (_cfg[0x12]) + *(vu32 *)_cfg[0x12] = _cfg[0x13]; + EMC(0x134) = _cfg[0x91]; + EMC(0xE8) = _cfg[0x90]; + EMC(0x138) = _cfg[0x92]; + EMC(0x13C) = _cfg[0x93]; + EMC(0x4A4) = _cfg[0x94]; + EMC(0x4C4) = _cfg[0x9A]; + EMC(0x4AC) = _cfg[0x95]; + EMC(0x4BC) = _cfg[0x98]; + EMC(0x4B0) = _cfg[0x96]; + EMC(0x4C0) = _cfg[0x99]; + if (_cfg[0xFA] << 31) + { + EMC(0x2EC) = _cfg[0xF7]; + sleep(_cfg[0xF9]); + EMC(0x2EC) = _cfg[0xF7] ^ 3; + if (!(_cfg[0xB2] & 2)) + { + EMC(0x2EC) = _cfg[0xF8]; + sleep(_cfg[0xF9]); + EMC(0x2EC) = _cfg[0xF8] ^ 3; + } + } + } + PMC(0x1D0) = _cfg_100[0xF]; + if (_cfg[0] == 1 || _cfg[0] == 2 || _cfg[0] == 3) + { + EMC(0x2E0) = _cfg[0xF3]; + EMC(0x2E4) = _cfg[0xF4]; + EMC(0x2E8) = _cfg[0xF5]; + } + if (_cfg[0x14]) + *(vu32 *)_cfg[0x14] = _cfg[0x15]; + EMC(0x28) = 1; + if (_cfg_100[8]) + EMC(0xD4) = ((1 << _cfg_100[8] << 8) - 0xFD) | (_cfg[0x38] << 30); + EMC(0x20) = _cfg[0xB2] | 0x80000000; + EMC(0x3E0) = _cfg[0xAD]; + EMC(0x5F4) = _cfg[0xA8]; + EMC(0xC) = _cfg[0xA3]; + EMC(0x310) = _cfg[0xB4]; + EMC(0x314) = _cfg[0xB5]; + EMC(0x3D8) = _cfg[0xB3]; + EMC(0x100) = _cfg[0x8A] | 2; + EMC(0x28) = 1; + EMC(0x558) = _cfg[0xA6]; + EMC(0x4D8) = _cfg[0xA7]; + SYSREG(AHB_ARBITRATION_XBAR_CTRL) = SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF | (*((u16 *)_cfg + 0x15C) << 16); + MC(0x650) = _cfg[0x18A]; + MC(0x678) = _cfg[0x18B]; + MC(0x9AC) = _cfg[0x1D9]; + MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of MC registers. +} + +void sdram_init() +{ + u32 sdram_id = _get_sdram_id(); + const u32 *cfg = _dram_cfgs[sdram_id]; //TODO: sdram_id should be in [0,4]. + + i2c_send_byte(I2C_5, 0x3C, 0x22, 0x05); + i2c_send_byte(I2C_5, 0x3C, 0x17, 40); //40 = (1000 * 1100 - 600000) / 12500 + + PMC(APBDEV_PMC_VDDP_SEL) = cfg[0x10C]; + sleep(cfg[0x10D]); + PMC(APBDEV_PMC_DDR_PWR) = PMC(0xE8); + PMC(APBDEV_PMC_NO_IOPOWER) = cfg[0x114]; + PMC(APBDEV_PMC_REG_SHORT) = cfg[0x113]; + PMC(APBDEV_PMC_DDR_CNTRL) = cfg[0x116]; + + if (cfg[8]) + *(vu32 *)cfg[8] = cfg[9]; + + _sdram_config(cfg); +} diff --git a/fusee/src/hwinit/sdram.h b/fusee/src/hwinit/sdram.h new file mode 100644 index 000000000..19db6da9b --- /dev/null +++ b/fusee/src/hwinit/sdram.h @@ -0,0 +1,6 @@ +#ifndef _SDRAM_H_ +#define _SDRAM_H_ + +void sdram_init(); + +#endif diff --git a/fusee/src/hwinit/sdram.inl b/fusee/src/hwinit/sdram.inl new file mode 100644 index 000000000..788dcc8aa --- /dev/null +++ b/fusee/src/hwinit/sdram.inl @@ -0,0 +1,812 @@ +static const u8 _dram_cfg_0[1896] = { + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, + 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, + 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, + 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, + 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, + 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, + 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, + 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, + 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, + 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C, + 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00, + 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, + 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, + 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, + 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, + 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, + 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00, + 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, + 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 _dram_cfg_1[1896] = { + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, + 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, + 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, + 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, + 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, + 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, + 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, + 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, + 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, + 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C, + 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00, + 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, + 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, + 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, + 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, + 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, + 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00, + 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, + 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 _dram_cfg_2[1896] = { + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, + 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, + 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, + 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, + 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, + 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, + 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, + 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, + 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, + 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C, + 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00, + 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, + 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, + 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, + 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, + 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, + 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00, + 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, + 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 _dram_cfg_3[1896] = { + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, + 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, + 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, + 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, + 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, + 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, + 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, + 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, + 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, + 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C, + 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00, + 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, + 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, + 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, + 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, + 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, + 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00, + 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, + 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 _dram_cfg_4[1896] = { + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, + 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, + 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, + 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, + 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, + 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, + 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, + 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, + 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, + 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, + 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C, + 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00, + 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, + 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, + 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, + 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, + 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, + 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, + 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x0C, 0x00, + 0x02, 0x03, 0x0C, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, + 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u32 *_dram_cfgs[5] = { + (const u32 *)_dram_cfg_0, + (const u32 *)_dram_cfg_1, + (const u32 *)_dram_cfg_2, + (const u32 *)_dram_cfg_3, + (const u32 *)_dram_cfg_4 +}; diff --git a/fusee/src/hwinit/t210.h b/fusee/src/hwinit/t210.h new file mode 100644 index 000000000..578d6282b --- /dev/null +++ b/fusee/src/hwinit/t210.h @@ -0,0 +1,71 @@ +#ifndef _T210_H_ +#define _T210_H_ + +#include "types.h" + +#define HOST1X_BASE 0x50000000 +#define DISPLAY_A_BASE 0x54200000 +#define DSI_BASE 0x54300000 +#define VIC_BASE 0x54340000 +#define TSEC_BASE 0x54500000 +#define SOR1_BASE 0x54580000 +#define TMR_BASE 0x60005000 +#define CLOCK_BASE 0x60006000 +#define FLOW_CTLR_BASE 0x60007000 +#define SYSREG_BASE 0x6000C000 +#define SB_BASE (SYSREG_BASE + 0x200) +#define GPIO_BASE 0x6000D000 +#define GPIO_1_BASE (GPIO_BASE) +#define GPIO_2_BASE (GPIO_BASE + 0x100) +#define GPIO_3_BASE (GPIO_BASE + 0x200) +#define GPIO_6_BASE (GPIO_BASE + 0x500) +#define EXCP_VEC_BASE 0x6000F000 +#define PINMUX_AUX_BASE 0x70003000 +#define UART_BASE 0x70006000 +#define PMC_BASE 0x7000E400 +#define SYSCTR0_BASE 0x7000F000 +#define FUSE_BASE 0x7000F800 +#define MC_BASE 0x70019000 +#define EMC_BASE 0x7001B000 +#define MIPI_CAL_BASE 0x700E3000 +#define I2S_BASE 0x702D1000 + +#define _REG(base, off) *(vu32 *)((base) + (off)) + +#define HOST1X(off) _REG(HOST1X_BASE, off) +#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off) +#define DSI(off) _REG(DSI_BASE, off) +#define VIC(off) _REG(VIC_BASE, off) +#define TSEC(off) _REG(TSEC_BASE, off) +#define SOR1(off) _REG(SOR1_BASE, off) +#define TMR(off) _REG(TMR_BASE, off) +#define CLOCK(off) _REG(CLOCK_BASE, off) +#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off) +#define SYSREG(off) _REG(SYSREG_BASE, off) +#define SB(off) _REG(SB_BASE, off) +#define GPIO_1(off) _REG(GPIO_1_BASE, off) +#define GPIO_2(off) _REG(GPIO_2_BASE, off) +#define GPIO_3(off) _REG(GPIO_3_BASE, off) +#define GPIO_6(off) _REG(GPIO_6_BASE, off) +#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off) +#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off) +#define PMC(off) _REG(PMC_BASE, off) +#define SYSCTR0(off) _REG(SYSCTR0_BASE, off) +#define FUSE(off) _REG(FUSE_BASE, off) +#define MC(off) _REG(MC_BASE, off) +#define EMC(off) _REG(EMC_BASE, off) +#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off) +#define I2S(off) _REG(I2S_BASE, off) + +/*! System registers. */ +#define AHB_ARBITRATION_XBAR_CTRL 0xE0 + +/*! Secure boot registers. */ +#define SB_CSR_0 0x0 +#define SB_AA64_RESET_LOW 0x30 +#define SB_AA64_RESET_HIGH 0x34 + +/*! SYSCTR0 registers. */ +#define SYSCTR0_CNTFID0 0x20 + +#endif diff --git a/fusee/src/hwinit/tsec.c b/fusee/src/hwinit/tsec.c new file mode 100644 index 000000000..3f3235deb --- /dev/null +++ b/fusee/src/hwinit/tsec.c @@ -0,0 +1,118 @@ +#include +#include "tsec.h" +#include "clock.h" +#include "t210.h" + +static const u8 _tsec_fw[3840] __attribute__((aligned(0x100))) = { + /* ... */ +}; + +static int _tsec_dma_wait_idle() +{ + u32 timeout = TMR(0x10) + 10000000; + + while (!(TSEC(0x1118) & 2)) + if (TMR(0x10) > timeout) + return 0; + + return 1; +} + +static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offset) +{ + u32 cmd; + + if (not_imem) + cmd = 0x600; // DMA 0x100 bytes + else + cmd = 0x10; // dma imem + + TSEC(0x1114) = i_offset; // tsec_dmatrfmoffs_r + TSEC(0x111C) = pa_offset; // tsec_dmatrffboffs_r + TSEC(0x1118) = cmd; // tsec_dmatrfcmd_r + + return _tsec_dma_wait_idle(); +} + +int tsec_query(u32 carveout, u8 *dst, u32 rev) +{ + int res = 0; + + //Enable clocks. + clock_enable_host1x(); + clock_enable_tsec(); + clock_enable_sor_safe(); + clock_enable_sor0(); + clock_enable_sor1(); + clock_enable_kfuse(); + + //Configure Falcon. + TSEC(0x110C) = 0; // tsec_dmactl_r + TSEC(0x1010) = 0xFFF2; // tsec_irqmset_r + TSEC(0x101C) = 0xFFF0; // tsec_irqdest_r + TSEC(0x1048) = 3; // tsec_itfen_r + if (!_tsec_dma_wait_idle()) + { + res = -1; + goto out; + } + + //Load firmware. + memcpy((void *)carveout, _tsec_fw, 0xF00); + TSEC(0x1110) = carveout >> 8;// tsec_dmatrfbase_r + for (u32 addr = 0; addr < 0xF00; addr += 0x100) + if (!_tsec_dma_pa_to_internal_100(0, addr, addr)) + { + res = -2; + goto out; + } + + //Execute firmware. + HOST1X(0x3300) = 0x34C2E1DA; + TSEC(0x1044) = 0; + TSEC(0x1040) = rev; + TSEC(0x1104) = 0; // tsec_bootvec_r + TSEC(0x1100) = 2; // tsec_cpuctl_r + if (!_tsec_dma_wait_idle()) + { + res = -3; + goto out; + } + u32 timeout = TMR(0x10) + 2000000; + while (!TSEC(0x1044)) + if (TMR(0x10) > timeout) + { + res = -4; + goto out; + } + if (TSEC(0x1044) != 0xB0B0B0B0) + { + res = -5; + goto out; + } + + //Fetch result. + HOST1X(0x3300) = 0; + u32 buf[4]; + buf[0] = SOR1(0x1E8); + buf[1] = SOR1(0x21C); + buf[2] = SOR1(0x208); + buf[3] = SOR1(0x20C); + SOR1(0x1E8) = 0; + SOR1(0x21C) = 0; + SOR1(0x208) = 0; + SOR1(0x20C) = 0; + memcpy(dst, &buf, 0x10); + +out:; + + //Disable clocks. + clock_disable_kfuse(); + clock_disable_sor1(); + clock_disable_sor0(); + clock_disable_sor_safe(); + clock_disable_tsec(); + clock_disable_host1x(); + + return res; +} diff --git a/fusee/src/hwinit/tsec.h b/fusee/src/hwinit/tsec.h new file mode 100644 index 000000000..03fb503d2 --- /dev/null +++ b/fusee/src/hwinit/tsec.h @@ -0,0 +1,8 @@ +#ifndef _TSEC_H_ +#define _TSEC_H_ + +#include "types.h" + +int tsec_query(u32 carveout, u8 *dst, u32 rev); + +#endif diff --git a/fusee/src/hwinit/types.h b/fusee/src/hwinit/types.h new file mode 100644 index 000000000..dff2978da --- /dev/null +++ b/fusee/src/hwinit/types.h @@ -0,0 +1,11 @@ +#ifndef _TYPES_H_ +#define _TYPES_H_ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef volatile unsigned int vu32; +typedef unsigned long long int u64; +typedef volatile unsigned long long int vu64; + +#endif diff --git a/fusee/src/hwinit/uart.c b/fusee/src/hwinit/uart.c new file mode 100644 index 000000000..b9b35aa8c --- /dev/null +++ b/fusee/src/hwinit/uart.c @@ -0,0 +1,62 @@ +#include "uart.h" +#include "t210.h" +#include "util.h" + +/* UART A, B, C, D and E. */ +static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 }; + +void uart_init(u32 idx, u32 baud) +{ + volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + //Set baud rate. + u32 rate = (8 * baud + 408000000) / (16 * baud); + uart->UART_LCR = 0x80; //Enable DLAB. + uart->UART_THR_DLAB = (u8)rate; //Divisor latch LSB. + uart->UART_IER_DLAB = (u8)(rate >> 8); //Divisor latch MSB. + uart->UART_LCR = 0; //Diable DLAB. + + //Setup UART in fifo mode. + uart->UART_IER_DLAB = 0; + uart->UART_IIR_FCR = 7; //Enable and clear TX and RX FIFOs. + volatile u32 tmp = uart->UART_LSR; + sleep(3 * ((baud + 999999) / baud)); + uart->UART_LCR = 3; //Set word length 8. + uart->UART_MCR = 0; + uart->UART_MSR = 0; + uart->UART_IRDA_CSR = 0; + uart->UART_RX_FIFO_CFG = 1; + uart->UART_MIE = 0; + uart->UART_ASR = 0; +} + +void uart_wait_idle(u32 idx, u32 which) +{ + volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + while (!(uart->UART_VENDOR_STATUS & which)) + ; +} + +void uart_send(u32 idx, u8 *buf, u32 len) +{ + volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + for (u32 i = 0; i != len; i++) + { + while (uart->UART_LSR & UART_TX_FIFO_FULL) + ; + uart->UART_THR_DLAB = buf[i]; + }; +} + +void uart_recv(u32 idx, u8 *buf, u32 len) +{ + volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + for (u32 i = 0; i != len; i++) + { + while (uart->UART_LSR & UART_RX_FIFO_EMPTY) + ; + buf[i] = uart->UART_THR_DLAB; + }; +} diff --git a/fusee/src/hwinit/uart.h b/fusee/src/hwinit/uart.h new file mode 100644 index 000000000..ac8222215 --- /dev/null +++ b/fusee/src/hwinit/uart.h @@ -0,0 +1,43 @@ +#ifndef _UART_H_ +#define _UART_H_ + +#include "types.h" + +#define UART_A 0 +#define UART_B 1 +#define UART_C 2 +//TODO: define clock inits for those. +/*#define UART_D 3 +#define UART_E 4*/ + +#define BAUD_115200 115200 + +#define UART_TX_IDLE 0x00000001 +#define UART_RX_IDLE 0x00000002 +#define UART_TX_FIFO_FULL 0x100 +#define UART_RX_FIFO_EMPTY 0x200 + +typedef struct _uart_t +{ + /* 0x00 */ u32 UART_THR_DLAB; + /* 0x04 */ u32 UART_IER_DLAB; + /* 0x08 */ u32 UART_IIR_FCR; + /* 0x0C */ u32 UART_LCR; + /* 0x10 */ u32 UART_MCR; + /* 0x14 */ u32 UART_LSR; + /* 0x18 */ u32 UART_MSR; + /* 0x1C */ u32 UART_SPR; + /* 0x20 */ u32 UART_IRDA_CSR; + /* 0x24 */ u32 UART_RX_FIFO_CFG; + /* 0x28 */ u32 UART_MIE; + /* 0x2C */ u32 UART_VENDOR_STATUS; + /* 0x30 */ u8 _pad_30[0x0C]; + /* 0x3C */ u32 UART_ASR; +} uart_t; + +void uart_init(u32 idx, u32 baud); +void uart_wait_idle(u32 idx, u32 which); +void uart_send(u32 idx, u8 *buf, u32 len); +void uart_recv(u32 idx, u8 *buf, u32 len); + +#endif diff --git a/fusee/src/hwinit/util.c b/fusee/src/hwinit/util.c new file mode 100644 index 000000000..780b31177 --- /dev/null +++ b/fusee/src/hwinit/util.c @@ -0,0 +1,16 @@ +#include "util.h" +#include "t210.h" + +void sleep(u32 ticks) +{ + u32 start = TMR(0x10); + while (TMR(0x10) - start <= ticks) + ; +} + +void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops) +{ + for(u32 i = 0; i < num_ops; i++) + base[ops[i].off] = ops[i].val; +} + diff --git a/fusee/src/hwinit/util.h b/fusee/src/hwinit/util.h new file mode 100644 index 000000000..13bc8024f --- /dev/null +++ b/fusee/src/hwinit/util.h @@ -0,0 +1,17 @@ +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include "types.h" +#pragma GCC diagnostic ignored "-Wparentheses" +#pragma GCC diagnostic ignored "-Wunused-variable" + +typedef struct _cfg_op_t +{ + u32 off; + u32 val; +} cfg_op_t; + +void sleep(u32 ticks); +void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); + +#endif diff --git a/fusee/src/main.c b/fusee/src/main.c index dcec4f144..98ea3f3b3 100644 --- a/fusee/src/main.c +++ b/fusee/src/main.c @@ -1,4 +1,7 @@ +#include "utils.h" +#include "hwinit.h" + int main(void) { - /* TODO */ + nx_hwinit(); return 0; } diff --git a/fusee/src/panic_color.h b/fusee/src/panic_color.h new file mode 100644 index 000000000..a310b139b --- /dev/null +++ b/fusee/src/panic_color.h @@ -0,0 +1,23 @@ +#ifndef EXOSPHERE_PANIC_COLOR_H +#define EXOSPHERE_PANIC_COLOR_H + +#define COLOR_0 0x00F00003 +#define COLOR_1 0x0F000003 +#define COLOR_2 0xF0000003 +#define COLOR_3 0x0FF00003 +#define COLOR_4 0xF0F00003 +#define COLOR_5 0xFF000003 +#define COLOR_6 0xFFF00003 +#define COLOR_7 0xAAF00003 +#define COLOR_8 0xAFA00003 +#define COLOR_9 0xFAA00003 +#define COLOR_A 0x33300003 +#define COLOR_B 0x06F00003 +#define COLOR_C 0x14800003 +#define COLOR_D 0x00300003 +#define COLOR_E 0x03000003 +#define COLOR_F 0xB6000003 + +#define PANIC_REBOOT 0x20 + +#endif \ No newline at end of file diff --git a/fusee/src/pmc.h b/fusee/src/pmc.h new file mode 100644 index 000000000..94d6b5ef5 --- /dev/null +++ b/fusee/src/pmc.h @@ -0,0 +1,27 @@ +#ifndef FUSEE_PMC_H +#define FUSEE_PMC_H + +#include "utils.h" + +#define PMC_BASE 0x7000E400 + +#define APBDEV_PMC_DPD_ENABLE_0 MAKE_REG32(PMC_BASE + 0x24) + +#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_REG32(PMC_BASE + 0x30) +#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_REG32(PMC_BASE + 0x38) + +#define APBDEV_PMC_SCRATCH0_0 MAKE_REG32(PMC_BASE + 0x50) + +#define APBDEV_PMC_CRYPTO_OP_0 MAKE_REG32(PMC_BASE + 0xF4) + +#define APBDEV_PM_0 MAKE_REG32(PMC_BASE + 0x14) +#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_REG32(PMC_BASE + 0x168) +#define APBDEV_PMC_CNTRL2_0 MAKE_REG32(PMC_BASE + 0x440) + +#define APBDEV_PMC_SCRATCH43_0 MAKE_REG32(PMC_BASE + 0x22C) + +#define APBDEV_PMC_SCRATCH200_0 MAKE_REG32(PMC_BASE + 0x840) + + + +#endif diff --git a/fusee/src/se.c b/fusee/src/se.c new file mode 100644 index 000000000..880a442c9 --- /dev/null +++ b/fusee/src/se.c @@ -0,0 +1,805 @@ +#include + +#include "utils.h" +/*#include "interrupt.h"*/ +#include "se.h" + +void trigger_se_rsa_op(void *buf, size_t size); +void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size); + +/* Globals for driver. */ +static unsigned int (*g_se_callback)(void); + +static unsigned int g_se_modulus_sizes[KEYSLOT_RSA_MAX]; +static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX]; + +static bool g_se_generated_vector = false; +static uint8_t g_se_stored_test_vector[0x10]; + + +/* Initialize a SE linked list. */ +void ll_init(se_ll_t *ll, void *buffer, size_t size) { + ll->num_entries = 0; /* 1 Entry. */ + + if (buffer != NULL) { + ll->addr_info.address = (uint32_t) get_physical_address(buffer); + ll->addr_info.size = (uint32_t) size; + } else { + ll->addr_info.address = 0; + ll->addr_info.size = 0; + } +} + +void set_security_engine_callback(unsigned int (*callback)(void)) { + if (callback == NULL || g_se_callback != NULL) { + generic_panic(); + } + + g_se_callback = callback; +} + +/* Fires on Security Engine operation completion. */ +void se_operation_completed(void) { + SECURITY_ENGINE->INT_ENABLE_REG = 0; + if (g_se_callback != NULL) { + g_se_callback(); + g_se_callback = NULL; + } +} + +void se_check_error_status_reg(void) { + if (SECURITY_ENGINE->ERR_STATUS_REG) { + generic_panic(); + } +} + +void se_check_for_error(void) { + if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) { + generic_panic(); + } +} + +void se_trigger_interrupt(void) { + /* TODO intr_set_pending(INTERRUPT_ID_USER_SECURITY_ENGINE); */ +} + +void se_verify_flags_cleared(void) { + if (SECURITY_ENGINE->FLAGS_REG & 3) { + generic_panic(); + } +} + + +void se_generate_test_vector(void *vector) { + /* TODO: Implement real test vector generation. */ + memset(vector, 0, 0x10); +} + +void se_validate_stored_vector(void) { + if (!g_se_generated_vector) { + generic_panic(); + } + + uint8_t ALIGN(16) calc_vector[0x10]; + se_generate_test_vector(calc_vector); + + /* Ensure nobody's messed with the security engine while we slept. */ + if (memcmp(calc_vector, g_se_stored_test_vector, 0x10) != 0) { + generic_panic(); + } +} + +void se_generate_stored_vector(void) { + if (g_se_generated_vector) { + generic_panic(); + } + + se_generate_test_vector(g_se_stored_test_vector); + g_se_generated_vector = true; +} + +/* Set the flags for an AES keyslot. */ +void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + /* Misc flags. */ + if (flags & ~0x80) { + SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + } + + /* Disable keyslot reads. */ + if (flags & 0x80) { + SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + } +} + +/* Set the flags for an RSA keyslot. */ +void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { + if (keyslot >= KEYSLOT_RSA_MAX) { + generic_panic(); + } + + /* Misc flags. */ + if (flags & ~0x80) { + /* TODO: Why are flags assigned this way? */ + SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + } + + /* Disable keyslot reads. */ + if (flags & 0x80) { + SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + } +} + +void clear_aes_keyslot(unsigned int keyslot) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + /* Zero out the whole keyslot and IV. */ + for (unsigned int i = 0; i < 0x10; i++) { + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = 0; + } +} + +void clear_rsa_keyslot(unsigned int keyslot) { + if (keyslot >= KEYSLOT_RSA_MAX) { + generic_panic(); + } + + /* Zero out the whole keyslot. */ + for (unsigned int i = 0; i < 0x40; i++) { + /* Select Keyslot Modulus[i] */ + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0; + } + for (unsigned int i = 0; i < 0x40; i++) { + /* Select Keyslot Expontent[i] */ + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0; + } +} + +void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { + if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) { + generic_panic(); + } + + for (size_t i = 0; i < (key_size >> 2); i++) { + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i); + } +} + +void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) { + if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) { + generic_panic(); + } + + for (size_t i = 0; i < (modulus_size >> 2); i++) { + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4); + } + + for (size_t i = 0; i < (exp_size >> 2); i++) { + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4); + } + + g_se_modulus_sizes[keyslot] = modulus_size; + g_se_exp_sizes[keyslot] = exp_size; +} + +void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { + if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) { + generic_panic(); + } + + for (size_t i = 0; i < (iv_size >> 2); i++) { + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + } +} + +void clear_aes_keyslot_iv(unsigned int keyslot) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + for (size_t i = 0; i < (0x10 >> 2); i++) { + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = 0; + } +} + +void set_se_ctr(const void *ctr) { + for (unsigned int i = 0; i < 4; i++) { + SECURITY_ENGINE->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + } +} + +void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) { + if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) { + generic_panic(); + } + + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); + SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + + trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); +} + +void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + if (size == 0) { + return; + } + + /* Setup Config register. */ + if (encrypt) { + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + } else { + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); + } + + /* Setup Crypto register. */ + SECURITY_ENGINE->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8); + + /* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */ + SECURITY_ENGINE->CRYPTO_REG |= 0x80000000; + + /* Appropriate number of blocks. */ + SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1; + + /* Set the callback, for after the async operation. */ + set_security_engine_callback(callback); + + /* Enable SE Interrupt firing for async op. */ + SECURITY_ENGINE->INT_ENABLE_REG = 0x10; + + /* Setup Input/Output lists */ + SECURITY_ENGINE->IN_LL_ADDR_REG = in_ll_paddr; + SECURITY_ENGINE->OUT_LL_ADDR_REG = out_ll_paddr; + + /* Set registers for operation. */ + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = 1; +} + +void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)) { + /* Unknown what this write does, but official code writes it for CTR mode. */ + SECURITY_ENGINE->_0x80C = 1; + set_se_ctr(ctr); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback); +} + +void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { + set_aes_keyslot_iv(keyslot, iv, 0x10); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, true, callback); +} + +void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { + set_aes_keyslot_iv(keyslot, iv, 0x10); + se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback); +} + + +void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) { + uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX]; + + if (keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) { + generic_panic(); + } + + /* Endian swap the input. */ + for (size_t i = 0; i < size; i++) { + stack_buf[i] = *((uint8_t *)buf + size - i - 1); + } + + + SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG); + SECURITY_ENGINE->RSA_CONFIG = keyslot << 24; + SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; + SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + + set_security_engine_callback(callback); + + /* Enable SE Interrupt firing for async op. */ + SECURITY_ENGINE->INT_ENABLE_REG = 0x10; + + trigger_se_rsa_op(stack_buf, size); + + while (!(SECURITY_ENGINE->INT_STATUS_REG & 2)) { /* Wait a while */ } +} + +void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { + uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX]; + + if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) { + generic_panic(); + } + + /* Endian swap the input. */ + for (size_t i = 0; i < src_size; i++) { + stack_buf[i] = *((uint8_t *)src + src_size - i - 1); + } + + SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG); + SECURITY_ENGINE->RSA_CONFIG = keyslot << 24; + SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; + SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + + + trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size); + se_get_exp_mod_output(dst, dst_size); +} + +void se_get_exp_mod_output(void *buf, size_t size) { + size_t num_dwords = (size >> 2); + if (num_dwords < 1) { + return; + } + + uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1; + uint32_t offset = 0; + + /* Copy endian swapped output. */ + while (num_dwords) { + *p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset); + offset += 4; + p_out--; + num_dwords--; + } +} + +bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size) { + uint8_t message[RSA_2048_BYTES]; + uint8_t h_buf[0x24]; + + /* Hardcode RSA with keyslot 0. */ + const uint8_t public_exponent[4] = {0x00, 0x01, 0x00, 0x01}; + set_rsa_keyslot(0, modulus, modulus_size, public_exponent, sizeof(public_exponent)); + se_synchronous_exp_mod(0, message, sizeof(message), signature, signature_size); + + /* Validate sanity byte. */ + if (message[RSA_2048_BYTES - 1] != 0xBC) { + return false; + } + + /* Copy Salt into MGF1 Hash Buffer. */ + memset(h_buf, 0, sizeof(h_buf)); + memcpy(h_buf, message + RSA_2048_BYTES - 0x20 - 0x1, 0x20); + + /* Decrypt maskedDB (via inline MGF1). */ + uint8_t seed = 0; + uint8_t mgf1_buf[0x20]; + for (unsigned int ofs = 0; ofs < RSA_2048_BYTES - 0x20 - 1; ofs += 0x20) { + h_buf[sizeof(h_buf) - 1] = seed++; + se_calculate_sha256(mgf1_buf, h_buf, sizeof(h_buf)); + for (unsigned int i = ofs; i < ofs + 0x20 && i < RSA_2048_BYTES - 0x20 - 1; i++) { + message[i] ^= mgf1_buf[i - ofs]; + } + } + + /* Constant lmask for rsa-2048-pss. */ + message[0] &= 0x7F; + + /* Validate DB is of the form 0000...0001. */ + for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) { + if (message[i] != 0) { + return false; + } + } + if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) { + return false; + } + + /* Check hash correctness. */ + uint8_t validate_buf[8 + 0x20 + 0x20]; + uint8_t validate_hash[0x20]; + + memset(validate_buf, 0, sizeof(validate_buf)); + se_calculate_sha256(&validate_buf[8], data, data_size); + memcpy(&validate_buf[0x28], &message[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20); + se_calculate_sha256(validate_hash, validate_buf, sizeof(validate_buf)); + return memcmp(h_buf, validate_hash, 0x20) == 0; +} + + +void trigger_se_rsa_op(void *buf, size_t size) { + se_ll_t in_ll; + ll_init(&in_ll, (void *)buf, size); + + /* Set the input LL. */ + SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); + + /* Set registers for operation. */ + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = 1; +} + +void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) { + se_ll_t in_ll; + se_ll_t out_ll; + + ll_init(&in_ll, (void *)src, src_size); + ll_init(&out_ll, dst, dst_size); + + /* Set the LLs. */ + SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll); + SECURITY_ENGINE->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll); + + /* Set registers for operation. */ + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = op; + + while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + se_check_for_error(); +} + + +/* Secure AES Functionality. */ +void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) { + uint8_t block[0x10] = {0}; + + if (src_size > sizeof(block) || dst_size > sizeof(block)) { + generic_panic(); + } + + /* Load src data into block. */ + if (src_size != 0) { + memcpy(block, src, src_size); + } + + /* Trigger AES operation. */ + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block)); + + /* Copy output data into dst. */ + if (dst_size != 0) { + memcpy(dst, block, dst_size); + } +} + +void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) { + if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) { + generic_panic(); + } + unsigned int num_blocks = src_size >> 4; + + /* Unknown what this write does, but official code writes it for CTR mode. */ + SECURITY_ENGINE->_0x80C = 1; + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E; + set_se_ctr(ctr); + + /* Handle any aligned blocks. */ + size_t aligned_size = (size_t)num_blocks << 4; + if (aligned_size) { + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1; + trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size); + } + + /* Handle final, unaligned block. */ + if (aligned_size < dst_size && aligned_size < src_size) { + size_t last_block_size = dst_size - aligned_size; + if (src_size < dst_size) { + last_block_size = src_size - aligned_size; + } + se_perform_aes_block_operation(dst + aligned_size, last_block_size, (uint8_t *)src + aligned_size, src_size - aligned_size); + } +} + +void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) { + if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { + generic_panic(); + } + + /* Set configuration high (256-bit vs 128-bit) based on parameter. */ + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + SECURITY_ENGINE->CRYPTO_REG = keyslot << 24 | 0x100; + se_perform_aes_block_operation(dst, 0x10, src, 0x10); + +} + +void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { + se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0); +} + +void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { + se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0x202); +} + + +void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { + if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { + generic_panic(); + } + + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = keyslot << 24; + se_perform_aes_block_operation(dst, 0x10, src, 0x10); +} + +void shift_left_xor_rb(uint8_t *key) { + uint8_t prev_high_bit = 0; + for (unsigned int i = 0; i < 0x10; i++) { + uint8_t cur_byte = key[0xF - i]; + key[0xF - i] = (cur_byte << 1) | (prev_high_bit); + prev_high_bit = cur_byte >> 7; + } + if (prev_high_bit) { + key[0xF] ^= 0x87; + } +} + +void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + /* Generate the derived key, to be XOR'd with final output block. */ + uint8_t ALIGN(16) derived_key[0x10] = {0}; + se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high); + shift_left_xor_rb(derived_key); + if (data_size & 0xF) { + shift_left_xor_rb(derived_key); + } + + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145); + clear_aes_keyslot_iv(keyslot); + + + unsigned int num_blocks = (data_size + 0xF) >> 4; + /* Handle aligned blocks. */ + if (num_blocks > 1) { + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 2; + trigger_se_blocking_op(OP_START, NULL, 0, data, data_size); + SECURITY_ENGINE->CRYPTO_REG |= 0x80; + } + + /* Create final block. */ + uint8_t ALIGN(16) last_block[0x10] = {0}; + if (data_size & 0xF) { + memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF); + last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */ + } else if (data_size >= 0x10) { + memcpy(last_block, data + data_size - 0x10, 0x10); + } + + for (unsigned int i = 0; i < 0x10; i++) { + last_block[i] ^= derived_key[i]; + } + + /* Perform last operation. */ + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block)); + + /* Copy output CMAC. */ + for (unsigned int i = 0; i < (cmac_size >> 2); i++) { + ((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2); + } +} + +void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) { + se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0); +} +void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) { + se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202); +} + +void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) { + if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) { + generic_panic(); + } + + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x144; + set_aes_keyslot_iv(keyslot, iv, 0x10); + SECURITY_ENGINE->BLOCK_COUNT_REG = (src_size >> 4) - 1; + trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); +} + +/* SHA256 Implementation. */ +void se_calculate_sha256(void *dst, const void *src, size_t src_size) { + /* Setup config for SHA256, size = BITS(src_size) */ + SECURITY_ENGINE->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + SECURITY_ENGINE->SHA_CONFIG_REG = 1; + SECURITY_ENGINE->SHA_MSG_LENGTH_REG = (unsigned int)(src_size << 3); + SECURITY_ENGINE->_0x20C = 0; + SECURITY_ENGINE->_0x210 = 0; + SECURITY_ENGINE->SHA_MSG_LEFT_REG = 0; + SECURITY_ENGINE->_0x218 = (unsigned int)(src_size << 3); + SECURITY_ENGINE->_0x21C = 0; + SECURITY_ENGINE->_0x220 = 0; + SECURITY_ENGINE->_0x224 = 0; + + /* Trigger the operation. */ + trigger_se_blocking_op(OP_START, NULL, 0, src, src_size); + + /* Copy output hash. */ + for (unsigned int i = 0; i < (0x20 >> 2); i++) { + ((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2); + } +} + +/* RNG API */ +void se_initialize_rng(unsigned int keyslot) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + /* To initialize the RNG, we'll perform an RNG operation into an output buffer. */ + /* This will be discarded, when done. */ + uint8_t ALIGN(16) output_buf[0x10]; + + SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ + SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001; + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 5; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0); +} + +void se_generate_random(unsigned int keyslot, void *dst, size_t size) { + if (keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + uint32_t num_blocks = size >> 4; + size_t aligned_size = num_blocks << 4; + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 4; + + if (num_blocks >= 1) { + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1; + trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0); + } + if (size > aligned_size) { + se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0); + } + +} + + +/* SE context save API. */ +void se_set_in_context_save_mode(bool is_context_save_mode) { + uint32_t val = SECURITY_ENGINE->_0x0; + if (is_context_save_mode) { + val |= 0x10000; + } else { + val &= 0xFFFEFFFF; + } + SECURITY_ENGINE->_0x0 = val; + /* Perform a useless read from flags reg. */ + (void)(SECURITY_ENGINE->FLAGS_REG); +} + +void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) { + if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) { + generic_panic(); + } + + /* Setup Config. */ + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_KEYTAB); + SECURITY_ENGINE->CRYPTO_REG = (rng_keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 4; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + + /* Generate low part of key. */ + SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8); + trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); + /* Generate high part of key. */ + SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1; + trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); +} + +void se_generate_srk(unsigned int srkgen_keyslot) { + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_SRK); + SECURITY_ENGINE->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 6; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0); +} + +void se_encrypt_with_srk(void *dst, size_t dst_size, const void *src, size_t src_size) { + uint8_t ALIGN(16) output[0x80]; + uint8_t *aligned_out = (uint8_t *)(((uintptr_t)output + 0x7F) & ~0x3F); + if (dst_size > 0x10) { + generic_panic(); + } + if (dst_size) { + trigger_se_blocking_op(OP_CTX_SAVE, aligned_out, dst_size, src, src_size); + memcpy(dst, aligned_out, dst_size); + } else { + trigger_se_blocking_op(OP_CTX_SAVE, aligned_out, 0, src, src_size); + } +} + +void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void *dst) { + uint8_t ALIGN(16) _work_buf[0x80]; + uint8_t *work_buf = (uint8_t *)(((uintptr_t)_work_buf + 0x7F) & ~0x3F); + + /* Generate the SRK (context save encryption key). */ + se_generate_random_key(srkgen_keyslot, rng_keyslot); + se_generate_srk(srkgen_keyslot); + + se_generate_random(rng_keyslot, work_buf, 0x10); + + /* Save random initial block. */ + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst, 0x10, work_buf, 0x10); + + /* Save Sticky Bits. */ + for (unsigned int i = 0; i < 0x2; i++) { + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0); + } + + /* Save AES Key Table. */ + for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0); + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0); + } + + /* Save AES Original IVs. */ + for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0); + } + + /* Save AES Updated IVs */ + for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) { + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0); + } + + /* Save RSA Keytable. */ + uint8_t *rsa_ctx_out = (uint8_t *)dst + 0x430; + for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) { + for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) { + for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) { + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0); + rsa_ctx_out += 0x10; + } + } + } + + /* Save "Known Pattern. " */ + static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10); + + /* Save SRK into PMC registers. */ + SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK); + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + se_encrypt_with_srk(work_buf, 0, NULL, 0); + SECURITY_ENGINE->CONFIG_REG = 0; + se_encrypt_with_srk(work_buf, 0, NULL, 0); +} diff --git a/fusee/src/se.h b/fusee/src/se.h new file mode 100644 index 000000000..b7621d2ec --- /dev/null +++ b/fusee/src/se.h @@ -0,0 +1,220 @@ +#ifndef FUSEE_SE_H +#define FISEE_SE_H + +#include "utils.h" +#include + +#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2 +#define KEYSLOT_SWITCH_SRKGENKEY 0x8 +#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8 +#define KEYSLOT_SWITCH_TEMPKEY 0x9 +#define KEYSLOT_SWITCH_SESSIONKEY 0xA +#define KEYSLOT_SWITCH_RNGKEY 0xB +#define KEYSLOT_SWITCH_MASTERKEY 0xC +#define KEYSLOT_SWITCH_DEVICEKEY 0xD + +/* This keyslot was added in 4.0.0. */ +#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD +#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE +#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF + +#define KEYSLOT_AES_MAX 0x10 +#define KEYSLOT_RSA_MAX 0x2 + +#define KEYSIZE_AES_MAX 0x20 +#define KEYSIZE_RSA_MAX 0x100 + +#define ALG_SHIFT (12) +#define ALG_DEC_SHIFT (8) +#define ALG_NOP (0 << ALG_SHIFT) +#define ALG_AES_ENC (1 << ALG_SHIFT) +#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP) +#define ALG_RNG (2 << ALG_SHIFT) +#define ALG_SHA (3 << ALG_SHIFT) +#define ALG_RSA (4 << ALG_SHIFT) + +#define DST_SHIFT (2) +#define DST_MEMORY (0 << DST_SHIFT) +#define DST_HASHREG (1 << DST_SHIFT) +#define DST_KEYTAB (2 << DST_SHIFT) +#define DST_SRK (3 << DST_SHIFT) +#define DST_RSAREG (4 << DST_SHIFT) + +#define ENCMODE_SHIFT (24) +#define DECMODE_SHIFT (16) +#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT) + +#define HASH_DISABLE (0x0) +#define HASH_ENABLE (0x1) + +#define OP_ABORT 0 +#define OP_START 1 +#define OP_RESTART 2 +#define OP_CTX_SAVE 3 +#define OP_RESTART_IN 4 + +#define CTX_SAVE_SRC_SHIFT 29 +#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT) +#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT) +#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT) +#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT) +#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT) + +#define CTX_SAVE_KEY_LOW_BITS 0 +#define CTX_SAVE_KEY_HIGH_BITS 1 +#define CTX_SAVE_KEY_ORIGINAL_IV 2 +#define CTX_SAVE_KEY_UPDATED_IV 3 + +#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24 +#define CTX_SAVE_KEY_INDEX_SHIFT 8 +#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16 +#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12 + +#define RSA_2048_BYTES 0x100 + +typedef struct security_engine { + unsigned int _0x0; + unsigned int _0x4; + unsigned int OPERATION_REG; + unsigned int INT_ENABLE_REG; + unsigned int INT_STATUS_REG; + unsigned int CONFIG_REG; + unsigned int IN_LL_ADDR_REG; + unsigned int _0x1C; + unsigned int _0x20; + unsigned int OUT_LL_ADDR_REG; + unsigned int _0x28; + unsigned int _0x2C; + unsigned char HASH_RESULT_REG[0x20]; + unsigned char _0x50[0x20]; + unsigned int CONTEXT_SAVE_CONFIG_REG; + unsigned char _0x74[0x18C]; + unsigned int SHA_CONFIG_REG; + unsigned int SHA_MSG_LENGTH_REG; + unsigned int _0x20C; + unsigned int _0x210; + unsigned int SHA_MSG_LEFT_REG; + unsigned int _0x218; + unsigned int _0x21C; + unsigned int _0x220; + unsigned int _0x224; + unsigned char _0x228[0x5C]; + unsigned int AES_KEY_READ_DISABLE_REG; + unsigned int AES_KEYSLOT_FLAGS[0x10]; + unsigned char _0x2C4[0x3C]; + unsigned int _0x300; + unsigned int CRYPTO_REG; + unsigned int CRYPTO_CTR_REG[4]; + unsigned int BLOCK_COUNT_REG; + unsigned int AES_KEYTABLE_ADDR; + unsigned int AES_KEYTABLE_DATA; + unsigned int _0x324; + unsigned int _0x328; + unsigned int _0x32C; + unsigned int CRYPTO_KEYTABLE_DST_REG; + unsigned char _0x334[0xC]; + unsigned int RNG_CONFIG_REG; + unsigned int RNG_SRC_CONFIG_REG; + unsigned int RNG_RESEED_INTERVAL_REG; + unsigned char _0x34C[0xB4]; + unsigned int RSA_CONFIG; + unsigned int RSA_KEY_SIZE_REG; + unsigned int RSA_EXP_SIZE_REG; + unsigned int RSA_KEY_READ_DISABLE_REG; + unsigned int RSA_KEYSLOT_FLAGS[2]; + unsigned int _0x418; + unsigned int _0x41C; + unsigned int RSA_KEYTABLE_ADDR; + unsigned int RSA_KEYTABLE_DATA; + unsigned char RSA_OUTPUT[0x100]; + unsigned char _0x528[0x2D8]; + unsigned int FLAGS_REG; + unsigned int ERR_STATUS_REG; + unsigned int _0x808; + unsigned int _0x80C; + unsigned int _0x810; + unsigned int _0x814; + unsigned int _0x818; + unsigned int _0x81C; + unsigned char _0x820[0x17E0]; +} security_engine_t; + +static_assert(sizeof(security_engine_t) == 0x2000, "Mis-defined Security Engine Registers!"); + +typedef struct { + uint32_t address; + uint32_t size; +} se_addr_info_t; + +typedef struct { + uint32_t num_entries; /* Set to total entries - 1 */ + se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */ +} se_ll_t; + + +/* WIP, API subject to change. */ + +static inline volatile security_engine_t *get_security_engine(void) { + return (volatile security_engine_t *)0x70012000; +} + +#define SECURITY_ENGINE (get_security_engine()) + +/* This function MUST be registered to fire on the appropriate interrupt. */ +void se_operation_completed(void); + +void se_check_error_status_reg(void); +void se_check_for_error(void); +void se_trigger_interrupt(void); + +void se_validate_stored_vector(void); +void se_generate_stored_vector(void); + +void se_verify_flags_cleared(void); + +void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags); +void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags); +void clear_aes_keyslot(unsigned int keyslot); +void clear_rsa_keyslot(unsigned int keyslot); + +void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size); +void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size); +void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size); +void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size); +void set_se_ctr(const void *ctr); + + +/* Insecure AES API */ +void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)); +void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)); +void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)); + +/* Secure AES API */ +void se_compute_aes_128_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size); +void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size); +void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); +void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); +void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size); +void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); +void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv); + +/* Hash API */ +void se_calculate_sha256(void *dst, const void *src, size_t src_size); + +/* RSA API */ +void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)); +void se_get_exp_mod_output(void *buf, size_t size); +void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); +bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const void *modulus, size_t modulus_size, const void *data, size_t data_size); + +/* RNG API */ +void se_initialize_rng(unsigned int keyslot); +void se_generate_random(unsigned int keyslot, void *dst, size_t size); + +/* SE context save API. */ +void se_generate_srk(unsigned int srkgen_keyslot); +void se_set_in_context_save_mode(bool is_context_save_mode); +void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot); +void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst); + +#endif /* EXOSPHERE_SE_H */ diff --git a/fusee/src/timers.h b/fusee/src/timers.h new file mode 100644 index 000000000..3c19a7f2c --- /dev/null +++ b/fusee/src/timers.h @@ -0,0 +1,31 @@ +#ifndef FUSEE_TIMERS_H +#define FUSEE_TIMERS_H + +#include "utils.h" + +#define TIMERS_BASE 0x60005000 + +#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n) + +#define TIMERUS_CNTR_1US_0 MAKE_REG32(TIMERS_BASE + 0x10) + +typedef struct { + uint32_t CONFIG; + uint32_t STATUS; + uint32_t COMMAND; + uint32_t PATTERN; +} watchdog_timers_t; + +#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n)) +#define WDT_REBOOT_PATTERN 0xC45A +#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8*n) + +void wait(uint32_t microseconds); + +static inline uint32_t get_time(void) { + return TIMERUS_CNTR_1US_0; +} + +__attribute__ ((noreturn)) void watchdog_reboot(void); + +#endif diff --git a/fusee/src/utils.c b/fusee/src/utils.c new file mode 100644 index 000000000..37eaac14e --- /dev/null +++ b/fusee/src/utils.c @@ -0,0 +1,39 @@ +#include +#include "utils.h" +#include "se.h" +#include "fuse.h" +#include "pmc.h" +#include "panic_color.h" +#include "timers.h" + + +__attribute__ ((noreturn)) void panic(uint32_t code) { + /* Set Panic Code for NX_BOOTLOADER. */ + if (APBDEV_PMC_SCRATCH200_0 == 0) { + APBDEV_PMC_SCRATCH200_0 = code; + } + + /* TODO: Custom Panic Driver, which displays to screen without rebooting. */ + /* For now, just use NX BOOTLOADER's panic. */ + fuse_disable_programming(); + APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */ + watchdog_reboot(); +} + +__attribute__ ((noreturn)) void generic_panic(void) { + panic(0xFF000006); +} + +__attribute__ ((noreturn)) void panic_predefined(uint32_t which) { + static const uint32_t codes[0x10] = {COLOR_0, COLOR_1, COLOR_2, COLOR_3, COLOR_4, COLOR_5, COLOR_6, COLOR_7, COLOR_8, COLOR_9, COLOR_A, COLOR_B, COLOR_C, COLOR_D, COLOR_E, COLOR_F}; + panic(codes[which & 0xF]); +} + +__attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be) +{ + if(as <= bs && bs <= ae) + return true; + if(bs <= as && as <= be) + return true; + return false; +} diff --git a/fusee/src/utils.h b/fusee/src/utils.h new file mode 100644 index 000000000..f2a767cf3 --- /dev/null +++ b/fusee/src/utils.h @@ -0,0 +1,76 @@ +#ifndef FUSEE_UTILS_H +#define FUSEE_UTILS_H + +#include +#include +#include +#include + +#define BIT(n) (1u << (n)) +#define BITL(n) (1ull << (n)) +#define MASK(n) (BIT(n) - 1) +#define MASKL(n) (BITL(n) - 1) +#define MASK2(a,b) (MASK(a) & ~MASK(b)) +#define MASK2L(a,b) (MASKL(a) & ~MASKL(b)) + +#define MAKE_REG32(a) (*(volatile uint32_t *)(a)) + +#define ALIGN(m) __attribute__((aligned(m))) +#define PACKED __attribute__((packed)) + +#define ALINLINE __attribute__((always_inline)) + +#define SET_SYSREG(reg, val) do { temp_reg = (val); __asm__ __volatile__ ("msr " #reg ", %0" :: "r"(temp_reg) : "memory"); } while(false) + +static inline uintptr_t get_physical_address(const void *addr) { + return (uintptr_t)addr; +} + +static inline uint32_t read32le(const volatile void *dword, size_t offset) { + uintptr_t addr = (uintptr_t)dword + offset; + uint32_t dst; + memcpy(&dst, (void *)addr, 4); + return dst; +} + +static inline uint32_t read32be(const volatile void *dword, size_t offset) { + return __builtin_bswap32(read32le(dword, offset)); +} + +static inline uint64_t read64le(const volatile void *qword, size_t offset) { + uintptr_t addr = (uintptr_t)qword + offset; + uint64_t dst; + memcpy(&dst, (void *)addr, 8); + return dst; +} + +static inline uint64_t read64be(const volatile void *qword, size_t offset) { + return __builtin_bswap64(read64le(qword, offset)); +} + +static inline void write32le(volatile void *dword, size_t offset, uint32_t value) { + memcpy((void *)((uintptr_t)dword + offset), &value, 4); +} + +static inline void write32be(volatile void *dword, size_t offset, uint32_t value) { + write32le(dword, offset, __builtin_bswap32(value)); +} + +static inline void write64le(volatile void *qword, size_t offset, uint64_t value) { + memcpy((void *)((uintptr_t)qword + offset), &value, 8); +} + +static inline void write64be(volatile void *qword, size_t offset, uint64_t value) { + write64le(qword, offset, __builtin_bswap64(value)); +} + +static inline bool check_32bit_additive_overflow(uint32_t a, uint32_t b) { + return __builtin_add_overflow_p(a, b, (uint32_t)0); +} + +void panic(uint32_t code); +void generic_panic(void); +void panic_predefined(uint32_t which); +bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be); + +#endif