diff options
98 files changed, 2730 insertions, 1614 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index d3ef58b..c6b1efe 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -4,6 +4,9 @@ menu "ARC architecture" config SYS_ARCH default "arc" +config SYS_CPU + default "arcv1" + choice prompt "Target select" diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 03ea6db..a59231e 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -2,8 +2,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -head-y := arch/arc/cpu/$(CPU)/start.o - libs-y += arch/arc/cpu/$(CPU)/ libs-y += arch/arc/lib/ diff --git a/arch/arc/config.mk b/arch/arc/config.mk index e408800..5321987 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -21,6 +21,10 @@ ifeq ($(CROSS_COMPILE),) CROSS_COMPILE := $(ARC_CROSS_COMPILE) endif +ifdef CONFIG_ARC_MMU_VER +CONFIG_MMU = 1 +endif + PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 # Needed for relocation diff --git a/arch/arc/cpu/arc700/Makefile b/arch/arc/cpu/arc700/Makefile deleted file mode 100644 index cdc5002..0000000 --- a/arch/arc/cpu/arc700/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -extra-y += start.o - -obj-y += cache.o -obj-y += cpu.o -obj-y += interrupts.o -obj-y += reset.o -obj-y += timer.o diff --git a/arch/arc/cpu/arcv1/Makefile b/arch/arc/cpu/arcv1/Makefile new file mode 100644 index 0000000..3704ebe --- /dev/null +++ b/arch/arc/cpu/arcv1/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += start.o diff --git a/arch/arc/cpu/arc700/config.mk b/arch/arc/cpu/arcv1/config.mk index 3206ff4..3206ff4 100644 --- a/arch/arc/cpu/arc700/config.mk +++ b/arch/arc/cpu/arcv1/config.mk diff --git a/arch/arc/cpu/arc700/start.S b/arch/arc/cpu/arcv1/start.S index 563513b..01cfba4 100644 --- a/arch/arc/cpu/arc700/start.S +++ b/arch/arc/cpu/arcv1/start.S @@ -57,11 +57,13 @@ .endm .macro SAVE_ALL_SYS - + /* saving %r0 to reg->r0 in advance since we read %ecr into it */ + st %r0, [%sp, -8] + lr %r0, [%ecr] /* all stack addressing is manual so far */ st %r0, [%sp] - lr %r0, [%ecr] - st %r0, [%sp, 8] /* ECR */ - st %sp, [%sp, 4] + st %sp, [%sp, -4] + /* now move %sp to reg->r0 position so we can do "push" automatically */ + sub %sp, %sp, 8 SAVE_R1_TO_R24 PUSH %r25 @@ -76,11 +78,21 @@ PUSHAX %erbta .endm +.macro SAVE_EXCEPTION_SOURCE +#ifdef CONFIG_MMU + /* If MMU exists exception faulting address is loaded in EFA reg */ + lr %r0, [%efa] +#else + /* Otherwise in ERET (exception return) reg */ + lr %r0, [%eret] +#endif +.endm + +.section .ivt, "ax",@progbits .align 4 -.globl _start -_start: +_ivt: /* Critical system events */ - j reset /* 0 - 0x000 */ + j _start /* 0 - 0x000 */ j memory_error /* 1 - 0x008 */ j instruction_error /* 2 - 0x010 */ @@ -98,15 +110,37 @@ _start: j EV_Trap /* 0x128, Trap exception (0x25) */ j EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ +.text +.globl _start +_start: + /* Setup interrupt vector base that matches "__text_start" */ + sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] + + /* Setup stack pointer */ + mov %sp, CONFIG_SYS_INIT_SP_ADDR + mov %fp, %sp + + /* Clear bss */ + mov %r0, __bss_start + mov %r1, __bss_end + +clear_bss: + st.ab 0, [%r0, 4] + brlt %r0, %r1, clear_bss + + /* Zero the one and only argument of "board_init_f" */ + mov_s %r0, 0 + j board_init_f + memory_error: SAVE_ALL_SYS - lr %r0, [%efa] + SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_memory_error instruction_error: SAVE_ALL_SYS - lr %r0, [%efa] + SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_instruction_error @@ -117,7 +151,7 @@ interrupt_handler: EV_MachineCheck: SAVE_ALL_SYS - lr %r0, [%efa] + SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_machine_check_fault @@ -133,7 +167,7 @@ EV_TLBMissD: EV_TLBProtV: SAVE_ALL_SYS - lr %r0, [%efa] + SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_tlb_prot_violation @@ -152,27 +186,6 @@ EV_Extension: mov %r0, %sp j do_extension - -reset: - /* Setup interrupt vector base that matches "__text_start" */ - sr __text_start, [ARC_AUX_INTR_VEC_BASE] - - /* Setup stack pointer */ - mov %sp, CONFIG_SYS_INIT_SP_ADDR - mov %fp, %sp - - /* Clear bss */ - mov %r0, __bss_start - mov %r1, __bss_end - -clear_bss: - st.ab 0, [%r0, 4] - brlt %r0, %r1, clear_bss - - /* Zero the one and only argument of "board_init_f" */ - mov_s %r0, 0 - j board_init_f - /* * void relocate_code (addr_sp, gd, addr_moni) * diff --git a/arch/arc/cpu/arc700/u-boot.lds b/arch/arc/cpu/u-boot.lds index 2d01b21..ccddbf7 100644 --- a/arch/arc/cpu/arc700/u-boot.lds +++ b/arch/arc/cpu/u-boot.lds @@ -13,7 +13,6 @@ SECTIONS .text : { *(.__text_start) *(.__image_copy_start) - CPUDIR/start.o (.text*) *(.text*) } @@ -23,6 +22,20 @@ SECTIONS *(.__text_end) } + . = ALIGN(1024); + .ivt_start : { + *(.__ivt_start) + } + + .ivt : + { + *(.ivt) + } + + .ivt_end : { + *(.__ivt_end) + } + . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 5d48d11..8ace87f 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -24,6 +24,7 @@ #if (CONFIG_ARC_MMU_VER > 2) #define ARC_AUX_IC_PTAG 0x1E #endif +#define ARC_BCR_IC_BUILD 0x77 /* Timer related auxiliary registers */ #define ARC_AUX_TIMER0_CNT 0x21 /* Timer 0 count */ @@ -42,6 +43,7 @@ #if (CONFIG_ARC_MMU_VER > 2) #define ARC_AUX_DC_PTAG 0x5C #endif +#define ARC_BCR_DC_BUILD 0x72 #ifndef __ASSEMBLY__ /* Accessors for auxiliary registers */ diff --git a/arch/arc/include/asm/sections.h b/arch/arc/include/asm/sections.h index 18484a1..b8f2a85 100644 --- a/arch/arc/include/asm/sections.h +++ b/arch/arc/include/asm/sections.h @@ -10,5 +10,8 @@ #include <asm-generic/sections.h> extern ulong __text_end; +extern ulong __ivt_start; +extern ulong __ivt_end; +extern ulong __image_copy_start; #endif /* __ASM_ARC_SECTIONS_H */ diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index 7675f85..bae4419 100644 --- a/arch/arc/lib/Makefile +++ b/arch/arc/lib/Makefile @@ -4,6 +4,9 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += cache.o +obj-y += cpu.o +obj-y += interrupts.o obj-y += sections.o obj-y += relocate.o obj-y += strchr-700.o @@ -13,4 +16,7 @@ obj-y += strlen.o obj-y += memcmp.o obj-y += memcpy-700.o obj-y += memset.o +obj-y += reset.o +obj-y += timer.o + obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/arc/cpu/arc700/cache.c b/arch/arc/lib/cache.c index 39d522d..fa19a13 100644 --- a/arch/arc/cpu/arc700/cache.c +++ b/arch/arc/lib/cache.c @@ -14,21 +14,34 @@ #define DC_CTRL_CACHE_DISABLE (1 << 0) #define DC_CTRL_INV_MODE_FLUSH (1 << 6) #define DC_CTRL_FLUSH_STATUS (1 << 8) +#define CACHE_VER_NUM_MASK 0xF int icache_status(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return 0; + return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) != IC_CTRL_CACHE_DISABLE; } void icache_enable(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & ~IC_CTRL_CACHE_DISABLE); } void icache_disable(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | IC_CTRL_CACHE_DISABLE); } @@ -43,24 +56,40 @@ void invalidate_icache_all(void) int dcache_status(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return 0; + return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) != DC_CTRL_CACHE_DISABLE; } void dcache_enable(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE)); } void dcache_disable(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) | DC_CTRL_CACHE_DISABLE); } void flush_dcache_all(void) { + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + /* Do flush of entire cache */ write_aux_reg(ARC_AUX_DC_FLSH, 1); diff --git a/arch/arc/cpu/arc700/cpu.c b/arch/arc/lib/cpu.c index 50634b8..50634b8 100644 --- a/arch/arc/cpu/arc700/cpu.c +++ b/arch/arc/lib/cpu.c diff --git a/arch/arc/cpu/arc700/interrupts.c b/arch/arc/lib/interrupts.c index d93a6eb..d7cab3b 100644 --- a/arch/arc/cpu/arc700/interrupts.c +++ b/arch/arc/lib/interrupts.c @@ -23,7 +23,7 @@ int interrupt_init(void) int disable_interrupts(void) { int status = read_aux_reg(ARC_AUX_STATUS32); - int state = (status | E1_MASK | E2_MASK) ? 1 : 0; + int state = (status & (E1_MASK | E2_MASK)) ? 1 : 0; status &= ~(E1_MASK | E2_MASK); /* STATUS32 register is updated indirectly with "FLAG" instruction */ @@ -61,6 +61,7 @@ static void print_reg_file(long *reg_rev, int start_num) void show_regs(struct pt_regs *regs) { + printf("ECR:\t0x%08lx\n", regs->ecr); printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n", regs->ret, regs->blink, regs->status32); printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25); diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c index 2482bcd..7797782 100644 --- a/arch/arc/lib/relocate.c +++ b/arch/arc/lib/relocate.c @@ -26,7 +26,7 @@ int do_elf_reloc_fixups(void) offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; /* Check that the location of the relocation is in .text */ - if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE && + if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start && offset_ptr_rom > last_offset) { unsigned int val; /* Switch to the in-RAM version */ @@ -44,29 +44,22 @@ int do_elf_reloc_fixups(void) #ifdef __LITTLE_ENDIAN__ /* If location in ".text" section swap value */ if ((unsigned int)offset_ptr_rom < - (unsigned int)&__text_end) + (unsigned int)&__ivt_end) val = (val << 16) | (val >> 16); #endif - /* Check that the target points into .text */ - if (val >= CONFIG_SYS_TEXT_BASE && val <= - (unsigned int)&__bss_end) { + /* Check that the target points into executable */ + if (val >= (unsigned int)&__image_copy_start && val <= + (unsigned int)&__image_copy_end) { val += gd->reloc_off; #ifdef __LITTLE_ENDIAN__ /* If location in ".text" section swap value */ if ((unsigned int)offset_ptr_rom < - (unsigned int)&__text_end) + (unsigned int)&__ivt_end) val = (val << 16) | (val >> 16); #endif memcpy(offset_ptr_ram, &val, sizeof(int)); - } else { - debug(" %p: rom reloc %x, ram %p, value %x, limit %x\n", - re_src, re_src->r_offset, offset_ptr_ram, - val, (unsigned int)&__bss_end); } - } else { - debug(" %p: rom reloc %x, last %p\n", re_src, - re_src->r_offset, last_offset); } last_offset = offset_ptr_rom; diff --git a/arch/arc/cpu/arc700/reset.c b/arch/arc/lib/reset.c index 98ebf1d..98ebf1d 100644 --- a/arch/arc/cpu/arc700/reset.c +++ b/arch/arc/lib/reset.c diff --git a/arch/arc/lib/sections.c b/arch/arc/lib/sections.c index b0b46a4..a72c694 100644 --- a/arch/arc/lib/sections.c +++ b/arch/arc/lib/sections.c @@ -19,3 +19,5 @@ char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); char __text_start[0] __attribute__((section(".__text_start"))); char __text_end[0] __attribute__((section(".__text_end"))); char __init_end[0] __attribute__((section(".__init_end"))); +char __ivt_start[0] __attribute__((section(".__ivt_start"))); +char __ivt_end[0] __attribute__((section(".__ivt_end"))); diff --git a/arch/arc/cpu/arc700/timer.c b/arch/arc/lib/timer.c index a0acbbc..a0acbbc 100644 --- a/arch/arc/cpu/arc700/timer.c +++ b/arch/arc/lib/timer.c diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index eaf09d1..81477aa 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -285,14 +285,6 @@ void s_init(void) #ifdef CONFIG_NOR_BOOT enable_norboot_pin_mux(); #endif - /* - * Save the boot parameters passed from romcode. - * We cannot delay the saving further than this, - * to prevent overwrites. - */ -#ifdef CONFIG_SPL_BUILD - save_omap_boot_params(); -#endif watchdog_disable(); set_uart_mux_conf(); setup_clocks_for_console(); @@ -301,9 +293,6 @@ void s_init(void) gd->baudrate = CONFIG_BAUDRATE; serial_init(); gd->have_console = 1; -#elif defined(CONFIG_SPL_BUILD) - gd = &gdata; - preloader_console_init(); #endif #if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) /* Enable RTC32K clock */ diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 00a1082..17500f2 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -106,6 +106,16 @@ u32 spl_boot_mode(void) void spl_board_init(void) { + /* + * Save the boot parameters passed from romcode. + * We cannot delay the saving further than this, + * to prevent overwrites. + */ + save_omap_boot_params(); + + /* Prepare console output */ + preloader_console_init(); + #ifdef CONFIG_SPL_NAND_SUPPORT gpmc_init(); #endif diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index dd52e93..cb35c19 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -111,14 +111,6 @@ int arch_cpu_init(void) */ void s_init(void) { - /* - * Save the boot parameters passed from romcode. - * We cannot delay the saving further than this, - * to prevent overwrites. - */ -#ifdef CONFIG_SPL_BUILD - save_omap_boot_params(); -#endif init_omap_revision(); hw_data_init(); @@ -133,9 +125,6 @@ void s_init(void) srcomp_enable(); setup_clocks_for_console(); - gd = &gdata; - - preloader_console_init(); do_io_settings(); #endif prcm_init(); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 53a9e5d..90d6ae7 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -119,6 +119,7 @@ int board_mmc_init(bd_t *bis) void spl_board_init(void) { + preloader_console_init(); #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT) gpmc_init(); #endif @@ -264,14 +265,6 @@ void s_init(void) ehci_clocks_enable(); #endif -#ifdef CONFIG_SPL_BUILD - gd = &gdata; - - preloader_console_init(); - - timer_init(); -#endif - if (!in_sdram) mem_init(); } diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index bc98c56..6e28bcd 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -27,28 +27,7 @@ #include <linux/compiler.h> -#ifdef CONFIG_SPL_BUILD -/* Pointer to the global data structure for SPL */ -DECLARE_GLOBAL_DATA_PTR; - -/* The sunxi internal brom will try to loader external bootloader - * from mmc0, nand flash, mmc2. - * Unfortunately we can't check how SPL was loaded so assume - * it's always the first SD/MMC controller - */ -u32 spl_boot_device(void) -{ - return BOOT_DEVICE_MMC1; -} - -/* No confirmation data available in SPL yet. Hardcode bootmode */ -u32 spl_boot_mode(void) -{ - return MMCSD_MODE_RAW; -} -#endif - -int gpio_init(void) +static int gpio_init(void) { #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F) #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) @@ -86,36 +65,9 @@ int gpio_init(void) return 0; } -void reset_cpu(ulong addr) -{ -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) - static const struct sunxi_wdog *wdog = - &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; - - /* Set the watchdog for its shortest interval (.5s) and wait */ - writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); - writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); - - while (1) { - /* sun5i sometimes gets stuck without this */ - writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); - } -#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_SUN8I || .. */ - static const struct sunxi_wdog *wdog = - ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; - - /* Set the watchdog for its shortest interval (.5s) and wait */ - writel(WDT_CFG_RESET, &wdog->cfg); - writel(WDT_MODE_EN, &wdog->mode); - writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); -#endif -} - -/* do some early init */ void s_init(void) { -#if defined CONFIG_SPL_BUILD && \ - (defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I) +#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I /* Magic (undocmented) value taken from boot0, without this DRAM * access gets messed up (seems cache related) */ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); @@ -133,9 +85,27 @@ void s_init(void) timer_init(); gpio_init(); i2c_init_board(); +} #ifdef CONFIG_SPL_BUILD - gd = &gdata; +/* The sunxi internal brom will try to loader external bootloader + * from mmc0, nand flash, mmc2. + * Unfortunately we can't check how SPL was loaded so assume + * it's always the first SD/MMC controller + */ +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_MMC1; +} + +/* No confirmation data available in SPL yet. Hardcode bootmode */ +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} + +void board_init_f(ulong dummy) +{ preloader_console_init(); #ifdef CONFIG_SPL_I2C_SUPPORT @@ -143,6 +113,36 @@ void s_init(void) i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif sunxi_board_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + board_init_r(NULL, 0); +} +#endif + +void reset_cpu(ulong addr) +{ +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) + static const struct sunxi_wdog *wdog = + &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; + + /* Set the watchdog for its shortest interval (.5s) and wait */ + writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); + writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); + + while (1) { + /* sun5i sometimes gets stuck without this */ + writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); + } +#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_SUN8I || .. */ + static const struct sunxi_wdog *wdog = + ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; + + /* Set the watchdog for its shortest interval (.5s) and wait */ + writel(WDT_CFG_RESET, &wdog->cfg); + writel(WDT_MODE_EN, &wdog->mode); + writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); #endif } diff --git a/arch/arm/cpu/armv7/uniphier/init_page_table.S b/arch/arm/cpu/armv7/uniphier/init_page_table.S new file mode 100644 index 0000000..2638bcd --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/init_page_table.S @@ -0,0 +1,26 @@ +#include <config.h> +#include <linux/linkage.h> + +/* page table */ +#define NR_SECTIONS 4096 +#define SECTION_SHIFT 20 +#define DEVICE 0x00002002 /* Non-shareable Device */ +#define NORMAL 0x0000000e /* Normal Memory Write-Back, No Write-Allocate */ + +#define TEXT_SECTION ((CONFIG_SPL_TEXT_BASE) >> (SECTION_SHIFT)) +#define STACK_SECTION ((CONFIG_SYS_INIT_SP_ADDR) >> (SECTION_SHIFT)) + + .section ".rodata" + .align 14 +ENTRY(init_page_table) + section = 0 + .rept NR_SECTIONS + .if section == TEXT_SECTION || section == STACK_SECTION + attr = NORMAL + .else + attr = DEVICE + .endif + .word (section << SECTION_SHIFT) | attr + section = section + 1 + .endr +END(init_page_table) diff --git a/arch/arm/cpu/armv7/uniphier/init_page_table.c b/arch/arm/cpu/armv7/uniphier/init_page_table.c deleted file mode 100644 index febb3c8..0000000 --- a/arch/arm/cpu/armv7/uniphier/init_page_table.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -/* encoding without TEX remap */ -#define NO_MAP 0x00000000 /* No Map */ -#define DEVICE 0x00002002 /* Non-shareable Device */ -#define NORMAL 0x0000000e /* Normal Memory Write-Back, No Write-Allocate */ - -#define SSC NORMAL /* System Cache: Normal */ -#define EXT DEVICE /* External Bus: Device */ -#define REG DEVICE /* IO Register: Device */ -#define DDR DEVICE /* DDR SDRAM: Device */ - -#define IS_SPL_TEXT_AREA(x) ((x) == ((CONFIG_SPL_TEXT_BASE) >> 20)) - -#define IS_INIT_STACK_AREA(x) ((x) == ((CONFIG_SYS_INIT_SP_ADDR) >> 20)) - -#define IS_SSC(x) ((IS_SPL_TEXT_AREA(x)) || \ - (IS_INIT_STACK_AREA(x))) -#define IS_EXT(x) ((x) < 0x100) - -/* 0x20000000-0x2fffffff, 0xf0000000-0xffffffff are only used by PH1-sLD3 */ -#define IS_REG(x) (0x200 <= (x) && (x) < 0x300) || \ - (0x500 <= (x) && (x) < 0x700) || \ - (0xf00 <= (x)) - -#define IS_DDR(x) (0x800 <= (x) && (x) < 0xf00) - -#define MMU_FLAGS(x) (IS_SSC(x)) ? SSC : \ - (IS_EXT(x)) ? EXT : \ - (IS_REG(x)) ? REG : \ - (IS_DDR(x)) ? DDR : \ - NO_MAP - -#define TBL_ENTRY(x) (((x) << 20) | (MMU_FLAGS(x))) - -const u32 __aligned(PGTABLE_SIZE) init_page_table[PGTABLE_SIZE / sizeof(u32)] - = { - TBL_ENTRY(0x000), TBL_ENTRY(0x001), TBL_ENTRY(0x002), TBL_ENTRY(0x003), - TBL_ENTRY(0x004), TBL_ENTRY(0x005), TBL_ENTRY(0x006), TBL_ENTRY(0x007), - TBL_ENTRY(0x008), TBL_ENTRY(0x009), TBL_ENTRY(0x00a), TBL_ENTRY(0x00b), - TBL_ENTRY(0x00c), TBL_ENTRY(0x00d), TBL_ENTRY(0x00e), TBL_ENTRY(0x00f), - TBL_ENTRY(0x010), TBL_ENTRY(0x011), TBL_ENTRY(0x012), TBL_ENTRY(0x013), - TBL_ENTRY(0x014), TBL_ENTRY(0x015), TBL_ENTRY(0x016), TBL_ENTRY(0x017), - TBL_ENTRY(0x018), TBL_ENTRY(0x019), TBL_ENTRY(0x01a), TBL_ENTRY(0x01b), - TBL_ENTRY(0x01c), TBL_ENTRY(0x01d), TBL_ENTRY(0x01e), TBL_ENTRY(0x01f), - TBL_ENTRY(0x020), TBL_ENTRY(0x021), TBL_ENTRY(0x022), TBL_ENTRY(0x023), - TBL_ENTRY(0x024), TBL_ENTRY(0x025), TBL_ENTRY(0x026), TBL_ENTRY(0x027), - TBL_ENTRY(0x028), TBL_ENTRY(0x029), TBL_ENTRY(0x02a), TBL_ENTRY(0x02b), - TBL_ENTRY(0x02c), TBL_ENTRY(0x02d), TBL_ENTRY(0x02e), TBL_ENTRY(0x02f), - TBL_ENTRY(0x030), TBL_ENTRY(0x031), TBL_ENTRY(0x032), TBL_ENTRY(0x033), - TBL_ENTRY(0x034), TBL_ENTRY(0x035), TBL_ENTRY(0x036), TBL_ENTRY(0x037), - TBL_ENTRY(0x038), TBL_ENTRY(0x039), TBL_ENTRY(0x03a), TBL_ENTRY(0x03b), - TBL_ENTRY(0x03c), TBL_ENTRY(0x03d), TBL_ENTRY(0x03e), TBL_ENTRY(0x03f), - TBL_ENTRY(0x040), TBL_ENTRY(0x041), TBL_ENTRY(0x042), TBL_ENTRY(0x043), - TBL_ENTRY(0x044), TBL_ENTRY(0x045), TBL_ENTRY(0x046), TBL_ENTRY(0x047), - TBL_ENTRY(0x048), TBL_ENTRY(0x049), TBL_ENTRY(0x04a), TBL_ENTRY(0x04b), - TBL_ENTRY(0x04c), TBL_ENTRY(0x04d), TBL_ENTRY(0x04e), TBL_ENTRY(0x04f), - TBL_ENTRY(0x050), TBL_ENTRY(0x051), TBL_ENTRY(0x052), TBL_ENTRY(0x053), - TBL_ENTRY(0x054), TBL_ENTRY(0x055), TBL_ENTRY(0x056), TBL_ENTRY(0x057), - TBL_ENTRY(0x058), TBL_ENTRY(0x059), TBL_ENTRY(0x05a), TBL_ENTRY(0x05b), - TBL_ENTRY(0x05c), TBL_ENTRY(0x05d), TBL_ENTRY(0x05e), TBL_ENTRY(0x05f), - TBL_ENTRY(0x060), TBL_ENTRY(0x061), TBL_ENTRY(0x062), TBL_ENTRY(0x063), - TBL_ENTRY(0x064), TBL_ENTRY(0x065), TBL_ENTRY(0x066), TBL_ENTRY(0x067), - TBL_ENTRY(0x068), TBL_ENTRY(0x069), TBL_ENTRY(0x06a), TBL_ENTRY(0x06b), - TBL_ENTRY(0x06c), TBL_ENTRY(0x06d), TBL_ENTRY(0x06e), TBL_ENTRY(0x06f), - TBL_ENTRY(0x070), TBL_ENTRY(0x071), TBL_ENTRY(0x072), TBL_ENTRY(0x073), - TBL_ENTRY(0x074), TBL_ENTRY(0x075), TBL_ENTRY(0x076), TBL_ENTRY(0x077), - TBL_ENTRY(0x078), TBL_ENTRY(0x079), TBL_ENTRY(0x07a), TBL_ENTRY(0x07b), - TBL_ENTRY(0x07c), TBL_ENTRY(0x07d), TBL_ENTRY(0x07e), TBL_ENTRY(0x07f), - TBL_ENTRY(0x080), TBL_ENTRY(0x081), TBL_ENTRY(0x082), TBL_ENTRY(0x083), - TBL_ENTRY(0x084), TBL_ENTRY(0x085), TBL_ENTRY(0x086), TBL_ENTRY(0x087), - TBL_ENTRY(0x088), TBL_ENTRY(0x089), TBL_ENTRY(0x08a), TBL_ENTRY(0x08b), - TBL_ENTRY(0x08c), TBL_ENTRY(0x08d), TBL_ENTRY(0x08e), TBL_ENTRY(0x08f), - TBL_ENTRY(0x090), TBL_ENTRY(0x091), TBL_ENTRY(0x092), TBL_ENTRY(0x093), - TBL_ENTRY(0x094), TBL_ENTRY(0x095), TBL_ENTRY(0x096), TBL_ENTRY(0x097), - TBL_ENTRY(0x098), TBL_ENTRY(0x099), TBL_ENTRY(0x09a), TBL_ENTRY(0x09b), - TBL_ENTRY(0x09c), TBL_ENTRY(0x09d), TBL_ENTRY(0x09e), TBL_ENTRY(0x09f), - TBL_ENTRY(0x0a0), TBL_ENTRY(0x0a1), TBL_ENTRY(0x0a2), TBL_ENTRY(0x0a3), - TBL_ENTRY(0x0a4), TBL_ENTRY(0x0a5), TBL_ENTRY(0x0a6), TBL_ENTRY(0x0a7), - TBL_ENTRY(0x0a8), TBL_ENTRY(0x0a9), TBL_ENTRY(0x0aa), TBL_ENTRY(0x0ab), - TBL_ENTRY(0x0ac), TBL_ENTRY(0x0ad), TBL_ENTRY(0x0ae), TBL_ENTRY(0x0af), - TBL_ENTRY(0x0b0), TBL_ENTRY(0x0b1), TBL_ENTRY(0x0b2), TBL_ENTRY(0x0b3), - TBL_ENTRY(0x0b4), TBL_ENTRY(0x0b5), TBL_ENTRY(0x0b6), TBL_ENTRY(0x0b7), - TBL_ENTRY(0x0b8), TBL_ENTRY(0x0b9), TBL_ENTRY(0x0ba), TBL_ENTRY(0x0bb), - TBL_ENTRY(0x0bc), TBL_ENTRY(0x0bd), TBL_ENTRY(0x0be), TBL_ENTRY(0x0bf), - TBL_ENTRY(0x0c0), TBL_ENTRY(0x0c1), TBL_ENTRY(0x0c2), TBL_ENTRY(0x0c3), - TBL_ENTRY(0x0c4), TBL_ENTRY(0x0c5), TBL_ENTRY(0x0c6), TBL_ENTRY(0x0c7), - TBL_ENTRY(0x0c8), TBL_ENTRY(0x0c9), TBL_ENTRY(0x0ca), TBL_ENTRY(0x0cb), - TBL_ENTRY(0x0cc), TBL_ENTRY(0x0cd), TBL_ENTRY(0x0ce), TBL_ENTRY(0x0cf), - TBL_ENTRY(0x0d0), TBL_ENTRY(0x0d1), TBL_ENTRY(0x0d2), TBL_ENTRY(0x0d3), - TBL_ENTRY(0x0d4), TBL_ENTRY(0x0d5), TBL_ENTRY(0x0d6), TBL_ENTRY(0x0d7), - TBL_ENTRY(0x0d8), TBL_ENTRY(0x0d9), TBL_ENTRY(0x0da), TBL_ENTRY(0x0db), - TBL_ENTRY(0x0dc), TBL_ENTRY(0x0dd), TBL_ENTRY(0x0de), TBL_ENTRY(0x0df), - TBL_ENTRY(0x0e0), TBL_ENTRY(0x0e1), TBL_ENTRY(0x0e2), TBL_ENTRY(0x0e3), - TBL_ENTRY(0x0e4), TBL_ENTRY(0x0e5), TBL_ENTRY(0x0e6), TBL_ENTRY(0x0e7), - TBL_ENTRY(0x0e8), TBL_ENTRY(0x0e9), TBL_ENTRY(0x0ea), TBL_ENTRY(0x0eb), - TBL_ENTRY(0x0ec), TBL_ENTRY(0x0ed), TBL_ENTRY(0x0ee), TBL_ENTRY(0x0ef), - TBL_ENTRY(0x0f0), TBL_ENTRY(0x0f1), TBL_ENTRY(0x0f2), TBL_ENTRY(0x0f3), - TBL_ENTRY(0x0f4), TBL_ENTRY(0x0f5), TBL_ENTRY(0x0f6), TBL_ENTRY(0x0f7), - TBL_ENTRY(0x0f8), TBL_ENTRY(0x0f9), TBL_ENTRY(0x0fa), TBL_ENTRY(0x0fb), - TBL_ENTRY(0x0fc), TBL_ENTRY(0x0fd), TBL_ENTRY(0x0fe), TBL_ENTRY(0x0ff), - TBL_ENTRY(0x100), TBL_ENTRY(0x101), TBL_ENTRY(0x102), TBL_ENTRY(0x103), - TBL_ENTRY(0x104), TBL_ENTRY(0x105), TBL_ENTRY(0x106), TBL_ENTRY(0x107), - TBL_ENTRY(0x108), TBL_ENTRY(0x109), TBL_ENTRY(0x10a), TBL_ENTRY(0x10b), - TBL_ENTRY(0x10c), TBL_ENTRY(0x10d), TBL_ENTRY(0x10e), TBL_ENTRY(0x10f), - TBL_ENTRY(0x110), TBL_ENTRY(0x111), TBL_ENTRY(0x112), TBL_ENTRY(0x113), - TBL_ENTRY(0x114), TBL_ENTRY(0x115), TBL_ENTRY(0x116), TBL_ENTRY(0x117), - TBL_ENTRY(0x118), TBL_ENTRY(0x119), TBL_ENTRY(0x11a), TBL_ENTRY(0x11b), - TBL_ENTRY(0x11c), TBL_ENTRY(0x11d), TBL_ENTRY(0x11e), TBL_ENTRY(0x11f), - TBL_ENTRY(0x120), TBL_ENTRY(0x121), TBL_ENTRY(0x122), TBL_ENTRY(0x123), - TBL_ENTRY(0x124), TBL_ENTRY(0x125), TBL_ENTRY(0x126), TBL_ENTRY(0x127), - TBL_ENTRY(0x128), TBL_ENTRY(0x129), TBL_ENTRY(0x12a), TBL_ENTRY(0x12b), - TBL_ENTRY(0x12c), TBL_ENTRY(0x12d), TBL_ENTRY(0x12e), TBL_ENTRY(0x12f), - TBL_ENTRY(0x130), TBL_ENTRY(0x131), TBL_ENTRY(0x132), TBL_ENTRY(0x133), - TBL_ENTRY(0x134), TBL_ENTRY(0x135), TBL_ENTRY(0x136), TBL_ENTRY(0x137), - TBL_ENTRY(0x138), TBL_ENTRY(0x139), TBL_ENTRY(0x13a), TBL_ENTRY(0x13b), - TBL_ENTRY(0x13c), TBL_ENTRY(0x13d), TBL_ENTRY(0x13e), TBL_ENTRY(0x13f), - TBL_ENTRY(0x140), TBL_ENTRY(0x141), TBL_ENTRY(0x142), TBL_ENTRY(0x143), - TBL_ENTRY(0x144), TBL_ENTRY(0x145), TBL_ENTRY(0x146), TBL_ENTRY(0x147), - TBL_ENTRY(0x148), TBL_ENTRY(0x149), TBL_ENTRY(0x14a), TBL_ENTRY(0x14b), - TBL_ENTRY(0x14c), TBL_ENTRY(0x14d), TBL_ENTRY(0x14e), TBL_ENTRY(0x14f), - TBL_ENTRY(0x150), TBL_ENTRY(0x151), TBL_ENTRY(0x152), TBL_ENTRY(0x153), - TBL_ENTRY(0x154), TBL_ENTRY(0x155), TBL_ENTRY(0x156), TBL_ENTRY(0x157), - TBL_ENTRY(0x158), TBL_ENTRY(0x159), TBL_ENTRY(0x15a), TBL_ENTRY(0x15b), - TBL_ENTRY(0x15c), TBL_ENTRY(0x15d), TBL_ENTRY(0x15e), TBL_ENTRY(0x15f), - TBL_ENTRY(0x160), TBL_ENTRY(0x161), TBL_ENTRY(0x162), TBL_ENTRY(0x163), - TBL_ENTRY(0x164), TBL_ENTRY(0x165), TBL_ENTRY(0x166), TBL_ENTRY(0x167), - TBL_ENTRY(0x168), TBL_ENTRY(0x169), TBL_ENTRY(0x16a), TBL_ENTRY(0x16b), - TBL_ENTRY(0x16c), TBL_ENTRY(0x16d), TBL_ENTRY(0x16e), TBL_ENTRY(0x16f), - TBL_ENTRY(0x170), TBL_ENTRY(0x171), TBL_ENTRY(0x172), TBL_ENTRY(0x173), - TBL_ENTRY(0x174), TBL_ENTRY(0x175), TBL_ENTRY(0x176), TBL_ENTRY(0x177), - TBL_ENTRY(0x178), TBL_ENTRY(0x179), TBL_ENTRY(0x17a), TBL_ENTRY(0x17b), - TBL_ENTRY(0x17c), TBL_ENTRY(0x17d), TBL_ENTRY(0x17e), TBL_ENTRY(0x17f), - TBL_ENTRY(0x180), TBL_ENTRY(0x181), TBL_ENTRY(0x182), TBL_ENTRY(0x183), - TBL_ENTRY(0x184), TBL_ENTRY(0x185), TBL_ENTRY(0x186), TBL_ENTRY(0x187), - TBL_ENTRY(0x188), TBL_ENTRY(0x189), TBL_ENTRY(0x18a), TBL_ENTRY(0x18b), - TBL_ENTRY(0x18c), TBL_ENTRY(0x18d), TBL_ENTRY(0x18e), TBL_ENTRY(0x18f), - TBL_ENTRY(0x190), TBL_ENTRY(0x191), TBL_ENTRY(0x192), TBL_ENTRY(0x193), - TBL_ENTRY(0x194), TBL_ENTRY(0x195), TBL_ENTRY(0x196), TBL_ENTRY(0x197), - TBL_ENTRY(0x198), TBL_ENTRY(0x199), TBL_ENTRY(0x19a), TBL_ENTRY(0x19b), - TBL_ENTRY(0x19c), TBL_ENTRY(0x19d), TBL_ENTRY(0x19e), TBL_ENTRY(0x19f), - TBL_ENTRY(0x1a0), TBL_ENTRY(0x1a1), TBL_ENTRY(0x1a2), TBL_ENTRY(0x1a3), - TBL_ENTRY(0x1a4), TBL_ENTRY(0x1a5), TBL_ENTRY(0x1a6), TBL_ENTRY(0x1a7), - TBL_ENTRY(0x1a8), TBL_ENTRY(0x1a9), TBL_ENTRY(0x1aa), TBL_ENTRY(0x1ab), - TBL_ENTRY(0x1ac), TBL_ENTRY(0x1ad), TBL_ENTRY(0x1ae), TBL_ENTRY(0x1af), - TBL_ENTRY(0x1b0), TBL_ENTRY(0x1b1), TBL_ENTRY(0x1b2), TBL_ENTRY(0x1b3), - TBL_ENTRY(0x1b4), TBL_ENTRY(0x1b5), TBL_ENTRY(0x1b6), TBL_ENTRY(0x1b7), - TBL_ENTRY(0x1b8), TBL_ENTRY(0x1b9), TBL_ENTRY(0x1ba), TBL_ENTRY(0x1bb), - TBL_ENTRY(0x1bc), TBL_ENTRY(0x1bd), TBL_ENTRY(0x1be), TBL_ENTRY(0x1bf), - TBL_ENTRY(0x1c0), TBL_ENTRY(0x1c1), TBL_ENTRY(0x1c2), TBL_ENTRY(0x1c3), - TBL_ENTRY(0x1c4), TBL_ENTRY(0x1c5), TBL_ENTRY(0x1c6), TBL_ENTRY(0x1c7), - TBL_ENTRY(0x1c8), TBL_ENTRY(0x1c9), TBL_ENTRY(0x1ca), TBL_ENTRY(0x1cb), - TBL_ENTRY(0x1cc), TBL_ENTRY(0x1cd), TBL_ENTRY(0x1ce), TBL_ENTRY(0x1cf), - TBL_ENTRY(0x1d0), TBL_ENTRY(0x1d1), TBL_ENTRY(0x1d2), TBL_ENTRY(0x1d3), - TBL_ENTRY(0x1d4), TBL_ENTRY(0x1d5), TBL_ENTRY(0x1d6), TBL_ENTRY(0x1d7), - TBL_ENTRY(0x1d8), TBL_ENTRY(0x1d9), TBL_ENTRY(0x1da), TBL_ENTRY(0x1db), - TBL_ENTRY(0x1dc), TBL_ENTRY(0x1dd), TBL_ENTRY(0x1de), TBL_ENTRY(0x1df), - TBL_ENTRY(0x1e0), TBL_ENTRY(0x1e1), TBL_ENTRY(0x1e2), TBL_ENTRY(0x1e3), - TBL_ENTRY(0x1e4), TBL_ENTRY(0x1e5), TBL_ENTRY(0x1e6), TBL_ENTRY(0x1e7), - TBL_ENTRY(0x1e8), TBL_ENTRY(0x1e9), TBL_ENTRY(0x1ea), TBL_ENTRY(0x1eb), - TBL_ENTRY(0x1ec), TBL_ENTRY(0x1ed), TBL_ENTRY(0x1ee), TBL_ENTRY(0x1ef), - TBL_ENTRY(0x1f0), TBL_ENTRY(0x1f1), TBL_ENTRY(0x1f2), TBL_ENTRY(0x1f3), - TBL_ENTRY(0x1f4), TBL_ENTRY(0x1f5), TBL_ENTRY(0x1f6), TBL_ENTRY(0x1f7), - TBL_ENTRY(0x1f8), TBL_ENTRY(0x1f9), TBL_ENTRY(0x1fa), TBL_ENTRY(0x1fb), - TBL_ENTRY(0x1fc), TBL_ENTRY(0x1fd), TBL_ENTRY(0x1fe), TBL_ENTRY(0x1ff), - TBL_ENTRY(0x200), TBL_ENTRY(0x201), TBL_ENTRY(0x202), TBL_ENTRY(0x203), - TBL_ENTRY(0x204), TBL_ENTRY(0x205), TBL_ENTRY(0x206), TBL_ENTRY(0x207), - TBL_ENTRY(0x208), TBL_ENTRY(0x209), TBL_ENTRY(0x20a), TBL_ENTRY(0x20b), - TBL_ENTRY(0x20c), TBL_ENTRY(0x20d), TBL_ENTRY(0x20e), TBL_ENTRY(0x20f), - TBL_ENTRY(0x210), TBL_ENTRY(0x211), TBL_ENTRY(0x212), TBL_ENTRY(0x213), - TBL_ENTRY(0x214), TBL_ENTRY(0x215), TBL_ENTRY(0x216), TBL_ENTRY(0x217), - TBL_ENTRY(0x218), TBL_ENTRY(0x219), TBL_ENTRY(0x21a), TBL_ENTRY(0x21b), - TBL_ENTRY(0x21c), TBL_ENTRY(0x21d), TBL_ENTRY(0x21e), TBL_ENTRY(0x21f), - TBL_ENTRY(0x220), TBL_ENTRY(0x221), TBL_ENTRY(0x222), TBL_ENTRY(0x223), - TBL_ENTRY(0x224), TBL_ENTRY(0x225), TBL_ENTRY(0x226), TBL_ENTRY(0x227), - TBL_ENTRY(0x228), TBL_ENTRY(0x229), TBL_ENTRY(0x22a), TBL_ENTRY(0x22b), - TBL_ENTRY(0x22c), TBL_ENTRY(0x22d), TBL_ENTRY(0x22e), TBL_ENTRY(0x22f), - TBL_ENTRY(0x230), TBL_ENTRY(0x231), TBL_ENTRY(0x232), TBL_ENTRY(0x233), - TBL_ENTRY(0x234), TBL_ENTRY(0x235), TBL_ENTRY(0x236), TBL_ENTRY(0x237), - TBL_ENTRY(0x238), TBL_ENTRY(0x239), TBL_ENTRY(0x23a), TBL_ENTRY(0x23b), - TBL_ENTRY(0x23c), TBL_ENTRY(0x23d), TBL_ENTRY(0x23e), TBL_ENTRY(0x23f), - TBL_ENTRY(0x240), TBL_ENTRY(0x241), TBL_ENTRY(0x242), TBL_ENTRY(0x243), - TBL_ENTRY(0x244), TBL_ENTRY(0x245), TBL_ENTRY(0x246), TBL_ENTRY(0x247), - TBL_ENTRY(0x248), TBL_ENTRY(0x249), TBL_ENTRY(0x24a), TBL_ENTRY(0x24b), - TBL_ENTRY(0x24c), TBL_ENTRY(0x24d), TBL_ENTRY(0x24e), TBL_ENTRY(0x24f), - TBL_ENTRY(0x250), TBL_ENTRY(0x251), TBL_ENTRY(0x252), TBL_ENTRY(0x253), - TBL_ENTRY(0x254), TBL_ENTRY(0x255), TBL_ENTRY(0x256), TBL_ENTRY(0x257), - TBL_ENTRY(0x258), TBL_ENTRY(0x259), TBL_ENTRY(0x25a), TBL_ENTRY(0x25b), - TBL_ENTRY(0x25c), TBL_ENTRY(0x25d), TBL_ENTRY(0x25e), TBL_ENTRY(0x25f), - TBL_ENTRY(0x260), TBL_ENTRY(0x261), TBL_ENTRY(0x262), TBL_ENTRY(0x263), - TBL_ENTRY(0x264), TBL_ENTRY(0x265), TBL_ENTRY(0x266), TBL_ENTRY(0x267), - TBL_ENTRY(0x268), TBL_ENTRY(0x269), TBL_ENTRY(0x26a), TBL_ENTRY(0x26b), - TBL_ENTRY(0x26c), TBL_ENTRY(0x26d), TBL_ENTRY(0x26e), TBL_ENTRY(0x26f), - TBL_ENTRY(0x270), TBL_ENTRY(0x271), TBL_ENTRY(0x272), TBL_ENTRY(0x273), - TBL_ENTRY(0x274), TBL_ENTRY(0x275), TBL_ENTRY(0x276), TBL_ENTRY(0x277), - TBL_ENTRY(0x278), TBL_ENTRY(0x279), TBL_ENTRY(0x27a), TBL_ENTRY(0x27b), - TBL_ENTRY(0x27c), TBL_ENTRY(0x27d), TBL_ENTRY(0x27e), TBL_ENTRY(0x27f), - TBL_ENTRY(0x280), TBL_ENTRY(0x281), TBL_ENTRY(0x282), TBL_ENTRY(0x283), - TBL_ENTRY(0x284), TBL_ENTRY(0x285), TBL_ENTRY(0x286), TBL_ENTRY(0x287), - TBL_ENTRY(0x288), TBL_ENTRY(0x289), TBL_ENTRY(0x28a), TBL_ENTRY(0x28b), - TBL_ENTRY(0x28c), TBL_ENTRY(0x28d), TBL_ENTRY(0x28e), TBL_ENTRY(0x28f), - TBL_ENTRY(0x290), TBL_ENTRY(0x291), TBL_ENTRY(0x292), TBL_ENTRY(0x293), - TBL_ENTRY(0x294), TBL_ENTRY(0x295), TBL_ENTRY(0x296), TBL_ENTRY(0x297), - TBL_ENTRY(0x298), TBL_ENTRY(0x299), TBL_ENTRY(0x29a), TBL_ENTRY(0x29b), - TBL_ENTRY(0x29c), TBL_ENTRY(0x29d), TBL_ENTRY(0x29e), TBL_ENTRY(0x29f), - TBL_ENTRY(0x2a0), TBL_ENTRY(0x2a1), TBL_ENTRY(0x2a2), TBL_ENTRY(0x2a3), - TBL_ENTRY(0x2a4), TBL_ENTRY(0x2a5), TBL_ENTRY(0x2a6), TBL_ENTRY(0x2a7), - TBL_ENTRY(0x2a8), TBL_ENTRY(0x2a9), TBL_ENTRY(0x2aa), TBL_ENTRY(0x2ab), - TBL_ENTRY(0x2ac), TBL_ENTRY(0x2ad), TBL_ENTRY(0x2ae), TBL_ENTRY(0x2af), - TBL_ENTRY(0x2b0), TBL_ENTRY(0x2b1), TBL_ENTRY(0x2b2), TBL_ENTRY(0x2b3), - TBL_ENTRY(0x2b4), TBL_ENTRY(0x2b5), TBL_ENTRY(0x2b6), TBL_ENTRY(0x2b7), - TBL_ENTRY(0x2b8), TBL_ENTRY(0x2b9), TBL_ENTRY(0x2ba), TBL_ENTRY(0x2bb), - TBL_ENTRY(0x2bc), TBL_ENTRY(0x2bd), TBL_ENTRY(0x2be), TBL_ENTRY(0x2bf), - TBL_ENTRY(0x2c0), TBL_ENTRY(0x2c1), TBL_ENTRY(0x2c2), TBL_ENTRY(0x2c3), - TBL_ENTRY(0x2c4), TBL_ENTRY(0x2c5), TBL_ENTRY(0x2c6), TBL_ENTRY(0x2c7), - TBL_ENTRY(0x2c8), TBL_ENTRY(0x2c9), TBL_ENTRY(0x2ca), TBL_ENTRY(0x2cb), - TBL_ENTRY(0x2cc), TBL_ENTRY(0x2cd), TBL_ENTRY(0x2ce), TBL_ENTRY(0x2cf), - TBL_ENTRY(0x2d0), TBL_ENTRY(0x2d1), TBL_ENTRY(0x2d2), TBL_ENTRY(0x2d3), - TBL_ENTRY(0x2d4), TBL_ENTRY(0x2d5), TBL_ENTRY(0x2d6), TBL_ENTRY(0x2d7), - TBL_ENTRY(0x2d8), TBL_ENTRY(0x2d9), TBL_ENTRY(0x2da), TBL_ENTRY(0x2db), - TBL_ENTRY(0x2dc), TBL_ENTRY(0x2dd), TBL_ENTRY(0x2de), TBL_ENTRY(0x2df), - TBL_ENTRY(0x2e0), TBL_ENTRY(0x2e1), TBL_ENTRY(0x2e2), TBL_ENTRY(0x2e3), - TBL_ENTRY(0x2e4), TBL_ENTRY(0x2e5), TBL_ENTRY(0x2e6), TBL_ENTRY(0x2e7), - TBL_ENTRY(0x2e8), TBL_ENTRY(0x2e9), TBL_ENTRY(0x2ea), TBL_ENTRY(0x2eb), - TBL_ENTRY(0x2ec), TBL_ENTRY(0x2ed), TBL_ENTRY(0x2ee), TBL_ENTRY(0x2ef), - TBL_ENTRY(0x2f0), TBL_ENTRY(0x2f1), TBL_ENTRY(0x2f2), TBL_ENTRY(0x2f3), - TBL_ENTRY(0x2f4), TBL_ENTRY(0x2f5), TBL_ENTRY(0x2f6), TBL_ENTRY(0x2f7), - TBL_ENTRY(0x2f8), TBL_ENTRY(0x2f9), TBL_ENTRY(0x2fa), TBL_ENTRY(0x2fb), - TBL_ENTRY(0x2fc), TBL_ENTRY(0x2fd), TBL_ENTRY(0x2fe), TBL_ENTRY(0x2ff), - TBL_ENTRY(0x300), TBL_ENTRY(0x301), TBL_ENTRY(0x302), TBL_ENTRY(0x303), - TBL_ENTRY(0x304), TBL_ENTRY(0x305), TBL_ENTRY(0x306), TBL_ENTRY(0x307), - TBL_ENTRY(0x308), TBL_ENTRY(0x309), TBL_ENTRY(0x30a), TBL_ENTRY(0x30b), - TBL_ENTRY(0x30c), TBL_ENTRY(0x30d), TBL_ENTRY(0x30e), TBL_ENTRY(0x30f), - TBL_ENTRY(0x310), TBL_ENTRY(0x311), TBL_ENTRY(0x312), TBL_ENTRY(0x313), - TBL_ENTRY(0x314), TBL_ENTRY(0x315), TBL_ENTRY(0x316), TBL_ENTRY(0x317), - TBL_ENTRY(0x318), TBL_ENTRY(0x319), TBL_ENTRY(0x31a), TBL_ENTRY(0x31b), - TBL_ENTRY(0x31c), TBL_ENTRY(0x31d), TBL_ENTRY(0x31e), TBL_ENTRY(0x31f), - TBL_ENTRY(0x320), TBL_ENTRY(0x321), TBL_ENTRY(0x322), TBL_ENTRY(0x323), - TBL_ENTRY(0x324), TBL_ENTRY(0x325), TBL_ENTRY(0x326), TBL_ENTRY(0x327), - TBL_ENTRY(0x328), TBL_ENTRY(0x329), TBL_ENTRY(0x32a), TBL_ENTRY(0x32b), - TBL_ENTRY(0x32c), TBL_ENTRY(0x32d), TBL_ENTRY(0x32e), TBL_ENTRY(0x32f), - TBL_ENTRY(0x330), TBL_ENTRY(0x331), TBL_ENTRY(0x332), TBL_ENTRY(0x333), - TBL_ENTRY(0x334), TBL_ENTRY(0x335), TBL_ENTRY(0x336), TBL_ENTRY(0x337), - TBL_ENTRY(0x338), TBL_ENTRY(0x339), TBL_ENTRY(0x33a), TBL_ENTRY(0x33b), - TBL_ENTRY(0x33c), TBL_ENTRY(0x33d), TBL_ENTRY(0x33e), TBL_ENTRY(0x33f), - TBL_ENTRY(0x340), TBL_ENTRY(0x341), TBL_ENTRY(0x342), TBL_ENTRY(0x343), - TBL_ENTRY(0x344), TBL_ENTRY(0x345), TBL_ENTRY(0x346), TBL_ENTRY(0x347), - TBL_ENTRY(0x348), TBL_ENTRY(0x349), TBL_ENTRY(0x34a), TBL_ENTRY(0x34b), - TBL_ENTRY(0x34c), TBL_ENTRY(0x34d), TBL_ENTRY(0x34e), TBL_ENTRY(0x34f), - TBL_ENTRY(0x350), TBL_ENTRY(0x351), TBL_ENTRY(0x352), TBL_ENTRY(0x353), - TBL_ENTRY(0x354), TBL_ENTRY(0x355), TBL_ENTRY(0x356), TBL_ENTRY(0x357), - TBL_ENTRY(0x358), TBL_ENTRY(0x359), TBL_ENTRY(0x35a), TBL_ENTRY(0x35b), - TBL_ENTRY(0x35c), TBL_ENTRY(0x35d), TBL_ENTRY(0x35e), TBL_ENTRY(0x35f), - TBL_ENTRY(0x360), TBL_ENTRY(0x361), TBL_ENTRY(0x362), TBL_ENTRY(0x363), - TBL_ENTRY(0x364), TBL_ENTRY(0x365), TBL_ENTRY(0x366), TBL_ENTRY(0x367), - TBL_ENTRY(0x368), TBL_ENTRY(0x369), TBL_ENTRY(0x36a), TBL_ENTRY(0x36b), - TBL_ENTRY(0x36c), TBL_ENTRY(0x36d), TBL_ENTRY(0x36e), TBL_ENTRY(0x36f), - TBL_ENTRY(0x370), TBL_ENTRY(0x371), TBL_ENTRY(0x372), TBL_ENTRY(0x373), - TBL_ENTRY(0x374), TBL_ENTRY(0x375), TBL_ENTRY(0x376), TBL_ENTRY(0x377), - TBL_ENTRY(0x378), TBL_ENTRY(0x379), TBL_ENTRY(0x37a), TBL_ENTRY(0x37b), - TBL_ENTRY(0x37c), TBL_ENTRY(0x37d), TBL_ENTRY(0x37e), TBL_ENTRY(0x37f), - TBL_ENTRY(0x380), TBL_ENTRY(0x381), TBL_ENTRY(0x382), TBL_ENTRY(0x383), - TBL_ENTRY(0x384), TBL_ENTRY(0x385), TBL_ENTRY(0x386), TBL_ENTRY(0x387), - TBL_ENTRY(0x388), TBL_ENTRY(0x389), TBL_ENTRY(0x38a), TBL_ENTRY(0x38b), - TBL_ENTRY(0x38c), TBL_ENTRY(0x38d), TBL_ENTRY(0x38e), TBL_ENTRY(0x38f), - TBL_ENTRY(0x390), TBL_ENTRY(0x391), TBL_ENTRY(0x392), TBL_ENTRY(0x393), - TBL_ENTRY(0x394), TBL_ENTRY(0x395), TBL_ENTRY(0x396), TBL_ENTRY(0x397), - TBL_ENTRY(0x398), TBL_ENTRY(0x399), TBL_ENTRY(0x39a), TBL_ENTRY(0x39b), - TBL_ENTRY(0x39c), TBL_ENTRY(0x39d), TBL_ENTRY(0x39e), TBL_ENTRY(0x39f), - TBL_ENTRY(0x3a0), TBL_ENTRY(0x3a1), TBL_ENTRY(0x3a2), TBL_ENTRY(0x3a3), - TBL_ENTRY(0x3a4), TBL_ENTRY(0x3a5), TBL_ENTRY(0x3a6), TBL_ENTRY(0x3a7), - TBL_ENTRY(0x3a8), TBL_ENTRY(0x3a9), TBL_ENTRY(0x3aa), TBL_ENTRY(0x3ab), - TBL_ENTRY(0x3ac), TBL_ENTRY(0x3ad), TBL_ENTRY(0x3ae), TBL_ENTRY(0x3af), - TBL_ENTRY(0x3b0), TBL_ENTRY(0x3b1), TBL_ENTRY(0x3b2), TBL_ENTRY(0x3b3), - TBL_ENTRY(0x3b4), TBL_ENTRY(0x3b5), TBL_ENTRY(0x3b6), TBL_ENTRY(0x3b7), - TBL_ENTRY(0x3b8), TBL_ENTRY(0x3b9), TBL_ENTRY(0x3ba), TBL_ENTRY(0x3bb), - TBL_ENTRY(0x3bc), TBL_ENTRY(0x3bd), TBL_ENTRY(0x3be), TBL_ENTRY(0x3bf), - TBL_ENTRY(0x3c0), TBL_ENTRY(0x3c1), TBL_ENTRY(0x3c2), TBL_ENTRY(0x3c3), - TBL_ENTRY(0x3c4), TBL_ENTRY(0x3c5), TBL_ENTRY(0x3c6), TBL_ENTRY(0x3c7), - TBL_ENTRY(0x3c8), TBL_ENTRY(0x3c9), TBL_ENTRY(0x3ca), TBL_ENTRY(0x3cb), - TBL_ENTRY(0x3cc), TBL_ENTRY(0x3cd), TBL_ENTRY(0x3ce), TBL_ENTRY(0x3cf), - TBL_ENTRY(0x3d0), TBL_ENTRY(0x3d1), TBL_ENTRY(0x3d2), TBL_ENTRY(0x3d3), - TBL_ENTRY(0x3d4), TBL_ENTRY(0x3d5), TBL_ENTRY(0x3d6), TBL_ENTRY(0x3d7), - TBL_ENTRY(0x3d8), TBL_ENTRY(0x3d9), TBL_ENTRY(0x3da), TBL_ENTRY(0x3db), - TBL_ENTRY(0x3dc), TBL_ENTRY(0x3dd), TBL_ENTRY(0x3de), TBL_ENTRY(0x3df), - TBL_ENTRY(0x3e0), TBL_ENTRY(0x3e1), TBL_ENTRY(0x3e2), TBL_ENTRY(0x3e3), - TBL_ENTRY(0x3e4), TBL_ENTRY(0x3e5), TBL_ENTRY(0x3e6), TBL_ENTRY(0x3e7), - TBL_ENTRY(0x3e8), TBL_ENTRY(0x3e9), TBL_ENTRY(0x3ea), TBL_ENTRY(0x3eb), - TBL_ENTRY(0x3ec), TBL_ENTRY(0x3ed), TBL_ENTRY(0x3ee), TBL_ENTRY(0x3ef), - TBL_ENTRY(0x3f0), TBL_ENTRY(0x3f1), TBL_ENTRY(0x3f2), TBL_ENTRY(0x3f3), - TBL_ENTRY(0x3f4), TBL_ENTRY(0x3f5), TBL_ENTRY(0x3f6), TBL_ENTRY(0x3f7), - TBL_ENTRY(0x3f8), TBL_ENTRY(0x3f9), TBL_ENTRY(0x3fa), TBL_ENTRY(0x3fb), - TBL_ENTRY(0x3fc), TBL_ENTRY(0x3fd), TBL_ENTRY(0x3fe), TBL_ENTRY(0x3ff), - TBL_ENTRY(0x400), TBL_ENTRY(0x401), TBL_ENTRY(0x402), TBL_ENTRY(0x403), - TBL_ENTRY(0x404), TBL_ENTRY(0x405), TBL_ENTRY(0x406), TBL_ENTRY(0x407), - TBL_ENTRY(0x408), TBL_ENTRY(0x409), TBL_ENTRY(0x40a), TBL_ENTRY(0x40b), - TBL_ENTRY(0x40c), TBL_ENTRY(0x40d), TBL_ENTRY(0x40e), TBL_ENTRY(0x40f), - TBL_ENTRY(0x410), TBL_ENTRY(0x411), TBL_ENTRY(0x412), TBL_ENTRY(0x413), - TBL_ENTRY(0x414), TBL_ENTRY(0x415), TBL_ENTRY(0x416), TBL_ENTRY(0x417), - TBL_ENTRY(0x418), TBL_ENTRY(0x419), TBL_ENTRY(0x41a), TBL_ENTRY(0x41b), - TBL_ENTRY(0x41c), TBL_ENTRY(0x41d), TBL_ENTRY(0x41e), TBL_ENTRY(0x41f), - TBL_ENTRY(0x420), TBL_ENTRY(0x421), TBL_ENTRY(0x422), TBL_ENTRY(0x423), - TBL_ENTRY(0x424), TBL_ENTRY(0x425), TBL_ENTRY(0x426), TBL_ENTRY(0x427), - TBL_ENTRY(0x428), TBL_ENTRY(0x429), TBL_ENTRY(0x42a), TBL_ENTRY(0x42b), - TBL_ENTRY(0x42c), TBL_ENTRY(0x42d), TBL_ENTRY(0x42e), TBL_ENTRY(0x42f), - TBL_ENTRY(0x430), TBL_ENTRY(0x431), TBL_ENTRY(0x432), TBL_ENTRY(0x433), - TBL_ENTRY(0x434), TBL_ENTRY(0x435), TBL_ENTRY(0x436), TBL_ENTRY(0x437), - TBL_ENTRY(0x438), TBL_ENTRY(0x439), TBL_ENTRY(0x43a), TBL_ENTRY(0x43b), - TBL_ENTRY(0x43c), TBL_ENTRY(0x43d), TBL_ENTRY(0x43e), TBL_ENTRY(0x43f), - TBL_ENTRY(0x440), TBL_ENTRY(0x441), TBL_ENTRY(0x442), TBL_ENTRY(0x443), - TBL_ENTRY(0x444), TBL_ENTRY(0x445), TBL_ENTRY(0x446), TBL_ENTRY(0x447), - TBL_ENTRY(0x448), TBL_ENTRY(0x449), TBL_ENTRY(0x44a), TBL_ENTRY(0x44b), - TBL_ENTRY(0x44c), TBL_ENTRY(0x44d), TBL_ENTRY(0x44e), TBL_ENTRY(0x44f), - TBL_ENTRY(0x450), TBL_ENTRY(0x451), TBL_ENTRY(0x452), TBL_ENTRY(0x453), - TBL_ENTRY(0x454), TBL_ENTRY(0x455), TBL_ENTRY(0x456), TBL_ENTRY(0x457), - TBL_ENTRY(0x458), TBL_ENTRY(0x459), TBL_ENTRY(0x45a), TBL_ENTRY(0x45b), - TBL_ENTRY(0x45c), TBL_ENTRY(0x45d), TBL_ENTRY(0x45e), TBL_ENTRY(0x45f), - TBL_ENTRY(0x460), TBL_ENTRY(0x461), TBL_ENTRY(0x462), TBL_ENTRY(0x463), - TBL_ENTRY(0x464), TBL_ENTRY(0x465), TBL_ENTRY(0x466), TBL_ENTRY(0x467), - TBL_ENTRY(0x468), TBL_ENTRY(0x469), TBL_ENTRY(0x46a), TBL_ENTRY(0x46b), - TBL_ENTRY(0x46c), TBL_ENTRY(0x46d), TBL_ENTRY(0x46e), TBL_ENTRY(0x46f), - TBL_ENTRY(0x470), TBL_ENTRY(0x471), TBL_ENTRY(0x472), TBL_ENTRY(0x473), - TBL_ENTRY(0x474), TBL_ENTRY(0x475), TBL_ENTRY(0x476), TBL_ENTRY(0x477), - TBL_ENTRY(0x478), TBL_ENTRY(0x479), TBL_ENTRY(0x47a), TBL_ENTRY(0x47b), - TBL_ENTRY(0x47c), TBL_ENTRY(0x47d), TBL_ENTRY(0x47e), TBL_ENTRY(0x47f), - TBL_ENTRY(0x480), TBL_ENTRY(0x481), TBL_ENTRY(0x482), TBL_ENTRY(0x483), - TBL_ENTRY(0x484), TBL_ENTRY(0x485), TBL_ENTRY(0x486), TBL_ENTRY(0x487), - TBL_ENTRY(0x488), TBL_ENTRY(0x489), TBL_ENTRY(0x48a), TBL_ENTRY(0x48b), - TBL_ENTRY(0x48c), TBL_ENTRY(0x48d), TBL_ENTRY(0x48e), TBL_ENTRY(0x48f), - TBL_ENTRY(0x490), TBL_ENTRY(0x491), TBL_ENTRY(0x492), TBL_ENTRY(0x493), - TBL_ENTRY(0x494), TBL_ENTRY(0x495), TBL_ENTRY(0x496), TBL_ENTRY(0x497), - TBL_ENTRY(0x498), TBL_ENTRY(0x499), TBL_ENTRY(0x49a), TBL_ENTRY(0x49b), - TBL_ENTRY(0x49c), TBL_ENTRY(0x49d), TBL_ENTRY(0x49e), TBL_ENTRY(0x49f), - TBL_ENTRY(0x4a0), TBL_ENTRY(0x4a1), TBL_ENTRY(0x4a2), TBL_ENTRY(0x4a3), - TBL_ENTRY(0x4a4), TBL_ENTRY(0x4a5), TBL_ENTRY(0x4a6), TBL_ENTRY(0x4a7), - TBL_ENTRY(0x4a8), TBL_ENTRY(0x4a9), TBL_ENTRY(0x4aa), TBL_ENTRY(0x4ab), - TBL_ENTRY(0x4ac), TBL_ENTRY(0x4ad), TBL_ENTRY(0x4ae), TBL_ENTRY(0x4af), - TBL_ENTRY(0x4b0), TBL_ENTRY(0x4b1), TBL_ENTRY(0x4b2), TBL_ENTRY(0x4b3), - TBL_ENTRY(0x4b4), TBL_ENTRY(0x4b5), TBL_ENTRY(0x4b6), TBL_ENTRY(0x4b7), - TBL_ENTRY(0x4b8), TBL_ENTRY(0x4b9), TBL_ENTRY(0x4ba), TBL_ENTRY(0x4bb), - TBL_ENTRY(0x4bc), TBL_ENTRY(0x4bd), TBL_ENTRY(0x4be), TBL_ENTRY(0x4bf), - TBL_ENTRY(0x4c0), TBL_ENTRY(0x4c1), TBL_ENTRY(0x4c2), TBL_ENTRY(0x4c3), - TBL_ENTRY(0x4c4), TBL_ENTRY(0x4c5), TBL_ENTRY(0x4c6), TBL_ENTRY(0x4c7), - TBL_ENTRY(0x4c8), TBL_ENTRY(0x4c9), TBL_ENTRY(0x4ca), TBL_ENTRY(0x4cb), - TBL_ENTRY(0x4cc), TBL_ENTRY(0x4cd), TBL_ENTRY(0x4ce), TBL_ENTRY(0x4cf), - TBL_ENTRY(0x4d0), TBL_ENTRY(0x4d1), TBL_ENTRY(0x4d2), TBL_ENTRY(0x4d3), - TBL_ENTRY(0x4d4), TBL_ENTRY(0x4d5), TBL_ENTRY(0x4d6), TBL_ENTRY(0x4d7), - TBL_ENTRY(0x4d8), TBL_ENTRY(0x4d9), TBL_ENTRY(0x4da), TBL_ENTRY(0x4db), - TBL_ENTRY(0x4dc), TBL_ENTRY(0x4dd), TBL_ENTRY(0x4de), TBL_ENTRY(0x4df), - TBL_ENTRY(0x4e0), TBL_ENTRY(0x4e1), TBL_ENTRY(0x4e2), TBL_ENTRY(0x4e3), - TBL_ENTRY(0x4e4), TBL_ENTRY(0x4e5), TBL_ENTRY(0x4e6), TBL_ENTRY(0x4e7), - TBL_ENTRY(0x4e8), TBL_ENTRY(0x4e9), TBL_ENTRY(0x4ea), TBL_ENTRY(0x4eb), - TBL_ENTRY(0x4ec), TBL_ENTRY(0x4ed), TBL_ENTRY(0x4ee), TBL_ENTRY(0x4ef), - TBL_ENTRY(0x4f0), TBL_ENTRY(0x4f1), TBL_ENTRY(0x4f2), TBL_ENTRY(0x4f3), - TBL_ENTRY(0x4f4), TBL_ENTRY(0x4f5), TBL_ENTRY(0x4f6), TBL_ENTRY(0x4f7), - TBL_ENTRY(0x4f8), TBL_ENTRY(0x4f9), TBL_ENTRY(0x4fa), TBL_ENTRY(0x4fb), - TBL_ENTRY(0x4fc), TBL_ENTRY(0x4fd), TBL_ENTRY(0x4fe), TBL_ENTRY(0x4ff), - TBL_ENTRY(0x500), TBL_ENTRY(0x501), TBL_ENTRY(0x502), TBL_ENTRY(0x503), - TBL_ENTRY(0x504), TBL_ENTRY(0x505), TBL_ENTRY(0x506), TBL_ENTRY(0x507), - TBL_ENTRY(0x508), TBL_ENTRY(0x509), TBL_ENTRY(0x50a), TBL_ENTRY(0x50b), - TBL_ENTRY(0x50c), TBL_ENTRY(0x50d), TBL_ENTRY(0x50e), TBL_ENTRY(0x50f), - TBL_ENTRY(0x510), TBL_ENTRY(0x511), TBL_ENTRY(0x512), TBL_ENTRY(0x513), - TBL_ENTRY(0x514), TBL_ENTRY(0x515), TBL_ENTRY(0x516), TBL_ENTRY(0x517), - TBL_ENTRY(0x518), TBL_ENTRY(0x519), TBL_ENTRY(0x51a), TBL_ENTRY(0x51b), - TBL_ENTRY(0x51c), TBL_ENTRY(0x51d), TBL_ENTRY(0x51e), TBL_ENTRY(0x51f), - TBL_ENTRY(0x520), TBL_ENTRY(0x521), TBL_ENTRY(0x522), TBL_ENTRY(0x523), - TBL_ENTRY(0x524), TBL_ENTRY(0x525), TBL_ENTRY(0x526), TBL_ENTRY(0x527), - TBL_ENTRY(0x528), TBL_ENTRY(0x529), TBL_ENTRY(0x52a), TBL_ENTRY(0x52b), - TBL_ENTRY(0x52c), TBL_ENTRY(0x52d), TBL_ENTRY(0x52e), TBL_ENTRY(0x52f), - TBL_ENTRY(0x530), TBL_ENTRY(0x531), TBL_ENTRY(0x532), TBL_ENTRY(0x533), - TBL_ENTRY(0x534), TBL_ENTRY(0x535), TBL_ENTRY(0x536), TBL_ENTRY(0x537), - TBL_ENTRY(0x538), TBL_ENTRY(0x539), TBL_ENTRY(0x53a), TBL_ENTRY(0x53b), - TBL_ENTRY(0x53c), TBL_ENTRY(0x53d), TBL_ENTRY(0x53e), TBL_ENTRY(0x53f), - TBL_ENTRY(0x540), TBL_ENTRY(0x541), TBL_ENTRY(0x542), TBL_ENTRY(0x543), - TBL_ENTRY(0x544), TBL_ENTRY(0x545), TBL_ENTRY(0x546), TBL_ENTRY(0x547), - TBL_ENTRY(0x548), TBL_ENTRY(0x549), TBL_ENTRY(0x54a), TBL_ENTRY(0x54b), - TBL_ENTRY(0x54c), TBL_ENTRY(0x54d), TBL_ENTRY(0x54e), TBL_ENTRY(0x54f), - TBL_ENTRY(0x550), TBL_ENTRY(0x551), TBL_ENTRY(0x552), TBL_ENTRY(0x553), - TBL_ENTRY(0x554), TBL_ENTRY(0x555), TBL_ENTRY(0x556), TBL_ENTRY(0x557), - TBL_ENTRY(0x558), TBL_ENTRY(0x559), TBL_ENTRY(0x55a), TBL_ENTRY(0x55b), - TBL_ENTRY(0x55c), TBL_ENTRY(0x55d), TBL_ENTRY(0x55e), TBL_ENTRY(0x55f), - TBL_ENTRY(0x560), TBL_ENTRY(0x561), TBL_ENTRY(0x562), TBL_ENTRY(0x563), - TBL_ENTRY(0x564), TBL_ENTRY(0x565), TBL_ENTRY(0x566), TBL_ENTRY(0x567), - TBL_ENTRY(0x568), TBL_ENTRY(0x569), TBL_ENTRY(0x56a), TBL_ENTRY(0x56b), - TBL_ENTRY(0x56c), TBL_ENTRY(0x56d), TBL_ENTRY(0x56e), TBL_ENTRY(0x56f), - TBL_ENTRY(0x570), TBL_ENTRY(0x571), TBL_ENTRY(0x572), TBL_ENTRY(0x573), - TBL_ENTRY(0x574), TBL_ENTRY(0x575), TBL_ENTRY(0x576), TBL_ENTRY(0x577), - TBL_ENTRY(0x578), TBL_ENTRY(0x579), TBL_ENTRY(0x57a), TBL_ENTRY(0x57b), - TBL_ENTRY(0x57c), TBL_ENTRY(0x57d), TBL_ENTRY(0x57e), TBL_ENTRY(0x57f), - TBL_ENTRY(0x580), TBL_ENTRY(0x581), TBL_ENTRY(0x582), TBL_ENTRY(0x583), - TBL_ENTRY(0x584), TBL_ENTRY(0x585), TBL_ENTRY(0x586), TBL_ENTRY(0x587), - TBL_ENTRY(0x588), TBL_ENTRY(0x589), TBL_ENTRY(0x58a), TBL_ENTRY(0x58b), - TBL_ENTRY(0x58c), TBL_ENTRY(0x58d), TBL_ENTRY(0x58e), TBL_ENTRY(0x58f), - TBL_ENTRY(0x590), TBL_ENTRY(0x591), TBL_ENTRY(0x592), TBL_ENTRY(0x593), - TBL_ENTRY(0x594), TBL_ENTRY(0x595), TBL_ENTRY(0x596), TBL_ENTRY(0x597), - TBL_ENTRY(0x598), TBL_ENTRY(0x599), TBL_ENTRY(0x59a), TBL_ENTRY(0x59b), - TBL_ENTRY(0x59c), TBL_ENTRY(0x59d), TBL_ENTRY(0x59e), TBL_ENTRY(0x59f), - TBL_ENTRY(0x5a0), TBL_ENTRY(0x5a1), TBL_ENTRY(0x5a2), TBL_ENTRY(0x5a3), - TBL_ENTRY(0x5a4), TBL_ENTRY(0x5a5), TBL_ENTRY(0x5a6), TBL_ENTRY(0x5a7), - TBL_ENTRY(0x5a8), TBL_ENTRY(0x5a9), TBL_ENTRY(0x5aa), TBL_ENTRY(0x5ab), - TBL_ENTRY(0x5ac), TBL_ENTRY(0x5ad), TBL_ENTRY(0x5ae), TBL_ENTRY(0x5af), - TBL_ENTRY(0x5b0), TBL_ENTRY(0x5b1), TBL_ENTRY(0x5b2), TBL_ENTRY(0x5b3), - TBL_ENTRY(0x5b4), TBL_ENTRY(0x5b5), TBL_ENTRY(0x5b6), TBL_ENTRY(0x5b7), - TBL_ENTRY(0x5b8), TBL_ENTRY(0x5b9), TBL_ENTRY(0x5ba), TBL_ENTRY(0x5bb), - TBL_ENTRY(0x5bc), TBL_ENTRY(0x5bd), TBL_ENTRY(0x5be), TBL_ENTRY(0x5bf), - TBL_ENTRY(0x5c0), TBL_ENTRY(0x5c1), TBL_ENTRY(0x5c2), TBL_ENTRY(0x5c3), - TBL_ENTRY(0x5c4), TBL_ENTRY(0x5c5), TBL_ENTRY(0x5c6), TBL_ENTRY(0x5c7), - TBL_ENTRY(0x5c8), TBL_ENTRY(0x5c9), TBL_ENTRY(0x5ca), TBL_ENTRY(0x5cb), - TBL_ENTRY(0x5cc), TBL_ENTRY(0x5cd), TBL_ENTRY(0x5ce), TBL_ENTRY(0x5cf), - TBL_ENTRY(0x5d0), TBL_ENTRY(0x5d1), TBL_ENTRY(0x5d2), TBL_ENTRY(0x5d3), - TBL_ENTRY(0x5d4), TBL_ENTRY(0x5d5), TBL_ENTRY(0x5d6), TBL_ENTRY(0x5d7), - TBL_ENTRY(0x5d8), TBL_ENTRY(0x5d9), TBL_ENTRY(0x5da), TBL_ENTRY(0x5db), - TBL_ENTRY(0x5dc), TBL_ENTRY(0x5dd), TBL_ENTRY(0x5de), TBL_ENTRY(0x5df), - TBL_ENTRY(0x5e0), TBL_ENTRY(0x5e1), TBL_ENTRY(0x5e2), TBL_ENTRY(0x5e3), - TBL_ENTRY(0x5e4), TBL_ENTRY(0x5e5), TBL_ENTRY(0x5e6), TBL_ENTRY(0x5e7), - TBL_ENTRY(0x5e8), TBL_ENTRY(0x5e9), TBL_ENTRY(0x5ea), TBL_ENTRY(0x5eb), - TBL_ENTRY(0x5ec), TBL_ENTRY(0x5ed), TBL_ENTRY(0x5ee), TBL_ENTRY(0x5ef), - TBL_ENTRY(0x5f0), TBL_ENTRY(0x5f1), TBL_ENTRY(0x5f2), TBL_ENTRY(0x5f3), - TBL_ENTRY(0x5f4), TBL_ENTRY(0x5f5), TBL_ENTRY(0x5f6), TBL_ENTRY(0x5f7), - TBL_ENTRY(0x5f8), TBL_ENTRY(0x5f9), TBL_ENTRY(0x5fa), TBL_ENTRY(0x5fb), - TBL_ENTRY(0x5fc), TBL_ENTRY(0x5fd), TBL_ENTRY(0x5fe), TBL_ENTRY(0x5ff), - TBL_ENTRY(0x600), TBL_ENTRY(0x601), TBL_ENTRY(0x602), TBL_ENTRY(0x603), - TBL_ENTRY(0x604), TBL_ENTRY(0x605), TBL_ENTRY(0x606), TBL_ENTRY(0x607), - TBL_ENTRY(0x608), TBL_ENTRY(0x609), TBL_ENTRY(0x60a), TBL_ENTRY(0x60b), - TBL_ENTRY(0x60c), TBL_ENTRY(0x60d), TBL_ENTRY(0x60e), TBL_ENTRY(0x60f), - TBL_ENTRY(0x610), TBL_ENTRY(0x611), TBL_ENTRY(0x612), TBL_ENTRY(0x613), - TBL_ENTRY(0x614), TBL_ENTRY(0x615), TBL_ENTRY(0x616), TBL_ENTRY(0x617), - TBL_ENTRY(0x618), TBL_ENTRY(0x619), TBL_ENTRY(0x61a), TBL_ENTRY(0x61b), - TBL_ENTRY(0x61c), TBL_ENTRY(0x61d), TBL_ENTRY(0x61e), TBL_ENTRY(0x61f), - TBL_ENTRY(0x620), TBL_ENTRY(0x621), TBL_ENTRY(0x622), TBL_ENTRY(0x623), - TBL_ENTRY(0x624), TBL_ENTRY(0x625), TBL_ENTRY(0x626), TBL_ENTRY(0x627), - TBL_ENTRY(0x628), TBL_ENTRY(0x629), TBL_ENTRY(0x62a), TBL_ENTRY(0x62b), - TBL_ENTRY(0x62c), TBL_ENTRY(0x62d), TBL_ENTRY(0x62e), TBL_ENTRY(0x62f), - TBL_ENTRY(0x630), TBL_ENTRY(0x631), TBL_ENTRY(0x632), TBL_ENTRY(0x633), - TBL_ENTRY(0x634), TBL_ENTRY(0x635), TBL_ENTRY(0x636), TBL_ENTRY(0x637), - TBL_ENTRY(0x638), TBL_ENTRY(0x639), TBL_ENTRY(0x63a), TBL_ENTRY(0x63b), - TBL_ENTRY(0x63c), TBL_ENTRY(0x63d), TBL_ENTRY(0x63e), TBL_ENTRY(0x63f), - TBL_ENTRY(0x640), TBL_ENTRY(0x641), TBL_ENTRY(0x642), TBL_ENTRY(0x643), - TBL_ENTRY(0x644), TBL_ENTRY(0x645), TBL_ENTRY(0x646), TBL_ENTRY(0x647), - TBL_ENTRY(0x648), TBL_ENTRY(0x649), TBL_ENTRY(0x64a), TBL_ENTRY(0x64b), - TBL_ENTRY(0x64c), TBL_ENTRY(0x64d), TBL_ENTRY(0x64e), TBL_ENTRY(0x64f), - TBL_ENTRY(0x650), TBL_ENTRY(0x651), TBL_ENTRY(0x652), TBL_ENTRY(0x653), - TBL_ENTRY(0x654), TBL_ENTRY(0x655), TBL_ENTRY(0x656), TBL_ENTRY(0x657), - TBL_ENTRY(0x658), TBL_ENTRY(0x659), TBL_ENTRY(0x65a), TBL_ENTRY(0x65b), - TBL_ENTRY(0x65c), TBL_ENTRY(0x65d), TBL_ENTRY(0x65e), TBL_ENTRY(0x65f), - TBL_ENTRY(0x660), TBL_ENTRY(0x661), TBL_ENTRY(0x662), TBL_ENTRY(0x663), - TBL_ENTRY(0x664), TBL_ENTRY(0x665), TBL_ENTRY(0x666), TBL_ENTRY(0x667), - TBL_ENTRY(0x668), TBL_ENTRY(0x669), TBL_ENTRY(0x66a), TBL_ENTRY(0x66b), - TBL_ENTRY(0x66c), TBL_ENTRY(0x66d), TBL_ENTRY(0x66e), TBL_ENTRY(0x66f), - TBL_ENTRY(0x670), TBL_ENTRY(0x671), TBL_ENTRY(0x672), TBL_ENTRY(0x673), - TBL_ENTRY(0x674), TBL_ENTRY(0x675), TBL_ENTRY(0x676), TBL_ENTRY(0x677), - TBL_ENTRY(0x678), TBL_ENTRY(0x679), TBL_ENTRY(0x67a), TBL_ENTRY(0x67b), - TBL_ENTRY(0x67c), TBL_ENTRY(0x67d), TBL_ENTRY(0x67e), TBL_ENTRY(0x67f), - TBL_ENTRY(0x680), TBL_ENTRY(0x681), TBL_ENTRY(0x682), TBL_ENTRY(0x683), - TBL_ENTRY(0x684), TBL_ENTRY(0x685), TBL_ENTRY(0x686), TBL_ENTRY(0x687), - TBL_ENTRY(0x688), TBL_ENTRY(0x689), TBL_ENTRY(0x68a), TBL_ENTRY(0x68b), - TBL_ENTRY(0x68c), TBL_ENTRY(0x68d), TBL_ENTRY(0x68e), TBL_ENTRY(0x68f), - TBL_ENTRY(0x690), TBL_ENTRY(0x691), TBL_ENTRY(0x692), TBL_ENTRY(0x693), - TBL_ENTRY(0x694), TBL_ENTRY(0x695), TBL_ENTRY(0x696), TBL_ENTRY(0x697), - TBL_ENTRY(0x698), TBL_ENTRY(0x699), TBL_ENTRY(0x69a), TBL_ENTRY(0x69b), - TBL_ENTRY(0x69c), TBL_ENTRY(0x69d), TBL_ENTRY(0x69e), TBL_ENTRY(0x69f), - TBL_ENTRY(0x6a0), TBL_ENTRY(0x6a1), TBL_ENTRY(0x6a2), TBL_ENTRY(0x6a3), - TBL_ENTRY(0x6a4), TBL_ENTRY(0x6a5), TBL_ENTRY(0x6a6), TBL_ENTRY(0x6a7), - TBL_ENTRY(0x6a8), TBL_ENTRY(0x6a9), TBL_ENTRY(0x6aa), TBL_ENTRY(0x6ab), - TBL_ENTRY(0x6ac), TBL_ENTRY(0x6ad), TBL_ENTRY(0x6ae), TBL_ENTRY(0x6af), - TBL_ENTRY(0x6b0), TBL_ENTRY(0x6b1), TBL_ENTRY(0x6b2), TBL_ENTRY(0x6b3), - TBL_ENTRY(0x6b4), TBL_ENTRY(0x6b5), TBL_ENTRY(0x6b6), TBL_ENTRY(0x6b7), - TBL_ENTRY(0x6b8), TBL_ENTRY(0x6b9), TBL_ENTRY(0x6ba), TBL_ENTRY(0x6bb), - TBL_ENTRY(0x6bc), TBL_ENTRY(0x6bd), TBL_ENTRY(0x6be), TBL_ENTRY(0x6bf), - TBL_ENTRY(0x6c0), TBL_ENTRY(0x6c1), TBL_ENTRY(0x6c2), TBL_ENTRY(0x6c3), - TBL_ENTRY(0x6c4), TBL_ENTRY(0x6c5), TBL_ENTRY(0x6c6), TBL_ENTRY(0x6c7), - TBL_ENTRY(0x6c8), TBL_ENTRY(0x6c9), TBL_ENTRY(0x6ca), TBL_ENTRY(0x6cb), - TBL_ENTRY(0x6cc), TBL_ENTRY(0x6cd), TBL_ENTRY(0x6ce), TBL_ENTRY(0x6cf), - TBL_ENTRY(0x6d0), TBL_ENTRY(0x6d1), TBL_ENTRY(0x6d2), TBL_ENTRY(0x6d3), - TBL_ENTRY(0x6d4), TBL_ENTRY(0x6d5), TBL_ENTRY(0x6d6), TBL_ENTRY(0x6d7), - TBL_ENTRY(0x6d8), TBL_ENTRY(0x6d9), TBL_ENTRY(0x6da), TBL_ENTRY(0x6db), - TBL_ENTRY(0x6dc), TBL_ENTRY(0x6dd), TBL_ENTRY(0x6de), TBL_ENTRY(0x6df), - TBL_ENTRY(0x6e0), TBL_ENTRY(0x6e1), TBL_ENTRY(0x6e2), TBL_ENTRY(0x6e3), - TBL_ENTRY(0x6e4), TBL_ENTRY(0x6e5), TBL_ENTRY(0x6e6), TBL_ENTRY(0x6e7), - TBL_ENTRY(0x6e8), TBL_ENTRY(0x6e9), TBL_ENTRY(0x6ea), TBL_ENTRY(0x6eb), - TBL_ENTRY(0x6ec), TBL_ENTRY(0x6ed), TBL_ENTRY(0x6ee), TBL_ENTRY(0x6ef), - TBL_ENTRY(0x6f0), TBL_ENTRY(0x6f1), TBL_ENTRY(0x6f2), TBL_ENTRY(0x6f3), - TBL_ENTRY(0x6f4), TBL_ENTRY(0x6f5), TBL_ENTRY(0x6f6), TBL_ENTRY(0x6f7), - TBL_ENTRY(0x6f8), TBL_ENTRY(0x6f9), TBL_ENTRY(0x6fa), TBL_ENTRY(0x6fb), - TBL_ENTRY(0x6fc), TBL_ENTRY(0x6fd), TBL_ENTRY(0x6fe), TBL_ENTRY(0x6ff), - TBL_ENTRY(0x700), TBL_ENTRY(0x701), TBL_ENTRY(0x702), TBL_ENTRY(0x703), - TBL_ENTRY(0x704), TBL_ENTRY(0x705), TBL_ENTRY(0x706), TBL_ENTRY(0x707), - TBL_ENTRY(0x708), TBL_ENTRY(0x709), TBL_ENTRY(0x70a), TBL_ENTRY(0x70b), - TBL_ENTRY(0x70c), TBL_ENTRY(0x70d), TBL_ENTRY(0x70e), TBL_ENTRY(0x70f), - TBL_ENTRY(0x710), TBL_ENTRY(0x711), TBL_ENTRY(0x712), TBL_ENTRY(0x713), - TBL_ENTRY(0x714), TBL_ENTRY(0x715), TBL_ENTRY(0x716), TBL_ENTRY(0x717), - TBL_ENTRY(0x718), TBL_ENTRY(0x719), TBL_ENTRY(0x71a), TBL_ENTRY(0x71b), - TBL_ENTRY(0x71c), TBL_ENTRY(0x71d), TBL_ENTRY(0x71e), TBL_ENTRY(0x71f), - TBL_ENTRY(0x720), TBL_ENTRY(0x721), TBL_ENTRY(0x722), TBL_ENTRY(0x723), - TBL_ENTRY(0x724), TBL_ENTRY(0x725), TBL_ENTRY(0x726), TBL_ENTRY(0x727), - TBL_ENTRY(0x728), TBL_ENTRY(0x729), TBL_ENTRY(0x72a), TBL_ENTRY(0x72b), - TBL_ENTRY(0x72c), TBL_ENTRY(0x72d), TBL_ENTRY(0x72e), TBL_ENTRY(0x72f), - TBL_ENTRY(0x730), TBL_ENTRY(0x731), TBL_ENTRY(0x732), TBL_ENTRY(0x733), - TBL_ENTRY(0x734), TBL_ENTRY(0x735), TBL_ENTRY(0x736), TBL_ENTRY(0x737), - TBL_ENTRY(0x738), TBL_ENTRY(0x739), TBL_ENTRY(0x73a), TBL_ENTRY(0x73b), - TBL_ENTRY(0x73c), TBL_ENTRY(0x73d), TBL_ENTRY(0x73e), TBL_ENTRY(0x73f), - TBL_ENTRY(0x740), TBL_ENTRY(0x741), TBL_ENTRY(0x742), TBL_ENTRY(0x743), - TBL_ENTRY(0x744), TBL_ENTRY(0x745), TBL_ENTRY(0x746), TBL_ENTRY(0x747), - TBL_ENTRY(0x748), TBL_ENTRY(0x749), TBL_ENTRY(0x74a), TBL_ENTRY(0x74b), - TBL_ENTRY(0x74c), TBL_ENTRY(0x74d), TBL_ENTRY(0x74e), TBL_ENTRY(0x74f), - TBL_ENTRY(0x750), TBL_ENTRY(0x751), TBL_ENTRY(0x752), TBL_ENTRY(0x753), - TBL_ENTRY(0x754), TBL_ENTRY(0x755), TBL_ENTRY(0x756), TBL_ENTRY(0x757), - TBL_ENTRY(0x758), TBL_ENTRY(0x759), TBL_ENTRY(0x75a), TBL_ENTRY(0x75b), - TBL_ENTRY(0x75c), TBL_ENTRY(0x75d), TBL_ENTRY(0x75e), TBL_ENTRY(0x75f), - TBL_ENTRY(0x760), TBL_ENTRY(0x761), TBL_ENTRY(0x762), TBL_ENTRY(0x763), - TBL_ENTRY(0x764), TBL_ENTRY(0x765), TBL_ENTRY(0x766), TBL_ENTRY(0x767), - TBL_ENTRY(0x768), TBL_ENTRY(0x769), TBL_ENTRY(0x76a), TBL_ENTRY(0x76b), - TBL_ENTRY(0x76c), TBL_ENTRY(0x76d), TBL_ENTRY(0x76e), TBL_ENTRY(0x76f), - TBL_ENTRY(0x770), TBL_ENTRY(0x771), TBL_ENTRY(0x772), TBL_ENTRY(0x773), - TBL_ENTRY(0x774), TBL_ENTRY(0x775), TBL_ENTRY(0x776), TBL_ENTRY(0x777), - TBL_ENTRY(0x778), TBL_ENTRY(0x779), TBL_ENTRY(0x77a), TBL_ENTRY(0x77b), - TBL_ENTRY(0x77c), TBL_ENTRY(0x77d), TBL_ENTRY(0x77e), TBL_ENTRY(0x77f), - TBL_ENTRY(0x780), TBL_ENTRY(0x781), TBL_ENTRY(0x782), TBL_ENTRY(0x783), - TBL_ENTRY(0x784), TBL_ENTRY(0x785), TBL_ENTRY(0x786), TBL_ENTRY(0x787), - TBL_ENTRY(0x788), TBL_ENTRY(0x789), TBL_ENTRY(0x78a), TBL_ENTRY(0x78b), - TBL_ENTRY(0x78c), TBL_ENTRY(0x78d), TBL_ENTRY(0x78e), TBL_ENTRY(0x78f), - TBL_ENTRY(0x790), TBL_ENTRY(0x791), TBL_ENTRY(0x792), TBL_ENTRY(0x793), - TBL_ENTRY(0x794), TBL_ENTRY(0x795), TBL_ENTRY(0x796), TBL_ENTRY(0x797), - TBL_ENTRY(0x798), TBL_ENTRY(0x799), TBL_ENTRY(0x79a), TBL_ENTRY(0x79b), - TBL_ENTRY(0x79c), TBL_ENTRY(0x79d), TBL_ENTRY(0x79e), TBL_ENTRY(0x79f), - TBL_ENTRY(0x7a0), TBL_ENTRY(0x7a1), TBL_ENTRY(0x7a2), TBL_ENTRY(0x7a3), - TBL_ENTRY(0x7a4), TBL_ENTRY(0x7a5), TBL_ENTRY(0x7a6), TBL_ENTRY(0x7a7), - TBL_ENTRY(0x7a8), TBL_ENTRY(0x7a9), TBL_ENTRY(0x7aa), TBL_ENTRY(0x7ab), - TBL_ENTRY(0x7ac), TBL_ENTRY(0x7ad), TBL_ENTRY(0x7ae), TBL_ENTRY(0x7af), - TBL_ENTRY(0x7b0), TBL_ENTRY(0x7b1), TBL_ENTRY(0x7b2), TBL_ENTRY(0x7b3), - TBL_ENTRY(0x7b4), TBL_ENTRY(0x7b5), TBL_ENTRY(0x7b6), TBL_ENTRY(0x7b7), - TBL_ENTRY(0x7b8), TBL_ENTRY(0x7b9), TBL_ENTRY(0x7ba), TBL_ENTRY(0x7bb), - TBL_ENTRY(0x7bc), TBL_ENTRY(0x7bd), TBL_ENTRY(0x7be), TBL_ENTRY(0x7bf), - TBL_ENTRY(0x7c0), TBL_ENTRY(0x7c1), TBL_ENTRY(0x7c2), TBL_ENTRY(0x7c3), - TBL_ENTRY(0x7c4), TBL_ENTRY(0x7c5), TBL_ENTRY(0x7c6), TBL_ENTRY(0x7c7), - TBL_ENTRY(0x7c8), TBL_ENTRY(0x7c9), TBL_ENTRY(0x7ca), TBL_ENTRY(0x7cb), - TBL_ENTRY(0x7cc), TBL_ENTRY(0x7cd), TBL_ENTRY(0x7ce), TBL_ENTRY(0x7cf), - TBL_ENTRY(0x7d0), TBL_ENTRY(0x7d1), TBL_ENTRY(0x7d2), TBL_ENTRY(0x7d3), - TBL_ENTRY(0x7d4), TBL_ENTRY(0x7d5), TBL_ENTRY(0x7d6), TBL_ENTRY(0x7d7), - TBL_ENTRY(0x7d8), TBL_ENTRY(0x7d9), TBL_ENTRY(0x7da), TBL_ENTRY(0x7db), - TBL_ENTRY(0x7dc), TBL_ENTRY(0x7dd), TBL_ENTRY(0x7de), TBL_ENTRY(0x7df), - TBL_ENTRY(0x7e0), TBL_ENTRY(0x7e1), TBL_ENTRY(0x7e2), TBL_ENTRY(0x7e3), - TBL_ENTRY(0x7e4), TBL_ENTRY(0x7e5), TBL_ENTRY(0x7e6), TBL_ENTRY(0x7e7), - TBL_ENTRY(0x7e8), TBL_ENTRY(0x7e9), TBL_ENTRY(0x7ea), TBL_ENTRY(0x7eb), - TBL_ENTRY(0x7ec), TBL_ENTRY(0x7ed), TBL_ENTRY(0x7ee), TBL_ENTRY(0x7ef), - TBL_ENTRY(0x7f0), TBL_ENTRY(0x7f1), TBL_ENTRY(0x7f2), TBL_ENTRY(0x7f3), - TBL_ENTRY(0x7f4), TBL_ENTRY(0x7f5), TBL_ENTRY(0x7f6), TBL_ENTRY(0x7f7), - TBL_ENTRY(0x7f8), TBL_ENTRY(0x7f9), TBL_ENTRY(0x7fa), TBL_ENTRY(0x7fb), - TBL_ENTRY(0x7fc), TBL_ENTRY(0x7fd), TBL_ENTRY(0x7fe), TBL_ENTRY(0x7ff), - TBL_ENTRY(0x800), TBL_ENTRY(0x801), TBL_ENTRY(0x802), TBL_ENTRY(0x803), - TBL_ENTRY(0x804), TBL_ENTRY(0x805), TBL_ENTRY(0x806), TBL_ENTRY(0x807), - TBL_ENTRY(0x808), TBL_ENTRY(0x809), TBL_ENTRY(0x80a), TBL_ENTRY(0x80b), - TBL_ENTRY(0x80c), TBL_ENTRY(0x80d), TBL_ENTRY(0x80e), TBL_ENTRY(0x80f), - TBL_ENTRY(0x810), TBL_ENTRY(0x811), TBL_ENTRY(0x812), TBL_ENTRY(0x813), - TBL_ENTRY(0x814), TBL_ENTRY(0x815), TBL_ENTRY(0x816), TBL_ENTRY(0x817), - TBL_ENTRY(0x818), TBL_ENTRY(0x819), TBL_ENTRY(0x81a), TBL_ENTRY(0x81b), - TBL_ENTRY(0x81c), TBL_ENTRY(0x81d), TBL_ENTRY(0x81e), TBL_ENTRY(0x81f), - TBL_ENTRY(0x820), TBL_ENTRY(0x821), TBL_ENTRY(0x822), TBL_ENTRY(0x823), - TBL_ENTRY(0x824), TBL_ENTRY(0x825), TBL_ENTRY(0x826), TBL_ENTRY(0x827), - TBL_ENTRY(0x828), TBL_ENTRY(0x829), TBL_ENTRY(0x82a), TBL_ENTRY(0x82b), - TBL_ENTRY(0x82c), TBL_ENTRY(0x82d), TBL_ENTRY(0x82e), TBL_ENTRY(0x82f), - TBL_ENTRY(0x830), TBL_ENTRY(0x831), TBL_ENTRY(0x832), TBL_ENTRY(0x833), - TBL_ENTRY(0x834), TBL_ENTRY(0x835), TBL_ENTRY(0x836), TBL_ENTRY(0x837), - TBL_ENTRY(0x838), TBL_ENTRY(0x839), TBL_ENTRY(0x83a), TBL_ENTRY(0x83b), - TBL_ENTRY(0x83c), TBL_ENTRY(0x83d), TBL_ENTRY(0x83e), TBL_ENTRY(0x83f), - TBL_ENTRY(0x840), TBL_ENTRY(0x841), TBL_ENTRY(0x842), TBL_ENTRY(0x843), - TBL_ENTRY(0x844), TBL_ENTRY(0x845), TBL_ENTRY(0x846), TBL_ENTRY(0x847), - TBL_ENTRY(0x848), TBL_ENTRY(0x849), TBL_ENTRY(0x84a), TBL_ENTRY(0x84b), - TBL_ENTRY(0x84c), TBL_ENTRY(0x84d), TBL_ENTRY(0x84e), TBL_ENTRY(0x84f), - TBL_ENTRY(0x850), TBL_ENTRY(0x851), TBL_ENTRY(0x852), TBL_ENTRY(0x853), - TBL_ENTRY(0x854), TBL_ENTRY(0x855), TBL_ENTRY(0x856), TBL_ENTRY(0x857), - TBL_ENTRY(0x858), TBL_ENTRY(0x859), TBL_ENTRY(0x85a), TBL_ENTRY(0x85b), - TBL_ENTRY(0x85c), TBL_ENTRY(0x85d), TBL_ENTRY(0x85e), TBL_ENTRY(0x85f), - TBL_ENTRY(0x860), TBL_ENTRY(0x861), TBL_ENTRY(0x862), TBL_ENTRY(0x863), - TBL_ENTRY(0x864), TBL_ENTRY(0x865), TBL_ENTRY(0x866), TBL_ENTRY(0x867), - TBL_ENTRY(0x868), TBL_ENTRY(0x869), TBL_ENTRY(0x86a), TBL_ENTRY(0x86b), - TBL_ENTRY(0x86c), TBL_ENTRY(0x86d), TBL_ENTRY(0x86e), TBL_ENTRY(0x86f), - TBL_ENTRY(0x870), TBL_ENTRY(0x871), TBL_ENTRY(0x872), TBL_ENTRY(0x873), - TBL_ENTRY(0x874), TBL_ENTRY(0x875), TBL_ENTRY(0x876), TBL_ENTRY(0x877), - TBL_ENTRY(0x878), TBL_ENTRY(0x879), TBL_ENTRY(0x87a), TBL_ENTRY(0x87b), - TBL_ENTRY(0x87c), TBL_ENTRY(0x87d), TBL_ENTRY(0x87e), TBL_ENTRY(0x87f), - TBL_ENTRY(0x880), TBL_ENTRY(0x881), TBL_ENTRY(0x882), TBL_ENTRY(0x883), - TBL_ENTRY(0x884), TBL_ENTRY(0x885), TBL_ENTRY(0x886), TBL_ENTRY(0x887), - TBL_ENTRY(0x888), TBL_ENTRY(0x889), TBL_ENTRY(0x88a), TBL_ENTRY(0x88b), - TBL_ENTRY(0x88c), TBL_ENTRY(0x88d), TBL_ENTRY(0x88e), TBL_ENTRY(0x88f), - TBL_ENTRY(0x890), TBL_ENTRY(0x891), TBL_ENTRY(0x892), TBL_ENTRY(0x893), - TBL_ENTRY(0x894), TBL_ENTRY(0x895), TBL_ENTRY(0x896), TBL_ENTRY(0x897), - TBL_ENTRY(0x898), TBL_ENTRY(0x899), TBL_ENTRY(0x89a), TBL_ENTRY(0x89b), - TBL_ENTRY(0x89c), TBL_ENTRY(0x89d), TBL_ENTRY(0x89e), TBL_ENTRY(0x89f), - TBL_ENTRY(0x8a0), TBL_ENTRY(0x8a1), TBL_ENTRY(0x8a2), TBL_ENTRY(0x8a3), - TBL_ENTRY(0x8a4), TBL_ENTRY(0x8a5), TBL_ENTRY(0x8a6), TBL_ENTRY(0x8a7), - TBL_ENTRY(0x8a8), TBL_ENTRY(0x8a9), TBL_ENTRY(0x8aa), TBL_ENTRY(0x8ab), - TBL_ENTRY(0x8ac), TBL_ENTRY(0x8ad), TBL_ENTRY(0x8ae), TBL_ENTRY(0x8af), - TBL_ENTRY(0x8b0), TBL_ENTRY(0x8b1), TBL_ENTRY(0x8b2), TBL_ENTRY(0x8b3), - TBL_ENTRY(0x8b4), TBL_ENTRY(0x8b5), TBL_ENTRY(0x8b6), TBL_ENTRY(0x8b7), - TBL_ENTRY(0x8b8), TBL_ENTRY(0x8b9), TBL_ENTRY(0x8ba), TBL_ENTRY(0x8bb), - TBL_ENTRY(0x8bc), TBL_ENTRY(0x8bd), TBL_ENTRY(0x8be), TBL_ENTRY(0x8bf), - TBL_ENTRY(0x8c0), TBL_ENTRY(0x8c1), TBL_ENTRY(0x8c2), TBL_ENTRY(0x8c3), - TBL_ENTRY(0x8c4), TBL_ENTRY(0x8c5), TBL_ENTRY(0x8c6), TBL_ENTRY(0x8c7), - TBL_ENTRY(0x8c8), TBL_ENTRY(0x8c9), TBL_ENTRY(0x8ca), TBL_ENTRY(0x8cb), - TBL_ENTRY(0x8cc), TBL_ENTRY(0x8cd), TBL_ENTRY(0x8ce), TBL_ENTRY(0x8cf), - TBL_ENTRY(0x8d0), TBL_ENTRY(0x8d1), TBL_ENTRY(0x8d2), TBL_ENTRY(0x8d3), - TBL_ENTRY(0x8d4), TBL_ENTRY(0x8d5), TBL_ENTRY(0x8d6), TBL_ENTRY(0x8d7), - TBL_ENTRY(0x8d8), TBL_ENTRY(0x8d9), TBL_ENTRY(0x8da), TBL_ENTRY(0x8db), - TBL_ENTRY(0x8dc), TBL_ENTRY(0x8dd), TBL_ENTRY(0x8de), TBL_ENTRY(0x8df), - TBL_ENTRY(0x8e0), TBL_ENTRY(0x8e1), TBL_ENTRY(0x8e2), TBL_ENTRY(0x8e3), - TBL_ENTRY(0x8e4), TBL_ENTRY(0x8e5), TBL_ENTRY(0x8e6), TBL_ENTRY(0x8e7), - TBL_ENTRY(0x8e8), TBL_ENTRY(0x8e9), TBL_ENTRY(0x8ea), TBL_ENTRY(0x8eb), - TBL_ENTRY(0x8ec), TBL_ENTRY(0x8ed), TBL_ENTRY(0x8ee), TBL_ENTRY(0x8ef), - TBL_ENTRY(0x8f0), TBL_ENTRY(0x8f1), TBL_ENTRY(0x8f2), TBL_ENTRY(0x8f3), - TBL_ENTRY(0x8f4), TBL_ENTRY(0x8f5), TBL_ENTRY(0x8f6), TBL_ENTRY(0x8f7), - TBL_ENTRY(0x8f8), TBL_ENTRY(0x8f9), TBL_ENTRY(0x8fa), TBL_ENTRY(0x8fb), - TBL_ENTRY(0x8fc), TBL_ENTRY(0x8fd), TBL_ENTRY(0x8fe), TBL_ENTRY(0x8ff), - TBL_ENTRY(0x900), TBL_ENTRY(0x901), TBL_ENTRY(0x902), TBL_ENTRY(0x903), - TBL_ENTRY(0x904), TBL_ENTRY(0x905), TBL_ENTRY(0x906), TBL_ENTRY(0x907), - TBL_ENTRY(0x908), TBL_ENTRY(0x909), TBL_ENTRY(0x90a), TBL_ENTRY(0x90b), - TBL_ENTRY(0x90c), TBL_ENTRY(0x90d), TBL_ENTRY(0x90e), TBL_ENTRY(0x90f), - TBL_ENTRY(0x910), TBL_ENTRY(0x911), TBL_ENTRY(0x912), TBL_ENTRY(0x913), - TBL_ENTRY(0x914), TBL_ENTRY(0x915), TBL_ENTRY(0x916), TBL_ENTRY(0x917), - TBL_ENTRY(0x918), TBL_ENTRY(0x919), TBL_ENTRY(0x91a), TBL_ENTRY(0x91b), - TBL_ENTRY(0x91c), TBL_ENTRY(0x91d), TBL_ENTRY(0x91e), TBL_ENTRY(0x91f), - TBL_ENTRY(0x920), TBL_ENTRY(0x921), TBL_ENTRY(0x922), TBL_ENTRY(0x923), - TBL_ENTRY(0x924), TBL_ENTRY(0x925), TBL_ENTRY(0x926), TBL_ENTRY(0x927), - TBL_ENTRY(0x928), TBL_ENTRY(0x929), TBL_ENTRY(0x92a), TBL_ENTRY(0x92b), - TBL_ENTRY(0x92c), TBL_ENTRY(0x92d), TBL_ENTRY(0x92e), TBL_ENTRY(0x92f), - TBL_ENTRY(0x930), TBL_ENTRY(0x931), TBL_ENTRY(0x932), TBL_ENTRY(0x933), - TBL_ENTRY(0x934), TBL_ENTRY(0x935), TBL_ENTRY(0x936), TBL_ENTRY(0x937), - TBL_ENTRY(0x938), TBL_ENTRY(0x939), TBL_ENTRY(0x93a), TBL_ENTRY(0x93b), - TBL_ENTRY(0x93c), TBL_ENTRY(0x93d), TBL_ENTRY(0x93e), TBL_ENTRY(0x93f), - TBL_ENTRY(0x940), TBL_ENTRY(0x941), TBL_ENTRY(0x942), TBL_ENTRY(0x943), - TBL_ENTRY(0x944), TBL_ENTRY(0x945), TBL_ENTRY(0x946), TBL_ENTRY(0x947), - TBL_ENTRY(0x948), TBL_ENTRY(0x949), TBL_ENTRY(0x94a), TBL_ENTRY(0x94b), - TBL_ENTRY(0x94c), TBL_ENTRY(0x94d), TBL_ENTRY(0x94e), TBL_ENTRY(0x94f), - TBL_ENTRY(0x950), TBL_ENTRY(0x951), TBL_ENTRY(0x952), TBL_ENTRY(0x953), - TBL_ENTRY(0x954), TBL_ENTRY(0x955), TBL_ENTRY(0x956), TBL_ENTRY(0x957), - TBL_ENTRY(0x958), TBL_ENTRY(0x959), TBL_ENTRY(0x95a), TBL_ENTRY(0x95b), - TBL_ENTRY(0x95c), TBL_ENTRY(0x95d), TBL_ENTRY(0x95e), TBL_ENTRY(0x95f), - TBL_ENTRY(0x960), TBL_ENTRY(0x961), TBL_ENTRY(0x962), TBL_ENTRY(0x963), - TBL_ENTRY(0x964), TBL_ENTRY(0x965), TBL_ENTRY(0x966), TBL_ENTRY(0x967), - TBL_ENTRY(0x968), TBL_ENTRY(0x969), TBL_ENTRY(0x96a), TBL_ENTRY(0x96b), - TBL_ENTRY(0x96c), TBL_ENTRY(0x96d), TBL_ENTRY(0x96e), TBL_ENTRY(0x96f), - TBL_ENTRY(0x970), TBL_ENTRY(0x971), TBL_ENTRY(0x972), TBL_ENTRY(0x973), - TBL_ENTRY(0x974), TBL_ENTRY(0x975), TBL_ENTRY(0x976), TBL_ENTRY(0x977), - TBL_ENTRY(0x978), TBL_ENTRY(0x979), TBL_ENTRY(0x97a), TBL_ENTRY(0x97b), - TBL_ENTRY(0x97c), TBL_ENTRY(0x97d), TBL_ENTRY(0x97e), TBL_ENTRY(0x97f), - TBL_ENTRY(0x980), TBL_ENTRY(0x981), TBL_ENTRY(0x982), TBL_ENTRY(0x983), - TBL_ENTRY(0x984), TBL_ENTRY(0x985), TBL_ENTRY(0x986), TBL_ENTRY(0x987), - TBL_ENTRY(0x988), TBL_ENTRY(0x989), TBL_ENTRY(0x98a), TBL_ENTRY(0x98b), - TBL_ENTRY(0x98c), TBL_ENTRY(0x98d), TBL_ENTRY(0x98e), TBL_ENTRY(0x98f), - TBL_ENTRY(0x990), TBL_ENTRY(0x991), TBL_ENTRY(0x992), TBL_ENTRY(0x993), - TBL_ENTRY(0x994), TBL_ENTRY(0x995), TBL_ENTRY(0x996), TBL_ENTRY(0x997), - TBL_ENTRY(0x998), TBL_ENTRY(0x999), TBL_ENTRY(0x99a), TBL_ENTRY(0x99b), - TBL_ENTRY(0x99c), TBL_ENTRY(0x99d), TBL_ENTRY(0x99e), TBL_ENTRY(0x99f), - TBL_ENTRY(0x9a0), TBL_ENTRY(0x9a1), TBL_ENTRY(0x9a2), TBL_ENTRY(0x9a3), - TBL_ENTRY(0x9a4), TBL_ENTRY(0x9a5), TBL_ENTRY(0x9a6), TBL_ENTRY(0x9a7), - TBL_ENTRY(0x9a8), TBL_ENTRY(0x9a9), TBL_ENTRY(0x9aa), TBL_ENTRY(0x9ab), - TBL_ENTRY(0x9ac), TBL_ENTRY(0x9ad), TBL_ENTRY(0x9ae), TBL_ENTRY(0x9af), - TBL_ENTRY(0x9b0), TBL_ENTRY(0x9b1), TBL_ENTRY(0x9b2), TBL_ENTRY(0x9b3), - TBL_ENTRY(0x9b4), TBL_ENTRY(0x9b5), TBL_ENTRY(0x9b6), TBL_ENTRY(0x9b7), - TBL_ENTRY(0x9b8), TBL_ENTRY(0x9b9), TBL_ENTRY(0x9ba), TBL_ENTRY(0x9bb), - TBL_ENTRY(0x9bc), TBL_ENTRY(0x9bd), TBL_ENTRY(0x9be), TBL_ENTRY(0x9bf), - TBL_ENTRY(0x9c0), TBL_ENTRY(0x9c1), TBL_ENTRY(0x9c2), TBL_ENTRY(0x9c3), - TBL_ENTRY(0x9c4), TBL_ENTRY(0x9c5), TBL_ENTRY(0x9c6), TBL_ENTRY(0x9c7), - TBL_ENTRY(0x9c8), TBL_ENTRY(0x9c9), TBL_ENTRY(0x9ca), TBL_ENTRY(0x9cb), - TBL_ENTRY(0x9cc), TBL_ENTRY(0x9cd), TBL_ENTRY(0x9ce), TBL_ENTRY(0x9cf), - TBL_ENTRY(0x9d0), TBL_ENTRY(0x9d1), TBL_ENTRY(0x9d2), TBL_ENTRY(0x9d3), - TBL_ENTRY(0x9d4), TBL_ENTRY(0x9d5), TBL_ENTRY(0x9d6), TBL_ENTRY(0x9d7), - TBL_ENTRY(0x9d8), TBL_ENTRY(0x9d9), TBL_ENTRY(0x9da), TBL_ENTRY(0x9db), - TBL_ENTRY(0x9dc), TBL_ENTRY(0x9dd), TBL_ENTRY(0x9de), TBL_ENTRY(0x9df), - TBL_ENTRY(0x9e0), TBL_ENTRY(0x9e1), TBL_ENTRY(0x9e2), TBL_ENTRY(0x9e3), - TBL_ENTRY(0x9e4), TBL_ENTRY(0x9e5), TBL_ENTRY(0x9e6), TBL_ENTRY(0x9e7), - TBL_ENTRY(0x9e8), TBL_ENTRY(0x9e9), TBL_ENTRY(0x9ea), TBL_ENTRY(0x9eb), - TBL_ENTRY(0x9ec), TBL_ENTRY(0x9ed), TBL_ENTRY(0x9ee), TBL_ENTRY(0x9ef), - TBL_ENTRY(0x9f0), TBL_ENTRY(0x9f1), TBL_ENTRY(0x9f2), TBL_ENTRY(0x9f3), - TBL_ENTRY(0x9f4), TBL_ENTRY(0x9f5), TBL_ENTRY(0x9f6), TBL_ENTRY(0x9f7), - TBL_ENTRY(0x9f8), TBL_ENTRY(0x9f9), TBL_ENTRY(0x9fa), TBL_ENTRY(0x9fb), - TBL_ENTRY(0x9fc), TBL_ENTRY(0x9fd), TBL_ENTRY(0x9fe), TBL_ENTRY(0x9ff), - TBL_ENTRY(0xa00), TBL_ENTRY(0xa01), TBL_ENTRY(0xa02), TBL_ENTRY(0xa03), - TBL_ENTRY(0xa04), TBL_ENTRY(0xa05), TBL_ENTRY(0xa06), TBL_ENTRY(0xa07), - TBL_ENTRY(0xa08), TBL_ENTRY(0xa09), TBL_ENTRY(0xa0a), TBL_ENTRY(0xa0b), - TBL_ENTRY(0xa0c), TBL_ENTRY(0xa0d), TBL_ENTRY(0xa0e), TBL_ENTRY(0xa0f), - TBL_ENTRY(0xa10), TBL_ENTRY(0xa11), TBL_ENTRY(0xa12), TBL_ENTRY(0xa13), - TBL_ENTRY(0xa14), TBL_ENTRY(0xa15), TBL_ENTRY(0xa16), TBL_ENTRY(0xa17), - TBL_ENTRY(0xa18), TBL_ENTRY(0xa19), TBL_ENTRY(0xa1a), TBL_ENTRY(0xa1b), - TBL_ENTRY(0xa1c), TBL_ENTRY(0xa1d), TBL_ENTRY(0xa1e), TBL_ENTRY(0xa1f), - TBL_ENTRY(0xa20), TBL_ENTRY(0xa21), TBL_ENTRY(0xa22), TBL_ENTRY(0xa23), - TBL_ENTRY(0xa24), TBL_ENTRY(0xa25), TBL_ENTRY(0xa26), TBL_ENTRY(0xa27), - TBL_ENTRY(0xa28), TBL_ENTRY(0xa29), TBL_ENTRY(0xa2a), TBL_ENTRY(0xa2b), - TBL_ENTRY(0xa2c), TBL_ENTRY(0xa2d), TBL_ENTRY(0xa2e), TBL_ENTRY(0xa2f), - TBL_ENTRY(0xa30), TBL_ENTRY(0xa31), TBL_ENTRY(0xa32), TBL_ENTRY(0xa33), - TBL_ENTRY(0xa34), TBL_ENTRY(0xa35), TBL_ENTRY(0xa36), TBL_ENTRY(0xa37), - TBL_ENTRY(0xa38), TBL_ENTRY(0xa39), TBL_ENTRY(0xa3a), TBL_ENTRY(0xa3b), - TBL_ENTRY(0xa3c), TBL_ENTRY(0xa3d), TBL_ENTRY(0xa3e), TBL_ENTRY(0xa3f), - TBL_ENTRY(0xa40), TBL_ENTRY(0xa41), TBL_ENTRY(0xa42), TBL_ENTRY(0xa43), - TBL_ENTRY(0xa44), TBL_ENTRY(0xa45), TBL_ENTRY(0xa46), TBL_ENTRY(0xa47), - TBL_ENTRY(0xa48), TBL_ENTRY(0xa49), TBL_ENTRY(0xa4a), TBL_ENTRY(0xa4b), - TBL_ENTRY(0xa4c), TBL_ENTRY(0xa4d), TBL_ENTRY(0xa4e), TBL_ENTRY(0xa4f), - TBL_ENTRY(0xa50), TBL_ENTRY(0xa51), TBL_ENTRY(0xa52), TBL_ENTRY(0xa53), - TBL_ENTRY(0xa54), TBL_ENTRY(0xa55), TBL_ENTRY(0xa56), TBL_ENTRY(0xa57), - TBL_ENTRY(0xa58), TBL_ENTRY(0xa59), TBL_ENTRY(0xa5a), TBL_ENTRY(0xa5b), - TBL_ENTRY(0xa5c), TBL_ENTRY(0xa5d), TBL_ENTRY(0xa5e), TBL_ENTRY(0xa5f), - TBL_ENTRY(0xa60), TBL_ENTRY(0xa61), TBL_ENTRY(0xa62), TBL_ENTRY(0xa63), - TBL_ENTRY(0xa64), TBL_ENTRY(0xa65), TBL_ENTRY(0xa66), TBL_ENTRY(0xa67), - TBL_ENTRY(0xa68), TBL_ENTRY(0xa69), TBL_ENTRY(0xa6a), TBL_ENTRY(0xa6b), - TBL_ENTRY(0xa6c), TBL_ENTRY(0xa6d), TBL_ENTRY(0xa6e), TBL_ENTRY(0xa6f), - TBL_ENTRY(0xa70), TBL_ENTRY(0xa71), TBL_ENTRY(0xa72), TBL_ENTRY(0xa73), - TBL_ENTRY(0xa74), TBL_ENTRY(0xa75), TBL_ENTRY(0xa76), TBL_ENTRY(0xa77), - TBL_ENTRY(0xa78), TBL_ENTRY(0xa79), TBL_ENTRY(0xa7a), TBL_ENTRY(0xa7b), - TBL_ENTRY(0xa7c), TBL_ENTRY(0xa7d), TBL_ENTRY(0xa7e), TBL_ENTRY(0xa7f), - TBL_ENTRY(0xa80), TBL_ENTRY(0xa81), TBL_ENTRY(0xa82), TBL_ENTRY(0xa83), - TBL_ENTRY(0xa84), TBL_ENTRY(0xa85), TBL_ENTRY(0xa86), TBL_ENTRY(0xa87), - TBL_ENTRY(0xa88), TBL_ENTRY(0xa89), TBL_ENTRY(0xa8a), TBL_ENTRY(0xa8b), - TBL_ENTRY(0xa8c), TBL_ENTRY(0xa8d), TBL_ENTRY(0xa8e), TBL_ENTRY(0xa8f), - TBL_ENTRY(0xa90), TBL_ENTRY(0xa91), TBL_ENTRY(0xa92), TBL_ENTRY(0xa93), - TBL_ENTRY(0xa94), TBL_ENTRY(0xa95), TBL_ENTRY(0xa96), TBL_ENTRY(0xa97), - TBL_ENTRY(0xa98), TBL_ENTRY(0xa99), TBL_ENTRY(0xa9a), TBL_ENTRY(0xa9b), - TBL_ENTRY(0xa9c), TBL_ENTRY(0xa9d), TBL_ENTRY(0xa9e), TBL_ENTRY(0xa9f), - TBL_ENTRY(0xaa0), TBL_ENTRY(0xaa1), TBL_ENTRY(0xaa2), TBL_ENTRY(0xaa3), - TBL_ENTRY(0xaa4), TBL_ENTRY(0xaa5), TBL_ENTRY(0xaa6), TBL_ENTRY(0xaa7), - TBL_ENTRY(0xaa8), TBL_ENTRY(0xaa9), TBL_ENTRY(0xaaa), TBL_ENTRY(0xaab), - TBL_ENTRY(0xaac), TBL_ENTRY(0xaad), TBL_ENTRY(0xaae), TBL_ENTRY(0xaaf), - TBL_ENTRY(0xab0), TBL_ENTRY(0xab1), TBL_ENTRY(0xab2), TBL_ENTRY(0xab3), - TBL_ENTRY(0xab4), TBL_ENTRY(0xab5), TBL_ENTRY(0xab6), TBL_ENTRY(0xab7), - TBL_ENTRY(0xab8), TBL_ENTRY(0xab9), TBL_ENTRY(0xaba), TBL_ENTRY(0xabb), - TBL_ENTRY(0xabc), TBL_ENTRY(0xabd), TBL_ENTRY(0xabe), TBL_ENTRY(0xabf), - TBL_ENTRY(0xac0), TBL_ENTRY(0xac1), TBL_ENTRY(0xac2), TBL_ENTRY(0xac3), - TBL_ENTRY(0xac4), TBL_ENTRY(0xac5), TBL_ENTRY(0xac6), TBL_ENTRY(0xac7), - TBL_ENTRY(0xac8), TBL_ENTRY(0xac9), TBL_ENTRY(0xaca), TBL_ENTRY(0xacb), - TBL_ENTRY(0xacc), TBL_ENTRY(0xacd), TBL_ENTRY(0xace), TBL_ENTRY(0xacf), - TBL_ENTRY(0xad0), TBL_ENTRY(0xad1), TBL_ENTRY(0xad2), TBL_ENTRY(0xad3), - TBL_ENTRY(0xad4), TBL_ENTRY(0xad5), TBL_ENTRY(0xad6), TBL_ENTRY(0xad7), - TBL_ENTRY(0xad8), TBL_ENTRY(0xad9), TBL_ENTRY(0xada), TBL_ENTRY(0xadb), - TBL_ENTRY(0xadc), TBL_ENTRY(0xadd), TBL_ENTRY(0xade), TBL_ENTRY(0xadf), - TBL_ENTRY(0xae0), TBL_ENTRY(0xae1), TBL_ENTRY(0xae2), TBL_ENTRY(0xae3), - TBL_ENTRY(0xae4), TBL_ENTRY(0xae5), TBL_ENTRY(0xae6), TBL_ENTRY(0xae7), - TBL_ENTRY(0xae8), TBL_ENTRY(0xae9), TBL_ENTRY(0xaea), TBL_ENTRY(0xaeb), - TBL_ENTRY(0xaec), TBL_ENTRY(0xaed), TBL_ENTRY(0xaee), TBL_ENTRY(0xaef), - TBL_ENTRY(0xaf0), TBL_ENTRY(0xaf1), TBL_ENTRY(0xaf2), TBL_ENTRY(0xaf3), - TBL_ENTRY(0xaf4), TBL_ENTRY(0xaf5), TBL_ENTRY(0xaf6), TBL_ENTRY(0xaf7), - TBL_ENTRY(0xaf8), TBL_ENTRY(0xaf9), TBL_ENTRY(0xafa), TBL_ENTRY(0xafb), - TBL_ENTRY(0xafc), TBL_ENTRY(0xafd), TBL_ENTRY(0xafe), TBL_ENTRY(0xaff), - TBL_ENTRY(0xb00), TBL_ENTRY(0xb01), TBL_ENTRY(0xb02), TBL_ENTRY(0xb03), - TBL_ENTRY(0xb04), TBL_ENTRY(0xb05), TBL_ENTRY(0xb06), TBL_ENTRY(0xb07), - TBL_ENTRY(0xb08), TBL_ENTRY(0xb09), TBL_ENTRY(0xb0a), TBL_ENTRY(0xb0b), - TBL_ENTRY(0xb0c), TBL_ENTRY(0xb0d), TBL_ENTRY(0xb0e), TBL_ENTRY(0xb0f), - TBL_ENTRY(0xb10), TBL_ENTRY(0xb11), TBL_ENTRY(0xb12), TBL_ENTRY(0xb13), - TBL_ENTRY(0xb14), TBL_ENTRY(0xb15), TBL_ENTRY(0xb16), TBL_ENTRY(0xb17), - TBL_ENTRY(0xb18), TBL_ENTRY(0xb19), TBL_ENTRY(0xb1a), TBL_ENTRY(0xb1b), - TBL_ENTRY(0xb1c), TBL_ENTRY(0xb1d), TBL_ENTRY(0xb1e), TBL_ENTRY(0xb1f), - TBL_ENTRY(0xb20), TBL_ENTRY(0xb21), TBL_ENTRY(0xb22), TBL_ENTRY(0xb23), - TBL_ENTRY(0xb24), TBL_ENTRY(0xb25), TBL_ENTRY(0xb26), TBL_ENTRY(0xb27), - TBL_ENTRY(0xb28), TBL_ENTRY(0xb29), TBL_ENTRY(0xb2a), TBL_ENTRY(0xb2b), - TBL_ENTRY(0xb2c), TBL_ENTRY(0xb2d), TBL_ENTRY(0xb2e), TBL_ENTRY(0xb2f), - TBL_ENTRY(0xb30), TBL_ENTRY(0xb31), TBL_ENTRY(0xb32), TBL_ENTRY(0xb33), - TBL_ENTRY(0xb34), TBL_ENTRY(0xb35), TBL_ENTRY(0xb36), TBL_ENTRY(0xb37), - TBL_ENTRY(0xb38), TBL_ENTRY(0xb39), TBL_ENTRY(0xb3a), TBL_ENTRY(0xb3b), - TBL_ENTRY(0xb3c), TBL_ENTRY(0xb3d), TBL_ENTRY(0xb3e), TBL_ENTRY(0xb3f), - TBL_ENTRY(0xb40), TBL_ENTRY(0xb41), TBL_ENTRY(0xb42), TBL_ENTRY(0xb43), - TBL_ENTRY(0xb44), TBL_ENTRY(0xb45), TBL_ENTRY(0xb46), TBL_ENTRY(0xb47), - TBL_ENTRY(0xb48), TBL_ENTRY(0xb49), TBL_ENTRY(0xb4a), TBL_ENTRY(0xb4b), - TBL_ENTRY(0xb4c), TBL_ENTRY(0xb4d), TBL_ENTRY(0xb4e), TBL_ENTRY(0xb4f), - TBL_ENTRY(0xb50), TBL_ENTRY(0xb51), TBL_ENTRY(0xb52), TBL_ENTRY(0xb53), - TBL_ENTRY(0xb54), TBL_ENTRY(0xb55), TBL_ENTRY(0xb56), TBL_ENTRY(0xb57), - TBL_ENTRY(0xb58), TBL_ENTRY(0xb59), TBL_ENTRY(0xb5a), TBL_ENTRY(0xb5b), - TBL_ENTRY(0xb5c), TBL_ENTRY(0xb5d), TBL_ENTRY(0xb5e), TBL_ENTRY(0xb5f), - TBL_ENTRY(0xb60), TBL_ENTRY(0xb61), TBL_ENTRY(0xb62), TBL_ENTRY(0xb63), - TBL_ENTRY(0xb64), TBL_ENTRY(0xb65), TBL_ENTRY(0xb66), TBL_ENTRY(0xb67), - TBL_ENTRY(0xb68), TBL_ENTRY(0xb69), TBL_ENTRY(0xb6a), TBL_ENTRY(0xb6b), - TBL_ENTRY(0xb6c), TBL_ENTRY(0xb6d), TBL_ENTRY(0xb6e), TBL_ENTRY(0xb6f), - TBL_ENTRY(0xb70), TBL_ENTRY(0xb71), TBL_ENTRY(0xb72), TBL_ENTRY(0xb73), - TBL_ENTRY(0xb74), TBL_ENTRY(0xb75), TBL_ENTRY(0xb76), TBL_ENTRY(0xb77), - TBL_ENTRY(0xb78), TBL_ENTRY(0xb79), TBL_ENTRY(0xb7a), TBL_ENTRY(0xb7b), - TBL_ENTRY(0xb7c), TBL_ENTRY(0xb7d), TBL_ENTRY(0xb7e), TBL_ENTRY(0xb7f), - TBL_ENTRY(0xb80), TBL_ENTRY(0xb81), TBL_ENTRY(0xb82), TBL_ENTRY(0xb83), - TBL_ENTRY(0xb84), TBL_ENTRY(0xb85), TBL_ENTRY(0xb86), TBL_ENTRY(0xb87), - TBL_ENTRY(0xb88), TBL_ENTRY(0xb89), TBL_ENTRY(0xb8a), TBL_ENTRY(0xb8b), - TBL_ENTRY(0xb8c), TBL_ENTRY(0xb8d), TBL_ENTRY(0xb8e), TBL_ENTRY(0xb8f), - TBL_ENTRY(0xb90), TBL_ENTRY(0xb91), TBL_ENTRY(0xb92), TBL_ENTRY(0xb93), - TBL_ENTRY(0xb94), TBL_ENTRY(0xb95), TBL_ENTRY(0xb96), TBL_ENTRY(0xb97), - TBL_ENTRY(0xb98), TBL_ENTRY(0xb99), TBL_ENTRY(0xb9a), TBL_ENTRY(0xb9b), - TBL_ENTRY(0xb9c), TBL_ENTRY(0xb9d), TBL_ENTRY(0xb9e), TBL_ENTRY(0xb9f), - TBL_ENTRY(0xba0), TBL_ENTRY(0xba1), TBL_ENTRY(0xba2), TBL_ENTRY(0xba3), - TBL_ENTRY(0xba4), TBL_ENTRY(0xba5), TBL_ENTRY(0xba6), TBL_ENTRY(0xba7), - TBL_ENTRY(0xba8), TBL_ENTRY(0xba9), TBL_ENTRY(0xbaa), TBL_ENTRY(0xbab), - TBL_ENTRY(0xbac), TBL_ENTRY(0xbad), TBL_ENTRY(0xbae), TBL_ENTRY(0xbaf), - TBL_ENTRY(0xbb0), TBL_ENTRY(0xbb1), TBL_ENTRY(0xbb2), TBL_ENTRY(0xbb3), - TBL_ENTRY(0xbb4), TBL_ENTRY(0xbb5), TBL_ENTRY(0xbb6), TBL_ENTRY(0xbb7), - TBL_ENTRY(0xbb8), TBL_ENTRY(0xbb9), TBL_ENTRY(0xbba), TBL_ENTRY(0xbbb), - TBL_ENTRY(0xbbc), TBL_ENTRY(0xbbd), TBL_ENTRY(0xbbe), TBL_ENTRY(0xbbf), - TBL_ENTRY(0xbc0), TBL_ENTRY(0xbc1), TBL_ENTRY(0xbc2), TBL_ENTRY(0xbc3), - TBL_ENTRY(0xbc4), TBL_ENTRY(0xbc5), TBL_ENTRY(0xbc6), TBL_ENTRY(0xbc7), - TBL_ENTRY(0xbc8), TBL_ENTRY(0xbc9), TBL_ENTRY(0xbca), TBL_ENTRY(0xbcb), - TBL_ENTRY(0xbcc), TBL_ENTRY(0xbcd), TBL_ENTRY(0xbce), TBL_ENTRY(0xbcf), - TBL_ENTRY(0xbd0), TBL_ENTRY(0xbd1), TBL_ENTRY(0xbd2), TBL_ENTRY(0xbd3), - TBL_ENTRY(0xbd4), TBL_ENTRY(0xbd5), TBL_ENTRY(0xbd6), TBL_ENTRY(0xbd7), - TBL_ENTRY(0xbd8), TBL_ENTRY(0xbd9), TBL_ENTRY(0xbda), TBL_ENTRY(0xbdb), - TBL_ENTRY(0xbdc), TBL_ENTRY(0xbdd), TBL_ENTRY(0xbde), TBL_ENTRY(0xbdf), - TBL_ENTRY(0xbe0), TBL_ENTRY(0xbe1), TBL_ENTRY(0xbe2), TBL_ENTRY(0xbe3), - TBL_ENTRY(0xbe4), TBL_ENTRY(0xbe5), TBL_ENTRY(0xbe6), TBL_ENTRY(0xbe7), - TBL_ENTRY(0xbe8), TBL_ENTRY(0xbe9), TBL_ENTRY(0xbea), TBL_ENTRY(0xbeb), - TBL_ENTRY(0xbec), TBL_ENTRY(0xbed), TBL_ENTRY(0xbee), TBL_ENTRY(0xbef), - TBL_ENTRY(0xbf0), TBL_ENTRY(0xbf1), TBL_ENTRY(0xbf2), TBL_ENTRY(0xbf3), - TBL_ENTRY(0xbf4), TBL_ENTRY(0xbf5), TBL_ENTRY(0xbf6), TBL_ENTRY(0xbf7), - TBL_ENTRY(0xbf8), TBL_ENTRY(0xbf9), TBL_ENTRY(0xbfa), TBL_ENTRY(0xbfb), - TBL_ENTRY(0xbfc), TBL_ENTRY(0xbfd), TBL_ENTRY(0xbfe), TBL_ENTRY(0xbff), - TBL_ENTRY(0xc00), TBL_ENTRY(0xc01), TBL_ENTRY(0xc02), TBL_ENTRY(0xc03), - TBL_ENTRY(0xc04), TBL_ENTRY(0xc05), TBL_ENTRY(0xc06), TBL_ENTRY(0xc07), - TBL_ENTRY(0xc08), TBL_ENTRY(0xc09), TBL_ENTRY(0xc0a), TBL_ENTRY(0xc0b), - TBL_ENTRY(0xc0c), TBL_ENTRY(0xc0d), TBL_ENTRY(0xc0e), TBL_ENTRY(0xc0f), - TBL_ENTRY(0xc10), TBL_ENTRY(0xc11), TBL_ENTRY(0xc12), TBL_ENTRY(0xc13), - TBL_ENTRY(0xc14), TBL_ENTRY(0xc15), TBL_ENTRY(0xc16), TBL_ENTRY(0xc17), - TBL_ENTRY(0xc18), TBL_ENTRY(0xc19), TBL_ENTRY(0xc1a), TBL_ENTRY(0xc1b), - TBL_ENTRY(0xc1c), TBL_ENTRY(0xc1d), TBL_ENTRY(0xc1e), TBL_ENTRY(0xc1f), - TBL_ENTRY(0xc20), TBL_ENTRY(0xc21), TBL_ENTRY(0xc22), TBL_ENTRY(0xc23), - TBL_ENTRY(0xc24), TBL_ENTRY(0xc25), TBL_ENTRY(0xc26), TBL_ENTRY(0xc27), - TBL_ENTRY(0xc28), TBL_ENTRY(0xc29), TBL_ENTRY(0xc2a), TBL_ENTRY(0xc2b), - TBL_ENTRY(0xc2c), TBL_ENTRY(0xc2d), TBL_ENTRY(0xc2e), TBL_ENTRY(0xc2f), - TBL_ENTRY(0xc30), TBL_ENTRY(0xc31), TBL_ENTRY(0xc32), TBL_ENTRY(0xc33), - TBL_ENTRY(0xc34), TBL_ENTRY(0xc35), TBL_ENTRY(0xc36), TBL_ENTRY(0xc37), - TBL_ENTRY(0xc38), TBL_ENTRY(0xc39), TBL_ENTRY(0xc3a), TBL_ENTRY(0xc3b), - TBL_ENTRY(0xc3c), TBL_ENTRY(0xc3d), TBL_ENTRY(0xc3e), TBL_ENTRY(0xc3f), - TBL_ENTRY(0xc40), TBL_ENTRY(0xc41), TBL_ENTRY(0xc42), TBL_ENTRY(0xc43), - TBL_ENTRY(0xc44), TBL_ENTRY(0xc45), TBL_ENTRY(0xc46), TBL_ENTRY(0xc47), - TBL_ENTRY(0xc48), TBL_ENTRY(0xc49), TBL_ENTRY(0xc4a), TBL_ENTRY(0xc4b), - TBL_ENTRY(0xc4c), TBL_ENTRY(0xc4d), TBL_ENTRY(0xc4e), TBL_ENTRY(0xc4f), - TBL_ENTRY(0xc50), TBL_ENTRY(0xc51), TBL_ENTRY(0xc52), TBL_ENTRY(0xc53), - TBL_ENTRY(0xc54), TBL_ENTRY(0xc55), TBL_ENTRY(0xc56), TBL_ENTRY(0xc57), - TBL_ENTRY(0xc58), TBL_ENTRY(0xc59), TBL_ENTRY(0xc5a), TBL_ENTRY(0xc5b), - TBL_ENTRY(0xc5c), TBL_ENTRY(0xc5d), TBL_ENTRY(0xc5e), TBL_ENTRY(0xc5f), - TBL_ENTRY(0xc60), TBL_ENTRY(0xc61), TBL_ENTRY(0xc62), TBL_ENTRY(0xc63), - TBL_ENTRY(0xc64), TBL_ENTRY(0xc65), TBL_ENTRY(0xc66), TBL_ENTRY(0xc67), - TBL_ENTRY(0xc68), TBL_ENTRY(0xc69), TBL_ENTRY(0xc6a), TBL_ENTRY(0xc6b), - TBL_ENTRY(0xc6c), TBL_ENTRY(0xc6d), TBL_ENTRY(0xc6e), TBL_ENTRY(0xc6f), - TBL_ENTRY(0xc70), TBL_ENTRY(0xc71), TBL_ENTRY(0xc72), TBL_ENTRY(0xc73), - TBL_ENTRY(0xc74), TBL_ENTRY(0xc75), TBL_ENTRY(0xc76), TBL_ENTRY(0xc77), - TBL_ENTRY(0xc78), TBL_ENTRY(0xc79), TBL_ENTRY(0xc7a), TBL_ENTRY(0xc7b), - TBL_ENTRY(0xc7c), TBL_ENTRY(0xc7d), TBL_ENTRY(0xc7e), TBL_ENTRY(0xc7f), - TBL_ENTRY(0xc80), TBL_ENTRY(0xc81), TBL_ENTRY(0xc82), TBL_ENTRY(0xc83), - TBL_ENTRY(0xc84), TBL_ENTRY(0xc85), TBL_ENTRY(0xc86), TBL_ENTRY(0xc87), - TBL_ENTRY(0xc88), TBL_ENTRY(0xc89), TBL_ENTRY(0xc8a), TBL_ENTRY(0xc8b), - TBL_ENTRY(0xc8c), TBL_ENTRY(0xc8d), TBL_ENTRY(0xc8e), TBL_ENTRY(0xc8f), - TBL_ENTRY(0xc90), TBL_ENTRY(0xc91), TBL_ENTRY(0xc92), TBL_ENTRY(0xc93), - TBL_ENTRY(0xc94), TBL_ENTRY(0xc95), TBL_ENTRY(0xc96), TBL_ENTRY(0xc97), - TBL_ENTRY(0xc98), TBL_ENTRY(0xc99), TBL_ENTRY(0xc9a), TBL_ENTRY(0xc9b), - TBL_ENTRY(0xc9c), TBL_ENTRY(0xc9d), TBL_ENTRY(0xc9e), TBL_ENTRY(0xc9f), - TBL_ENTRY(0xca0), TBL_ENTRY(0xca1), TBL_ENTRY(0xca2), TBL_ENTRY(0xca3), - TBL_ENTRY(0xca4), TBL_ENTRY(0xca5), TBL_ENTRY(0xca6), TBL_ENTRY(0xca7), - TBL_ENTRY(0xca8), TBL_ENTRY(0xca9), TBL_ENTRY(0xcaa), TBL_ENTRY(0xcab), - TBL_ENTRY(0xcac), TBL_ENTRY(0xcad), TBL_ENTRY(0xcae), TBL_ENTRY(0xcaf), - TBL_ENTRY(0xcb0), TBL_ENTRY(0xcb1), TBL_ENTRY(0xcb2), TBL_ENTRY(0xcb3), - TBL_ENTRY(0xcb4), TBL_ENTRY(0xcb5), TBL_ENTRY(0xcb6), TBL_ENTRY(0xcb7), - TBL_ENTRY(0xcb8), TBL_ENTRY(0xcb9), TBL_ENTRY(0xcba), TBL_ENTRY(0xcbb), - TBL_ENTRY(0xcbc), TBL_ENTRY(0xcbd), TBL_ENTRY(0xcbe), TBL_ENTRY(0xcbf), - TBL_ENTRY(0xcc0), TBL_ENTRY(0xcc1), TBL_ENTRY(0xcc2), TBL_ENTRY(0xcc3), - TBL_ENTRY(0xcc4), TBL_ENTRY(0xcc5), TBL_ENTRY(0xcc6), TBL_ENTRY(0xcc7), - TBL_ENTRY(0xcc8), TBL_ENTRY(0xcc9), TBL_ENTRY(0xcca), TBL_ENTRY(0xccb), - TBL_ENTRY(0xccc), TBL_ENTRY(0xccd), TBL_ENTRY(0xcce), TBL_ENTRY(0xccf), - TBL_ENTRY(0xcd0), TBL_ENTRY(0xcd1), TBL_ENTRY(0xcd2), TBL_ENTRY(0xcd3), - TBL_ENTRY(0xcd4), TBL_ENTRY(0xcd5), TBL_ENTRY(0xcd6), TBL_ENTRY(0xcd7), - TBL_ENTRY(0xcd8), TBL_ENTRY(0xcd9), TBL_ENTRY(0xcda), TBL_ENTRY(0xcdb), - TBL_ENTRY(0xcdc), TBL_ENTRY(0xcdd), TBL_ENTRY(0xcde), TBL_ENTRY(0xcdf), - TBL_ENTRY(0xce0), TBL_ENTRY(0xce1), TBL_ENTRY(0xce2), TBL_ENTRY(0xce3), - TBL_ENTRY(0xce4), TBL_ENTRY(0xce5), TBL_ENTRY(0xce6), TBL_ENTRY(0xce7), - TBL_ENTRY(0xce8), TBL_ENTRY(0xce9), TBL_ENTRY(0xcea), TBL_ENTRY(0xceb), - TBL_ENTRY(0xcec), TBL_ENTRY(0xced), TBL_ENTRY(0xcee), TBL_ENTRY(0xcef), - TBL_ENTRY(0xcf0), TBL_ENTRY(0xcf1), TBL_ENTRY(0xcf2), TBL_ENTRY(0xcf3), - TBL_ENTRY(0xcf4), TBL_ENTRY(0xcf5), TBL_ENTRY(0xcf6), TBL_ENTRY(0xcf7), - TBL_ENTRY(0xcf8), TBL_ENTRY(0xcf9), TBL_ENTRY(0xcfa), TBL_ENTRY(0xcfb), - TBL_ENTRY(0xcfc), TBL_ENTRY(0xcfd), TBL_ENTRY(0xcfe), TBL_ENTRY(0xcff), - TBL_ENTRY(0xd00), TBL_ENTRY(0xd01), TBL_ENTRY(0xd02), TBL_ENTRY(0xd03), - TBL_ENTRY(0xd04), TBL_ENTRY(0xd05), TBL_ENTRY(0xd06), TBL_ENTRY(0xd07), - TBL_ENTRY(0xd08), TBL_ENTRY(0xd09), TBL_ENTRY(0xd0a), TBL_ENTRY(0xd0b), - TBL_ENTRY(0xd0c), TBL_ENTRY(0xd0d), TBL_ENTRY(0xd0e), TBL_ENTRY(0xd0f), - TBL_ENTRY(0xd10), TBL_ENTRY(0xd11), TBL_ENTRY(0xd12), TBL_ENTRY(0xd13), - TBL_ENTRY(0xd14), TBL_ENTRY(0xd15), TBL_ENTRY(0xd16), TBL_ENTRY(0xd17), - TBL_ENTRY(0xd18), TBL_ENTRY(0xd19), TBL_ENTRY(0xd1a), TBL_ENTRY(0xd1b), - TBL_ENTRY(0xd1c), TBL_ENTRY(0xd1d), TBL_ENTRY(0xd1e), TBL_ENTRY(0xd1f), - TBL_ENTRY(0xd20), TBL_ENTRY(0xd21), TBL_ENTRY(0xd22), TBL_ENTRY(0xd23), - TBL_ENTRY(0xd24), TBL_ENTRY(0xd25), TBL_ENTRY(0xd26), TBL_ENTRY(0xd27), - TBL_ENTRY(0xd28), TBL_ENTRY(0xd29), TBL_ENTRY(0xd2a), TBL_ENTRY(0xd2b), - TBL_ENTRY(0xd2c), TBL_ENTRY(0xd2d), TBL_ENTRY(0xd2e), TBL_ENTRY(0xd2f), - TBL_ENTRY(0xd30), TBL_ENTRY(0xd31), TBL_ENTRY(0xd32), TBL_ENTRY(0xd33), - TBL_ENTRY(0xd34), TBL_ENTRY(0xd35), TBL_ENTRY(0xd36), TBL_ENTRY(0xd37), - TBL_ENTRY(0xd38), TBL_ENTRY(0xd39), TBL_ENTRY(0xd3a), TBL_ENTRY(0xd3b), - TBL_ENTRY(0xd3c), TBL_ENTRY(0xd3d), TBL_ENTRY(0xd3e), TBL_ENTRY(0xd3f), - TBL_ENTRY(0xd40), TBL_ENTRY(0xd41), TBL_ENTRY(0xd42), TBL_ENTRY(0xd43), - TBL_ENTRY(0xd44), TBL_ENTRY(0xd45), TBL_ENTRY(0xd46), TBL_ENTRY(0xd47), - TBL_ENTRY(0xd48), TBL_ENTRY(0xd49), TBL_ENTRY(0xd4a), TBL_ENTRY(0xd4b), - TBL_ENTRY(0xd4c), TBL_ENTRY(0xd4d), TBL_ENTRY(0xd4e), TBL_ENTRY(0xd4f), - TBL_ENTRY(0xd50), TBL_ENTRY(0xd51), TBL_ENTRY(0xd52), TBL_ENTRY(0xd53), - TBL_ENTRY(0xd54), TBL_ENTRY(0xd55), TBL_ENTRY(0xd56), TBL_ENTRY(0xd57), - TBL_ENTRY(0xd58), TBL_ENTRY(0xd59), TBL_ENTRY(0xd5a), TBL_ENTRY(0xd5b), - TBL_ENTRY(0xd5c), TBL_ENTRY(0xd5d), TBL_ENTRY(0xd5e), TBL_ENTRY(0xd5f), - TBL_ENTRY(0xd60), TBL_ENTRY(0xd61), TBL_ENTRY(0xd62), TBL_ENTRY(0xd63), - TBL_ENTRY(0xd64), TBL_ENTRY(0xd65), TBL_ENTRY(0xd66), TBL_ENTRY(0xd67), - TBL_ENTRY(0xd68), TBL_ENTRY(0xd69), TBL_ENTRY(0xd6a), TBL_ENTRY(0xd6b), - TBL_ENTRY(0xd6c), TBL_ENTRY(0xd6d), TBL_ENTRY(0xd6e), TBL_ENTRY(0xd6f), - TBL_ENTRY(0xd70), TBL_ENTRY(0xd71), TBL_ENTRY(0xd72), TBL_ENTRY(0xd73), - TBL_ENTRY(0xd74), TBL_ENTRY(0xd75), TBL_ENTRY(0xd76), TBL_ENTRY(0xd77), - TBL_ENTRY(0xd78), TBL_ENTRY(0xd79), TBL_ENTRY(0xd7a), TBL_ENTRY(0xd7b), - TBL_ENTRY(0xd7c), TBL_ENTRY(0xd7d), TBL_ENTRY(0xd7e), TBL_ENTRY(0xd7f), - TBL_ENTRY(0xd80), TBL_ENTRY(0xd81), TBL_ENTRY(0xd82), TBL_ENTRY(0xd83), - TBL_ENTRY(0xd84), TBL_ENTRY(0xd85), TBL_ENTRY(0xd86), TBL_ENTRY(0xd87), - TBL_ENTRY(0xd88), TBL_ENTRY(0xd89), TBL_ENTRY(0xd8a), TBL_ENTRY(0xd8b), - TBL_ENTRY(0xd8c), TBL_ENTRY(0xd8d), TBL_ENTRY(0xd8e), TBL_ENTRY(0xd8f), - TBL_ENTRY(0xd90), TBL_ENTRY(0xd91), TBL_ENTRY(0xd92), TBL_ENTRY(0xd93), - TBL_ENTRY(0xd94), TBL_ENTRY(0xd95), TBL_ENTRY(0xd96), TBL_ENTRY(0xd97), - TBL_ENTRY(0xd98), TBL_ENTRY(0xd99), TBL_ENTRY(0xd9a), TBL_ENTRY(0xd9b), - TBL_ENTRY(0xd9c), TBL_ENTRY(0xd9d), TBL_ENTRY(0xd9e), TBL_ENTRY(0xd9f), - TBL_ENTRY(0xda0), TBL_ENTRY(0xda1), TBL_ENTRY(0xda2), TBL_ENTRY(0xda3), - TBL_ENTRY(0xda4), TBL_ENTRY(0xda5), TBL_ENTRY(0xda6), TBL_ENTRY(0xda7), - TBL_ENTRY(0xda8), TBL_ENTRY(0xda9), TBL_ENTRY(0xdaa), TBL_ENTRY(0xdab), - TBL_ENTRY(0xdac), TBL_ENTRY(0xdad), TBL_ENTRY(0xdae), TBL_ENTRY(0xdaf), - TBL_ENTRY(0xdb0), TBL_ENTRY(0xdb1), TBL_ENTRY(0xdb2), TBL_ENTRY(0xdb3), - TBL_ENTRY(0xdb4), TBL_ENTRY(0xdb5), TBL_ENTRY(0xdb6), TBL_ENTRY(0xdb7), - TBL_ENTRY(0xdb8), TBL_ENTRY(0xdb9), TBL_ENTRY(0xdba), TBL_ENTRY(0xdbb), - TBL_ENTRY(0xdbc), TBL_ENTRY(0xdbd), TBL_ENTRY(0xdbe), TBL_ENTRY(0xdbf), - TBL_ENTRY(0xdc0), TBL_ENTRY(0xdc1), TBL_ENTRY(0xdc2), TBL_ENTRY(0xdc3), - TBL_ENTRY(0xdc4), TBL_ENTRY(0xdc5), TBL_ENTRY(0xdc6), TBL_ENTRY(0xdc7), - TBL_ENTRY(0xdc8), TBL_ENTRY(0xdc9), TBL_ENTRY(0xdca), TBL_ENTRY(0xdcb), - TBL_ENTRY(0xdcc), TBL_ENTRY(0xdcd), TBL_ENTRY(0xdce), TBL_ENTRY(0xdcf), - TBL_ENTRY(0xdd0), TBL_ENTRY(0xdd1), TBL_ENTRY(0xdd2), TBL_ENTRY(0xdd3), - TBL_ENTRY(0xdd4), TBL_ENTRY(0xdd5), TBL_ENTRY(0xdd6), TBL_ENTRY(0xdd7), - TBL_ENTRY(0xdd8), TBL_ENTRY(0xdd9), TBL_ENTRY(0xdda), TBL_ENTRY(0xddb), - TBL_ENTRY(0xddc), TBL_ENTRY(0xddd), TBL_ENTRY(0xdde), TBL_ENTRY(0xddf), - TBL_ENTRY(0xde0), TBL_ENTRY(0xde1), TBL_ENTRY(0xde2), TBL_ENTRY(0xde3), - TBL_ENTRY(0xde4), TBL_ENTRY(0xde5), TBL_ENTRY(0xde6), TBL_ENTRY(0xde7), - TBL_ENTRY(0xde8), TBL_ENTRY(0xde9), TBL_ENTRY(0xdea), TBL_ENTRY(0xdeb), - TBL_ENTRY(0xdec), TBL_ENTRY(0xded), TBL_ENTRY(0xdee), TBL_ENTRY(0xdef), - TBL_ENTRY(0xdf0), TBL_ENTRY(0xdf1), TBL_ENTRY(0xdf2), TBL_ENTRY(0xdf3), - TBL_ENTRY(0xdf4), TBL_ENTRY(0xdf5), TBL_ENTRY(0xdf6), TBL_ENTRY(0xdf7), - TBL_ENTRY(0xdf8), TBL_ENTRY(0xdf9), TBL_ENTRY(0xdfa), TBL_ENTRY(0xdfb), - TBL_ENTRY(0xdfc), TBL_ENTRY(0xdfd), TBL_ENTRY(0xdfe), TBL_ENTRY(0xdff), - TBL_ENTRY(0xe00), TBL_ENTRY(0xe01), TBL_ENTRY(0xe02), TBL_ENTRY(0xe03), - TBL_ENTRY(0xe04), TBL_ENTRY(0xe05), TBL_ENTRY(0xe06), TBL_ENTRY(0xe07), - TBL_ENTRY(0xe08), TBL_ENTRY(0xe09), TBL_ENTRY(0xe0a), TBL_ENTRY(0xe0b), - TBL_ENTRY(0xe0c), TBL_ENTRY(0xe0d), TBL_ENTRY(0xe0e), TBL_ENTRY(0xe0f), - TBL_ENTRY(0xe10), TBL_ENTRY(0xe11), TBL_ENTRY(0xe12), TBL_ENTRY(0xe13), - TBL_ENTRY(0xe14), TBL_ENTRY(0xe15), TBL_ENTRY(0xe16), TBL_ENTRY(0xe17), - TBL_ENTRY(0xe18), TBL_ENTRY(0xe19), TBL_ENTRY(0xe1a), TBL_ENTRY(0xe1b), - TBL_ENTRY(0xe1c), TBL_ENTRY(0xe1d), TBL_ENTRY(0xe1e), TBL_ENTRY(0xe1f), - TBL_ENTRY(0xe20), TBL_ENTRY(0xe21), TBL_ENTRY(0xe22), TBL_ENTRY(0xe23), - TBL_ENTRY(0xe24), TBL_ENTRY(0xe25), TBL_ENTRY(0xe26), TBL_ENTRY(0xe27), - TBL_ENTRY(0xe28), TBL_ENTRY(0xe29), TBL_ENTRY(0xe2a), TBL_ENTRY(0xe2b), - TBL_ENTRY(0xe2c), TBL_ENTRY(0xe2d), TBL_ENTRY(0xe2e), TBL_ENTRY(0xe2f), - TBL_ENTRY(0xe30), TBL_ENTRY(0xe31), TBL_ENTRY(0xe32), TBL_ENTRY(0xe33), - TBL_ENTRY(0xe34), TBL_ENTRY(0xe35), TBL_ENTRY(0xe36), TBL_ENTRY(0xe37), - TBL_ENTRY(0xe38), TBL_ENTRY(0xe39), TBL_ENTRY(0xe3a), TBL_ENTRY(0xe3b), - TBL_ENTRY(0xe3c), TBL_ENTRY(0xe3d), TBL_ENTRY(0xe3e), TBL_ENTRY(0xe3f), - TBL_ENTRY(0xe40), TBL_ENTRY(0xe41), TBL_ENTRY(0xe42), TBL_ENTRY(0xe43), - TBL_ENTRY(0xe44), TBL_ENTRY(0xe45), TBL_ENTRY(0xe46), TBL_ENTRY(0xe47), - TBL_ENTRY(0xe48), TBL_ENTRY(0xe49), TBL_ENTRY(0xe4a), TBL_ENTRY(0xe4b), - TBL_ENTRY(0xe4c), TBL_ENTRY(0xe4d), TBL_ENTRY(0xe4e), TBL_ENTRY(0xe4f), - TBL_ENTRY(0xe50), TBL_ENTRY(0xe51), TBL_ENTRY(0xe52), TBL_ENTRY(0xe53), - TBL_ENTRY(0xe54), TBL_ENTRY(0xe55), TBL_ENTRY(0xe56), TBL_ENTRY(0xe57), - TBL_ENTRY(0xe58), TBL_ENTRY(0xe59), TBL_ENTRY(0xe5a), TBL_ENTRY(0xe5b), - TBL_ENTRY(0xe5c), TBL_ENTRY(0xe5d), TBL_ENTRY(0xe5e), TBL_ENTRY(0xe5f), - TBL_ENTRY(0xe60), TBL_ENTRY(0xe61), TBL_ENTRY(0xe62), TBL_ENTRY(0xe63), - TBL_ENTRY(0xe64), TBL_ENTRY(0xe65), TBL_ENTRY(0xe66), TBL_ENTRY(0xe67), - TBL_ENTRY(0xe68), TBL_ENTRY(0xe69), TBL_ENTRY(0xe6a), TBL_ENTRY(0xe6b), - TBL_ENTRY(0xe6c), TBL_ENTRY(0xe6d), TBL_ENTRY(0xe6e), TBL_ENTRY(0xe6f), - TBL_ENTRY(0xe70), TBL_ENTRY(0xe71), TBL_ENTRY(0xe72), TBL_ENTRY(0xe73), - TBL_ENTRY(0xe74), TBL_ENTRY(0xe75), TBL_ENTRY(0xe76), TBL_ENTRY(0xe77), - TBL_ENTRY(0xe78), TBL_ENTRY(0xe79), TBL_ENTRY(0xe7a), TBL_ENTRY(0xe7b), - TBL_ENTRY(0xe7c), TBL_ENTRY(0xe7d), TBL_ENTRY(0xe7e), TBL_ENTRY(0xe7f), - TBL_ENTRY(0xe80), TBL_ENTRY(0xe81), TBL_ENTRY(0xe82), TBL_ENTRY(0xe83), - TBL_ENTRY(0xe84), TBL_ENTRY(0xe85), TBL_ENTRY(0xe86), TBL_ENTRY(0xe87), - TBL_ENTRY(0xe88), TBL_ENTRY(0xe89), TBL_ENTRY(0xe8a), TBL_ENTRY(0xe8b), - TBL_ENTRY(0xe8c), TBL_ENTRY(0xe8d), TBL_ENTRY(0xe8e), TBL_ENTRY(0xe8f), - TBL_ENTRY(0xe90), TBL_ENTRY(0xe91), TBL_ENTRY(0xe92), TBL_ENTRY(0xe93), - TBL_ENTRY(0xe94), TBL_ENTRY(0xe95), TBL_ENTRY(0xe96), TBL_ENTRY(0xe97), - TBL_ENTRY(0xe98), TBL_ENTRY(0xe99), TBL_ENTRY(0xe9a), TBL_ENTRY(0xe9b), - TBL_ENTRY(0xe9c), TBL_ENTRY(0xe9d), TBL_ENTRY(0xe9e), TBL_ENTRY(0xe9f), - TBL_ENTRY(0xea0), TBL_ENTRY(0xea1), TBL_ENTRY(0xea2), TBL_ENTRY(0xea3), - TBL_ENTRY(0xea4), TBL_ENTRY(0xea5), TBL_ENTRY(0xea6), TBL_ENTRY(0xea7), - TBL_ENTRY(0xea8), TBL_ENTRY(0xea9), TBL_ENTRY(0xeaa), TBL_ENTRY(0xeab), - TBL_ENTRY(0xeac), TBL_ENTRY(0xead), TBL_ENTRY(0xeae), TBL_ENTRY(0xeaf), - TBL_ENTRY(0xeb0), TBL_ENTRY(0xeb1), TBL_ENTRY(0xeb2), TBL_ENTRY(0xeb3), - TBL_ENTRY(0xeb4), TBL_ENTRY(0xeb5), TBL_ENTRY(0xeb6), TBL_ENTRY(0xeb7), - TBL_ENTRY(0xeb8), TBL_ENTRY(0xeb9), TBL_ENTRY(0xeba), TBL_ENTRY(0xebb), - TBL_ENTRY(0xebc), TBL_ENTRY(0xebd), TBL_ENTRY(0xebe), TBL_ENTRY(0xebf), - TBL_ENTRY(0xec0), TBL_ENTRY(0xec1), TBL_ENTRY(0xec2), TBL_ENTRY(0xec3), - TBL_ENTRY(0xec4), TBL_ENTRY(0xec5), TBL_ENTRY(0xec6), TBL_ENTRY(0xec7), - TBL_ENTRY(0xec8), TBL_ENTRY(0xec9), TBL_ENTRY(0xeca), TBL_ENTRY(0xecb), - TBL_ENTRY(0xecc), TBL_ENTRY(0xecd), TBL_ENTRY(0xece), TBL_ENTRY(0xecf), - TBL_ENTRY(0xed0), TBL_ENTRY(0xed1), TBL_ENTRY(0xed2), TBL_ENTRY(0xed3), - TBL_ENTRY(0xed4), TBL_ENTRY(0xed5), TBL_ENTRY(0xed6), TBL_ENTRY(0xed7), - TBL_ENTRY(0xed8), TBL_ENTRY(0xed9), TBL_ENTRY(0xeda), TBL_ENTRY(0xedb), - TBL_ENTRY(0xedc), TBL_ENTRY(0xedd), TBL_ENTRY(0xede), TBL_ENTRY(0xedf), - TBL_ENTRY(0xee0), TBL_ENTRY(0xee1), TBL_ENTRY(0xee2), TBL_ENTRY(0xee3), - TBL_ENTRY(0xee4), TBL_ENTRY(0xee5), TBL_ENTRY(0xee6), TBL_ENTRY(0xee7), - TBL_ENTRY(0xee8), TBL_ENTRY(0xee9), TBL_ENTRY(0xeea), TBL_ENTRY(0xeeb), - TBL_ENTRY(0xeec), TBL_ENTRY(0xeed), TBL_ENTRY(0xeee), TBL_ENTRY(0xeef), - TBL_ENTRY(0xef0), TBL_ENTRY(0xef1), TBL_ENTRY(0xef2), TBL_ENTRY(0xef3), - TBL_ENTRY(0xef4), TBL_ENTRY(0xef5), TBL_ENTRY(0xef6), TBL_ENTRY(0xef7), - TBL_ENTRY(0xef8), TBL_ENTRY(0xef9), TBL_ENTRY(0xefa), TBL_ENTRY(0xefb), - TBL_ENTRY(0xefc), TBL_ENTRY(0xefd), TBL_ENTRY(0xefe), TBL_ENTRY(0xeff), - TBL_ENTRY(0xf00), TBL_ENTRY(0xf01), TBL_ENTRY(0xf02), TBL_ENTRY(0xf03), - TBL_ENTRY(0xf04), TBL_ENTRY(0xf05), TBL_ENTRY(0xf06), TBL_ENTRY(0xf07), - TBL_ENTRY(0xf08), TBL_ENTRY(0xf09), TBL_ENTRY(0xf0a), TBL_ENTRY(0xf0b), - TBL_ENTRY(0xf0c), TBL_ENTRY(0xf0d), TBL_ENTRY(0xf0e), TBL_ENTRY(0xf0f), - TBL_ENTRY(0xf10), TBL_ENTRY(0xf11), TBL_ENTRY(0xf12), TBL_ENTRY(0xf13), - TBL_ENTRY(0xf14), TBL_ENTRY(0xf15), TBL_ENTRY(0xf16), TBL_ENTRY(0xf17), - TBL_ENTRY(0xf18), TBL_ENTRY(0xf19), TBL_ENTRY(0xf1a), TBL_ENTRY(0xf1b), - TBL_ENTRY(0xf1c), TBL_ENTRY(0xf1d), TBL_ENTRY(0xf1e), TBL_ENTRY(0xf1f), - TBL_ENTRY(0xf20), TBL_ENTRY(0xf21), TBL_ENTRY(0xf22), TBL_ENTRY(0xf23), - TBL_ENTRY(0xf24), TBL_ENTRY(0xf25), TBL_ENTRY(0xf26), TBL_ENTRY(0xf27), - TBL_ENTRY(0xf28), TBL_ENTRY(0xf29), TBL_ENTRY(0xf2a), TBL_ENTRY(0xf2b), - TBL_ENTRY(0xf2c), TBL_ENTRY(0xf2d), TBL_ENTRY(0xf2e), TBL_ENTRY(0xf2f), - TBL_ENTRY(0xf30), TBL_ENTRY(0xf31), TBL_ENTRY(0xf32), TBL_ENTRY(0xf33), - TBL_ENTRY(0xf34), TBL_ENTRY(0xf35), TBL_ENTRY(0xf36), TBL_ENTRY(0xf37), - TBL_ENTRY(0xf38), TBL_ENTRY(0xf39), TBL_ENTRY(0xf3a), TBL_ENTRY(0xf3b), - TBL_ENTRY(0xf3c), TBL_ENTRY(0xf3d), TBL_ENTRY(0xf3e), TBL_ENTRY(0xf3f), - TBL_ENTRY(0xf40), TBL_ENTRY(0xf41), TBL_ENTRY(0xf42), TBL_ENTRY(0xf43), - TBL_ENTRY(0xf44), TBL_ENTRY(0xf45), TBL_ENTRY(0xf46), TBL_ENTRY(0xf47), - TBL_ENTRY(0xf48), TBL_ENTRY(0xf49), TBL_ENTRY(0xf4a), TBL_ENTRY(0xf4b), - TBL_ENTRY(0xf4c), TBL_ENTRY(0xf4d), TBL_ENTRY(0xf4e), TBL_ENTRY(0xf4f), - TBL_ENTRY(0xf50), TBL_ENTRY(0xf51), TBL_ENTRY(0xf52), TBL_ENTRY(0xf53), - TBL_ENTRY(0xf54), TBL_ENTRY(0xf55), TBL_ENTRY(0xf56), TBL_ENTRY(0xf57), - TBL_ENTRY(0xf58), TBL_ENTRY(0xf59), TBL_ENTRY(0xf5a), TBL_ENTRY(0xf5b), - TBL_ENTRY(0xf5c), TBL_ENTRY(0xf5d), TBL_ENTRY(0xf5e), TBL_ENTRY(0xf5f), - TBL_ENTRY(0xf60), TBL_ENTRY(0xf61), TBL_ENTRY(0xf62), TBL_ENTRY(0xf63), - TBL_ENTRY(0xf64), TBL_ENTRY(0xf65), TBL_ENTRY(0xf66), TBL_ENTRY(0xf67), - TBL_ENTRY(0xf68), TBL_ENTRY(0xf69), TBL_ENTRY(0xf6a), TBL_ENTRY(0xf6b), - TBL_ENTRY(0xf6c), TBL_ENTRY(0xf6d), TBL_ENTRY(0xf6e), TBL_ENTRY(0xf6f), - TBL_ENTRY(0xf70), TBL_ENTRY(0xf71), TBL_ENTRY(0xf72), TBL_ENTRY(0xf73), - TBL_ENTRY(0xf74), TBL_ENTRY(0xf75), TBL_ENTRY(0xf76), TBL_ENTRY(0xf77), - TBL_ENTRY(0xf78), TBL_ENTRY(0xf79), TBL_ENTRY(0xf7a), TBL_ENTRY(0xf7b), - TBL_ENTRY(0xf7c), TBL_ENTRY(0xf7d), TBL_ENTRY(0xf7e), TBL_ENTRY(0xf7f), - TBL_ENTRY(0xf80), TBL_ENTRY(0xf81), TBL_ENTRY(0xf82), TBL_ENTRY(0xf83), - TBL_ENTRY(0xf84), TBL_ENTRY(0xf85), TBL_ENTRY(0xf86), TBL_ENTRY(0xf87), - TBL_ENTRY(0xf88), TBL_ENTRY(0xf89), TBL_ENTRY(0xf8a), TBL_ENTRY(0xf8b), - TBL_ENTRY(0xf8c), TBL_ENTRY(0xf8d), TBL_ENTRY(0xf8e), TBL_ENTRY(0xf8f), - TBL_ENTRY(0xf90), TBL_ENTRY(0xf91), TBL_ENTRY(0xf92), TBL_ENTRY(0xf93), - TBL_ENTRY(0xf94), TBL_ENTRY(0xf95), TBL_ENTRY(0xf96), TBL_ENTRY(0xf97), - TBL_ENTRY(0xf98), TBL_ENTRY(0xf99), TBL_ENTRY(0xf9a), TBL_ENTRY(0xf9b), - TBL_ENTRY(0xf9c), TBL_ENTRY(0xf9d), TBL_ENTRY(0xf9e), TBL_ENTRY(0xf9f), - TBL_ENTRY(0xfa0), TBL_ENTRY(0xfa1), TBL_ENTRY(0xfa2), TBL_ENTRY(0xfa3), - TBL_ENTRY(0xfa4), TBL_ENTRY(0xfa5), TBL_ENTRY(0xfa6), TBL_ENTRY(0xfa7), - TBL_ENTRY(0xfa8), TBL_ENTRY(0xfa9), TBL_ENTRY(0xfaa), TBL_ENTRY(0xfab), - TBL_ENTRY(0xfac), TBL_ENTRY(0xfad), TBL_ENTRY(0xfae), TBL_ENTRY(0xfaf), - TBL_ENTRY(0xfb0), TBL_ENTRY(0xfb1), TBL_ENTRY(0xfb2), TBL_ENTRY(0xfb3), - TBL_ENTRY(0xfb4), TBL_ENTRY(0xfb5), TBL_ENTRY(0xfb6), TBL_ENTRY(0xfb7), - TBL_ENTRY(0xfb8), TBL_ENTRY(0xfb9), TBL_ENTRY(0xfba), TBL_ENTRY(0xfbb), - TBL_ENTRY(0xfbc), TBL_ENTRY(0xfbd), TBL_ENTRY(0xfbe), TBL_ENTRY(0xfbf), - TBL_ENTRY(0xfc0), TBL_ENTRY(0xfc1), TBL_ENTRY(0xfc2), TBL_ENTRY(0xfc3), - TBL_ENTRY(0xfc4), TBL_ENTRY(0xfc5), TBL_ENTRY(0xfc6), TBL_ENTRY(0xfc7), - TBL_ENTRY(0xfc8), TBL_ENTRY(0xfc9), TBL_ENTRY(0xfca), TBL_ENTRY(0xfcb), - TBL_ENTRY(0xfcc), TBL_ENTRY(0xfcd), TBL_ENTRY(0xfce), TBL_ENTRY(0xfcf), - TBL_ENTRY(0xfd0), TBL_ENTRY(0xfd1), TBL_ENTRY(0xfd2), TBL_ENTRY(0xfd3), - TBL_ENTRY(0xfd4), TBL_ENTRY(0xfd5), TBL_ENTRY(0xfd6), TBL_ENTRY(0xfd7), - TBL_ENTRY(0xfd8), TBL_ENTRY(0xfd9), TBL_ENTRY(0xfda), TBL_ENTRY(0xfdb), - TBL_ENTRY(0xfdc), TBL_ENTRY(0xfdd), TBL_ENTRY(0xfde), TBL_ENTRY(0xfdf), - TBL_ENTRY(0xfe0), TBL_ENTRY(0xfe1), TBL_ENTRY(0xfe2), TBL_ENTRY(0xfe3), - TBL_ENTRY(0xfe4), TBL_ENTRY(0xfe5), TBL_ENTRY(0xfe6), TBL_ENTRY(0xfe7), - TBL_ENTRY(0xfe8), TBL_ENTRY(0xfe9), TBL_ENTRY(0xfea), TBL_ENTRY(0xfeb), - TBL_ENTRY(0xfec), TBL_ENTRY(0xfed), TBL_ENTRY(0xfee), TBL_ENTRY(0xfef), - TBL_ENTRY(0xff0), TBL_ENTRY(0xff1), TBL_ENTRY(0xff2), TBL_ENTRY(0xff3), - TBL_ENTRY(0xff4), TBL_ENTRY(0xff5), TBL_ENTRY(0xff6), TBL_ENTRY(0xff7), - TBL_ENTRY(0xff8), TBL_ENTRY(0xff9), TBL_ENTRY(0xffa), TBL_ENTRY(0xffb), - TBL_ENTRY(0xffc), TBL_ENTRY(0xffd), TBL_ENTRY(0xffe), TBL_ENTRY(0xfff), -}; diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/pll_init.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/pll_init.c index 68b9d5f..b83582f 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/pll_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/pll_init.c @@ -11,7 +11,7 @@ #undef DPLL_SSC_RATE_1PER -void dpll_init(void) +static void dpll_init(void) { u32 tmp; @@ -42,7 +42,7 @@ void dpll_init(void) writel(tmp, SC_DPLLCTRL2); } -void upll_init(void) +static void upll_init(void) { u32 tmp, clk_mode_upll, clk_mode_axosel; @@ -82,7 +82,7 @@ void upll_init(void) writel(tmp, SC_UPLLCTRL); } -void vpll_init(void) +static void vpll_init(void) { u32 tmp, clk_mode_axosel; diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/sg_init.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/sg_init.c index b4dd799..2cc5df6 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/sg_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/sg_init.c @@ -21,7 +21,7 @@ void sg_init(void) #endif writel(tmp, SG_MEMCONF); - /* Input ports must be enabled deasserting reset of cores */ + /* Input ports must be enabled before deasserting reset of cores */ tmp = readl(SG_IECTRL); tmp |= 0x1; writel(tmp, SG_IECTRL); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c index 8788916..bbc3dcb 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c @@ -9,7 +9,7 @@ #include <asm/arch/umc-regs.h> #include <asm/arch/ddrphy-regs.h> -static inline void umc_start_ssif(void __iomem *ssif_base) +static void umc_start_ssif(void __iomem *ssif_base) { writel(0x00000000, ssif_base + 0x0000b004); writel(0xffffffff, ssif_base + 0x0000c004); @@ -43,8 +43,8 @@ static inline void umc_start_ssif(void __iomem *ssif_base) writel(0x00000001, ssif_base + UMC_DMDRST); } -void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, - int size, int freq) +static void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, + int size, int freq) { if (freq == 1333) { writel(0x45990b11, dramcont + UMC_CMDCTLA); @@ -119,7 +119,7 @@ void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, writel(0x00000520, dramcont + UMC_DFICUPDCTLA); } -static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) +static int umc_init_sub(int freq, int size_ch0, int size_ch1) { void __iomem *ssif_base = (void __iomem *)UMC_SSIF_BASE; void __iomem *ca_base0 = (void __iomem *)UMC_CA_BASE(0); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/pll_init.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/pll_init.c index 2dcc089..1db90f8 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/pll_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/pll_init.c @@ -11,7 +11,7 @@ #undef DPLL_SSC_RATE_1PER -void dpll_init(void) +static void dpll_init(void) { u32 tmp; @@ -46,7 +46,7 @@ void dpll_init(void) writel(tmp, SC_DPLLCTRL2); } -void stop_mpll(void) +static void stop_mpll(void) { u32 tmp; @@ -62,7 +62,7 @@ void stop_mpll(void) ; } -void vpll_init(void) +static void vpll_init(void) { u32 tmp, clk_mode_axosel; diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/sg_init.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/sg_init.c index b4dd799..b7c4b10 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/sg_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/sg_init.c @@ -21,8 +21,8 @@ void sg_init(void) #endif writel(tmp, SG_MEMCONF); - /* Input ports must be enabled deasserting reset of cores */ + /* Input ports must be enabled before deasserting reset of cores */ tmp = readl(SG_IECTRL); - tmp |= 0x1; + tmp |= 1 << 6; writel(tmp, SG_IECTRL); } diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c index 1973ab0..2d1bde6 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c @@ -9,7 +9,7 @@ #include <asm/arch/umc-regs.h> #include <asm/arch/ddrphy-regs.h> -static inline void umc_start_ssif(void __iomem *ssif_base) +static void umc_start_ssif(void __iomem *ssif_base) { writel(0x00000001, ssif_base + 0x0000b004); writel(0xffffffff, ssif_base + 0x0000c004); @@ -52,8 +52,8 @@ static inline void umc_start_ssif(void __iomem *ssif_base) writel(0x00000001, ssif_base + UMC_DMDRST); } -void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, - int size, int freq) +static void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, + int size, int freq) { writel(0x66bb0f17, dramcont + UMC_CMDCTLA); writel(0x18c6aa44, dramcont + UMC_CMDCTLB); @@ -88,7 +88,7 @@ void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, writel(0x80000020, dramcont + UMC_DFICUPDCTLA); } -static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) +static int umc_init_sub(int freq, int size_ch0, int size_ch1) { void __iomem *ssif_base = (void __iomem *)UMC_SSIF_BASE; void __iomem *ca_base0 = (void __iomem *)UMC_CA_BASE(0); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/pll_init.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/pll_init.c index 4d87053..4b82700 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/pll_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/pll_init.c @@ -9,7 +9,7 @@ #include <asm/arch/sc-regs.h> #include <asm/arch/sg-regs.h> -void dpll_init(void) +static void dpll_init(void) { u32 tmp; /* @@ -54,7 +54,7 @@ void dpll_init(void) writel(tmp, SC_DPLLCTRL2); } -void upll_init(void) +static void upll_init(void) { u32 tmp, clk_mode_upll, clk_mode_axosel; @@ -94,7 +94,7 @@ void upll_init(void) writel(tmp, SC_UPLLCTRL); } -void vpll_init(void) +static void vpll_init(void) { u32 tmp, clk_mode_axosel; diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c index 2e0f9ae..2fbc73a 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c @@ -9,7 +9,7 @@ #include <asm/arch/umc-regs.h> #include <asm/arch/ddrphy-regs.h> -static inline void umc_start_ssif(void __iomem *ssif_base) +static void umc_start_ssif(void __iomem *ssif_base) { writel(0x00000000, ssif_base + 0x0000b004); writel(0xffffffff, ssif_base + 0x0000c004); @@ -43,8 +43,8 @@ static inline void umc_start_ssif(void __iomem *ssif_base) writel(0x00000001, ssif_base + UMC_DMDRST); } -void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, - int size, int freq) +static void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, + int size, int freq) { #ifdef CONFIG_DDR_STANDARD writel(0x55990b11, dramcont + UMC_CMDCTLA); @@ -99,7 +99,7 @@ void umc_dramcont_init(void __iomem *dramcont, void __iomem *ca_base, writel(0x00000520, dramcont + UMC_DFICUPDCTLA); } -static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) +static int umc_init_sub(int freq, int size_ch0, int size_ch1) { void __iomem *ssif_base = (void __iomem *)UMC_SSIF_BASE; void __iomem *ca_base0 = (void __iomem *)UMC_CA_BASE(0); diff --git a/arch/arm/cpu/armv7/zynq/spl.c b/arch/arm/cpu/armv7/zynq/spl.c index 31627f9..0936bdd 100644 --- a/arch/arm/cpu/armv7/zynq/spl.c +++ b/arch/arm/cpu/armv7/zynq/spl.c @@ -20,9 +20,6 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* Set global data pointer. */ - gd = &gdata; - preloader_console_init(); arch_cpu_init(); board_init_r(NULL, 0); diff --git a/arch/arm/include/asm/arch-rmobile/r8a7790.h b/arch/arm/include/asm/arch-rmobile/r8a7790.h index 132d58c..748b802 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7790.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7790.h @@ -28,6 +28,12 @@ #define MSTP10_BITS 0xFFFEFFE0 #define MSTP11_BITS 0x00000000 +/* SDHI */ +#define CONFIG_SYS_SH_SDHI1_BASE 0xEE120000 +#define CONFIG_SYS_SH_SDHI2_BASE 0xEE140000 +#define CONFIG_SYS_SH_SDHI3_BASE 0xEE160000 +#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 4 + #define R8A7790_CUT_ES2X 2 #define IS_R8A7790_ES2() \ (rmobile_get_cpu_rev_integer() == R8A7790_CUT_ES2X) diff --git a/arch/arm/include/asm/arch-rmobile/r8a7791.h b/arch/arm/include/asm/arch-rmobile/r8a7791.h index d2cbcd7..1d06b65 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7791.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7791.h @@ -17,6 +17,11 @@ /* SH-I2C */ #define CONFIG_SYS_I2C_SH_BASE2 0xE60B0000 +/* SDHI */ +#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000 +#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000 +#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3 + #define DBSC3_1_QOS_R0_BASE 0xE67A1000 #define DBSC3_1_QOS_R1_BASE 0xE67A1100 #define DBSC3_1_QOS_R2_BASE 0xE67A1200 diff --git a/arch/arm/include/asm/arch-rmobile/r8a7793.h b/arch/arm/include/asm/arch-rmobile/r8a7793.h index 1abdeb7..3efc62a 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7793.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7793.h @@ -18,6 +18,11 @@ /* SH-I2C */ #define CONFIG_SYS_I2C_SH_BASE2 0xE60B0000 +/* SDHI */ +#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000 +#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000 +#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3 + #define DBSC3_1_QOS_R0_BASE 0xE67A1000 #define DBSC3_1_QOS_R1_BASE 0xE67A1100 #define DBSC3_1_QOS_R2_BASE 0xE67A1200 diff --git a/arch/arm/include/asm/arch-rmobile/r8a7794.h b/arch/arm/include/asm/arch-rmobile/r8a7794.h index d7c9004..6d11fa4 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7794.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7794.h @@ -27,4 +27,9 @@ #define MSTP10_BITS 0xFFFEFFE0 #define MSTP11_BITS 0x000001C0 +/* SDHI */ +#define CONFIG_SYS_SH_SDHI1_BASE 0xEE140000 +#define CONFIG_SYS_SH_SDHI2_BASE 0xEE160000 +#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 3 + #endif /* __ASM_ARCH_R8A7794_H */ diff --git a/arch/arm/include/asm/arch-rmobile/rcar-base.h b/arch/arm/include/asm/arch-rmobile/rcar-base.h index 23c4bba..d594cd7 100644 --- a/arch/arm/include/asm/arch-rmobile/rcar-base.h +++ b/arch/arm/include/asm/arch-rmobile/rcar-base.h @@ -82,6 +82,9 @@ #define CONFIG_SYS_RCAR_I2C2_BASE 0xE6530000 #define CONFIG_SYS_RCAR_I2C3_BASE 0xE6540000 +/* SDHI */ +#define CONFIG_SYS_SH_SDHI0_BASE 0xEE100000 + #define S3C_BASE 0xE6784000 #define S3C_INT_BASE 0xE6784A00 #define S3C_MEDIA_BASE 0xE6784B00 diff --git a/arch/arm/include/asm/arch-rmobile/sh_sdhi.h b/arch/arm/include/asm/arch-rmobile/sh_sdhi.h new file mode 100644 index 0000000..057bf3f --- /dev/null +++ b/arch/arm/include/asm/arch-rmobile/sh_sdhi.h @@ -0,0 +1,168 @@ +/* + * drivers/mmc/sh-sdhi.h + * + * SD/MMC driver for Reneas rmobile ARM SoCs + * + * Copyright (C) 2013-2014 Renesas Electronics Corporation + * Copyright (C) 2008-2009 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _SH_SDHI_H +#define _SH_SDHI_H + +#define SDHI_CMD (0x0000 >> 1) +#define SDHI_PORTSEL (0x0004 >> 1) +#define SDHI_ARG0 (0x0008 >> 1) +#define SDHI_ARG1 (0x000C >> 1) +#define SDHI_STOP (0x0010 >> 1) +#define SDHI_SECCNT (0x0014 >> 1) +#define SDHI_RSP00 (0x0018 >> 1) +#define SDHI_RSP01 (0x001C >> 1) +#define SDHI_RSP02 (0x0020 >> 1) +#define SDHI_RSP03 (0x0024 >> 1) +#define SDHI_RSP04 (0x0028 >> 1) +#define SDHI_RSP05 (0x002C >> 1) +#define SDHI_RSP06 (0x0030 >> 1) +#define SDHI_RSP07 (0x0034 >> 1) +#define SDHI_INFO1 (0x0038 >> 1) +#define SDHI_INFO2 (0x003C >> 1) +#define SDHI_INFO1_MASK (0x0040 >> 1) +#define SDHI_INFO2_MASK (0x0044 >> 1) +#define SDHI_CLK_CTRL (0x0048 >> 1) +#define SDHI_SIZE (0x004C >> 1) +#define SDHI_OPTION (0x0050 >> 1) +#define SDHI_ERR_STS1 (0x0058 >> 1) +#define SDHI_ERR_STS2 (0x005C >> 1) +#define SDHI_BUF0 (0x0060 >> 1) +#define SDHI_SDIO_MODE (0x0068 >> 1) +#define SDHI_SDIO_INFO1 (0x006C >> 1) +#define SDHI_SDIO_INFO1_MASK (0x0070 >> 1) +#define SDHI_CC_EXT_MODE (0x01B0 >> 1) +#define SDHI_SOFT_RST (0x01C0 >> 1) +#define SDHI_VERSION (0x01C4 >> 1) +#define SDHI_HOST_MODE (0x01C8 >> 1) +#define SDHI_SDIF_MODE (0x01CC >> 1) +#define SDHI_EXT_SWAP (0x01E0 >> 1) +#define SDHI_SD_DMACR (0x0324 >> 1) + +/* SDHI CMD VALUE */ +#define CMD_MASK 0x0000ffff +#define SDHI_APP 0x0040 +#define SDHI_SD_APP_SEND_SCR 0x0073 +#define SDHI_SD_SWITCH 0x1C06 + +/* SDHI_PORTSEL */ +#define USE_1PORT (1 << 8) /* 1 port */ + +/* SDHI_ARG */ +#define ARG0_MASK 0x0000ffff +#define ARG1_MASK 0x0000ffff + +/* SDHI_STOP */ +#define STOP_SEC_ENABLE (1 << 8) + +/* SDHI_INFO1 */ +#define INFO1_RESP_END (1 << 0) +#define INFO1_ACCESS_END (1 << 2) +#define INFO1_CARD_RE (1 << 3) +#define INFO1_CARD_IN (1 << 4) +#define INFO1_ISD0CD (1 << 5) +#define INFO1_WRITE_PRO (1 << 7) +#define INFO1_DATA3_CARD_RE (1 << 8) +#define INFO1_DATA3_CARD_IN (1 << 9) +#define INFO1_DATA3 (1 << 10) + +/* SDHI_INFO2 */ +#define INFO2_CMD_ERROR (1 << 0) +#define INFO2_CRC_ERROR (1 << 1) +#define INFO2_END_ERROR (1 << 2) +#define INFO2_TIMEOUT (1 << 3) +#define INFO2_BUF_ILL_WRITE (1 << 4) +#define INFO2_BUF_ILL_READ (1 << 5) +#define INFO2_RESP_TIMEOUT (1 << 6) +#define INFO2_SDDAT0 (1 << 7) +#define INFO2_BRE_ENABLE (1 << 8) +#define INFO2_BWE_ENABLE (1 << 9) +#define INFO2_CBUSY (1 << 14) +#define INFO2_ILA (1 << 15) +#define INFO2_ALL_ERR (0x807f) + +/* SDHI_INFO1_MASK */ +#define INFO1M_RESP_END (1 << 0) +#define INFO1M_ACCESS_END (1 << 2) +#define INFO1M_CARD_RE (1 << 3) +#define INFO1M_CARD_IN (1 << 4) +#define INFO1M_DATA3_CARD_RE (1 << 8) +#define INFO1M_DATA3_CARD_IN (1 << 9) +#define INFO1M_ALL (0xffff) +#define INFO1M_SET (INFO1M_RESP_END | \ + INFO1M_ACCESS_END | \ + INFO1M_DATA3_CARD_RE | \ + INFO1M_DATA3_CARD_IN) + +/* SDHI_INFO2_MASK */ +#define INFO2M_CMD_ERROR (1 << 0) +#define INFO2M_CRC_ERROR (1 << 1) +#define INFO2M_END_ERROR (1 << 2) +#define INFO2M_TIMEOUT (1 << 3) +#define INFO2M_BUF_ILL_WRITE (1 << 4) +#define INFO2M_BUF_ILL_READ (1 << 5) +#define INFO2M_RESP_TIMEOUT (1 << 6) +#define INFO2M_BRE_ENABLE (1 << 8) +#define INFO2M_BWE_ENABLE (1 << 9) +#define INFO2M_ILA (1 << 15) +#define INFO2M_ALL (0xffff) +#define INFO2M_ALL_ERR (0x807f) + +/* SDHI_CLK_CTRL */ +#define CLK_ENABLE (1 << 8) + +/* SDHI_OPTION */ +#define OPT_BUS_WIDTH_1 (1 << 15) /* bus width = 1 bit */ + +/* SDHI_ERR_STS1 */ +#define ERR_STS1_CRC_ERROR ((1 << 11) | (1 << 10) | (1 << 9) | \ + (1 << 8) | (1 << 5)) +#define ERR_STS1_CMD_ERROR ((1 << 4) | (1 << 3) | (1 << 2) | \ + (1 << 1) | (1 << 0)) + +/* SDHI_ERR_STS2 */ +#define ERR_STS2_RES_TIMEOUT (1 << 0) +#define ERR_STS2_RES_STOP_TIMEOUT ((1 << 0) | (1 << 1)) +#define ERR_STS2_SYS_ERROR ((1 << 6) | (1 << 5) | (1 << 4) | \ + (1 << 3) | (1 << 2) | (1 << 1) | \ + (1 << 0)) + +/* SDHI_SDIO_MODE */ +#define SDIO_MODE_ON (1 << 0) +#define SDIO_MODE_OFF (0 << 0) + +/* SDHI_SDIO_INFO1 */ +#define SDIO_INFO1_IOIRQ (1 << 0) +#define SDIO_INFO1_EXPUB52 (1 << 14) +#define SDIO_INFO1_EXWT (1 << 15) + +/* SDHI_SDIO_INFO1_MASK */ +#define SDIO_INFO1M_CLEAR ((1 << 1) | (1 << 2)) +#define SDIO_INFO1M_ON ((1 << 15) | (1 << 14) | (1 << 2) | \ + (1 << 1) | (1 << 0)) + +/* SDHI_EXT_SWAP */ +#define SET_SWAP ((1 << 6) | (1 << 7)) /* SWAP */ + +/* SDHI_SOFT_RST */ +#define SOFT_RST_ON (0 << 0) +#define SOFT_RST_OFF (1 << 0) + +#define CLKDEV_SD_DATA 25000000 /* 25 MHz */ +#define CLKDEV_HS_DATA 50000000 /* 50 MHz */ +#define CLKDEV_MMC_DATA 20000000 /* 20MHz */ +#define CLKDEV_INIT 400000 /* 100 - 400 KHz */ + +/* For quirk */ +#define SH_SDHI_QUIRK_16BIT_BUF (1) +int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks); + +#endif /* _SH_SDHI_H */ diff --git a/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h index 484559c..6b7d600 100644 --- a/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h +++ b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h @@ -72,7 +72,7 @@ struct ddrphy { u32 gtr; /* General Timing Register */ u32 rsv[3]; /* Reserved */ } dx[9]; -} __packed; +}; #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/include/asm/arch-uniphier/sg-regs.h b/arch/arm/include/asm/arch-uniphier/sg-regs.h index fa5e6ae..4ae67c8 100644 --- a/arch/arm/include/asm/arch-uniphier/sg-regs.h +++ b/arch/arm/include/asm/arch-uniphier/sg-regs.h @@ -25,22 +25,29 @@ /* Memory Configuration */ #define SG_MEMCONF (SG_CTRL_BASE | 0x0400) -#define SG_MEMCONF_CH0_SIZE_64MB ((0x0 << 10) | (0x01 << 0)) -#define SG_MEMCONF_CH0_SIZE_128MB ((0x0 << 10) | (0x02 << 0)) -#define SG_MEMCONF_CH0_SIZE_256MB ((0x0 << 10) | (0x03 << 0)) -#define SG_MEMCONF_CH0_SIZE_512MB ((0x1 << 10) | (0x00 << 0)) -#define SG_MEMCONF_CH0_SIZE_1024MB ((0x1 << 10) | (0x01 << 0)) +#define SG_MEMCONF_CH0_SZ_64M ((0x0 << 10) | (0x01 << 0)) +#define SG_MEMCONF_CH0_SZ_128M ((0x0 << 10) | (0x02 << 0)) +#define SG_MEMCONF_CH0_SZ_256M ((0x0 << 10) | (0x03 << 0)) +#define SG_MEMCONF_CH0_SZ_512M ((0x1 << 10) | (0x00 << 0)) +#define SG_MEMCONF_CH0_SZ_1G ((0x1 << 10) | (0x01 << 0)) #define SG_MEMCONF_CH0_NUM_1 (0x1 << 8) #define SG_MEMCONF_CH0_NUM_2 (0x0 << 8) -#define SG_MEMCONF_CH1_SIZE_64MB ((0x0 << 11) | (0x01 << 2)) -#define SG_MEMCONF_CH1_SIZE_128MB ((0x0 << 11) | (0x02 << 2)) -#define SG_MEMCONF_CH1_SIZE_256MB ((0x0 << 11) | (0x03 << 2)) -#define SG_MEMCONF_CH1_SIZE_512MB ((0x1 << 11) | (0x00 << 2)) -#define SG_MEMCONF_CH1_SIZE_1024MB ((0x1 << 11) | (0x01 << 2)) +#define SG_MEMCONF_CH1_SZ_64M ((0x0 << 11) | (0x01 << 2)) +#define SG_MEMCONF_CH1_SZ_128M ((0x0 << 11) | (0x02 << 2)) +#define SG_MEMCONF_CH1_SZ_256M ((0x0 << 11) | (0x03 << 2)) +#define SG_MEMCONF_CH1_SZ_512M ((0x1 << 11) | (0x00 << 2)) +#define SG_MEMCONF_CH1_SZ_1G ((0x1 << 11) | (0x01 << 2)) #define SG_MEMCONF_CH1_NUM_1 (0x1 << 9) #define SG_MEMCONF_CH1_NUM_2 (0x0 << 9) +#define SG_MEMCONF_CH2_SZ_64M ((0x0 << 26) | (0x01 << 16)) +#define SG_MEMCONF_CH2_SZ_128M ((0x0 << 26) | (0x02 << 16)) +#define SG_MEMCONF_CH2_SZ_256M ((0x0 << 26) | (0x03 << 16)) +#define SG_MEMCONF_CH2_SZ_512M ((0x1 << 26) | (0x00 << 16)) +#define SG_MEMCONF_CH2_NUM_1 (0x1 << 24) +#define SG_MEMCONF_CH2_NUM_2 (0x0 << 24) + #define SG_MEMCONF_SPARSEMEM (0x1 << 4) /* Pin Control */ @@ -101,6 +108,7 @@ #else #include <linux/types.h> +#include <linux/sizes.h> #include <asm/io.h> static inline void sg_set_pinsel(int n, int value) @@ -111,24 +119,24 @@ static inline void sg_set_pinsel(int n, int value) static inline u32 sg_memconf_val_ch0(unsigned long size, int num) { - int size_mb = (size >> 20) / num; + int size_mb = size / num; u32 ret; switch (size_mb) { - case 64: - ret = SG_MEMCONF_CH0_SIZE_64MB; + case SZ_64M: + ret = SG_MEMCONF_CH0_SZ_64M; break; - case 128: - ret = SG_MEMCONF_CH0_SIZE_128MB; + case SZ_128M: + ret = SG_MEMCONF_CH0_SZ_128M; break; - case 256: - ret = SG_MEMCONF_CH0_SIZE_256MB; + case SZ_256M: + ret = SG_MEMCONF_CH0_SZ_256M; break; - case 512: - ret = SG_MEMCONF_CH0_SIZE_512MB; + case SZ_512M: + ret = SG_MEMCONF_CH0_SZ_512M; break; - case 1024: - ret = SG_MEMCONF_CH0_SIZE_1024MB; + case SZ_1G: + ret = SG_MEMCONF_CH0_SZ_1G; break; default: BUG(); @@ -151,24 +159,24 @@ static inline u32 sg_memconf_val_ch0(unsigned long size, int num) static inline u32 sg_memconf_val_ch1(unsigned long size, int num) { - int size_mb = (size >> 20) / num; + int size_mb = size / num; u32 ret; switch (size_mb) { - case 64: - ret = SG_MEMCONF_CH1_SIZE_64MB; + case SZ_64M: + ret = SG_MEMCONF_CH1_SZ_64M; break; - case 128: - ret = SG_MEMCONF_CH1_SIZE_128MB; + case SZ_128M: + ret = SG_MEMCONF_CH1_SZ_128M; break; - case 256: - ret = SG_MEMCONF_CH1_SIZE_256MB; + case SZ_256M: + ret = SG_MEMCONF_CH1_SZ_256M; break; - case 512: - ret = SG_MEMCONF_CH1_SIZE_512MB; + case SZ_512M: + ret = SG_MEMCONF_CH1_SZ_512M; break; - case 1024: - ret = SG_MEMCONF_CH1_SIZE_1024MB; + case SZ_1G: + ret = SG_MEMCONF_CH1_SZ_1G; break; default: BUG(); @@ -188,6 +196,43 @@ static inline u32 sg_memconf_val_ch1(unsigned long size, int num) } return ret; } + +static inline u32 sg_memconf_val_ch2(unsigned long size, int num) +{ + int size_mb = size / num; + u32 ret; + + switch (size_mb) { + case SZ_64M: + ret = SG_MEMCONF_CH2_SZ_64M; + break; + case SZ_128M: + ret = SG_MEMCONF_CH2_SZ_128M; + break; + case SZ_256M: + ret = SG_MEMCONF_CH2_SZ_256M; + break; + case SZ_512M: + ret = SG_MEMCONF_CH2_SZ_512M; + break; + default: + BUG(); + break; + } + + switch (num) { + case 1: + ret |= SG_MEMCONF_CH2_NUM_1; + break; + case 2: + ret |= SG_MEMCONF_CH2_NUM_2; + break; + default: + BUG(); + break; + } + return ret; +} #endif /* __ASSEMBLY__ */ #endif /* ARCH_SG_REGS_H */ diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 89c47f3..9d50e24 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -20,7 +20,7 @@ extern void zynq_ddrc_init(void); extern unsigned int zynq_get_silicon_version(void); /* Driver extern functions */ -extern int zynq_sdhci_init(u32 regbase); +extern int zynq_sdhci_init(phys_addr_t regbase); extern int zynq_sdhci_of_init(const void *blob); extern void ps7_init(void); diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c index dfcc596..c41850a 100644 --- a/arch/arm/lib/spl.c +++ b/arch/arm/lib/spl.c @@ -15,6 +15,11 @@ /* Pointer to as well as the global data structure for SPL */ DECLARE_GLOBAL_DATA_PTR; + +/* + * WARNING: This is going away very soon. Don't use it and don't submit + * pafches that rely on it. The global_data area is set up in crt0.S. + */ gd_t gdata __attribute__ ((section(".data"))); /* @@ -28,7 +33,7 @@ void __weak board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* Set global data pointer. */ + /* TODO: Remove settings of the global data pointer here */ gd = &gdata; board_init_r(NULL, 0); diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 1757bbf..84c29e5 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -23,11 +23,15 @@ _start: mts rmsr, r0 /* disable cache */ + addi r8, r0, __end + mts rslr, r8 #if defined(CONFIG_SPL_BUILD) addi r1, r0, CONFIG_SPL_STACK_ADDR + mts rshr, r1 addi r1, r1, -4 /* Decrement SP to top of memory */ #else addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET + mts rshr, r1 addi r1, r1, -4 /* Decrement SP to top of memory */ /* Find-out if u-boot is running on BIG/LITTLE endian platform @@ -130,7 +134,7 @@ flush: bralid r15, flush_cache /* enable instruction and data cache */ mfs r12, rmsr - ori r12, r12, 0xa0 + ori r12, r12, 0x1a0 mts rmsr, r12 clear_bss: diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4991da2..ef78929 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -29,6 +29,7 @@ config TARGET_MALTA select SUPPORTS_LITTLE_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 + select SWAP_IO_SPACE config TARGET_VCT bool "Support vct" @@ -116,6 +117,39 @@ config CPU_MIPS64_R2 endchoice +menu "OS boot interface" + +config MIPS_BOOT_CMDLINE_LEGACY + bool "Hand over legacy command line to Linux kernel" + default y + help + Enable this option if you want U-Boot to hand over the Yamon-style + command line to the kernel. All bootargs will be prepared as argc/argv + compatible list. The argument count (argc) is stored in register $a0. + The address of the argument list (argv) is stored in register $a1. + +config MIPS_BOOT_ENV_LEGACY + bool "Hand over legacy environment to Linux kernel" + default y + help + Enable this option if you want U-Boot to hand over the Yamon-style + environment to the kernel. Information like memory size, initrd + address and size will be prepared as zero-terminated key/value list. + The address of the enviroment is stored in register $a2. + +config MIPS_BOOT_FDT + bool "Hand over a flattened device tree to Linux kernel (INCOMPLETE)" + default n + help + Enable this option if you want U-Boot to hand over a flattened + device tree to the kernel. + + Note: the final hand over to the kernel is not yet implemented. After + the community agreed on the MIPS boot interface for device trees, + the corresponding code will be added. + +endmenu + config SUPPORTS_BIG_ENDIAN bool @@ -134,12 +168,23 @@ config SUPPORTS_CPU_MIPS64_R1 config SUPPORTS_CPU_MIPS64_R2 bool +config CPU_MIPS32 + bool + default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 + +config CPU_MIPS64 + bool + default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 + config 32BIT bool config 64BIT bool +config SWAP_IO_SPACE + bool + endif endmenu diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 1907b57..0a9e7e6 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -2,7 +2,9 @@ # SPDX-License-Identifier: GPL-2.0+ # -head-y := arch/mips/cpu/$(CPU)/start.o +head-$(CONFIG_CPU_MIPS32) := arch/mips/cpu/mips32/start.o +head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o -libs-y += arch/mips/cpu/$(CPU)/ +libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/ +libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/ libs-y += arch/mips/lib/ diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 384ea26..36b92cc 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -15,6 +15,11 @@ #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #endif +#ifndef CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_INIT_SP_OFFSET) +#endif + /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using @@ -135,9 +140,31 @@ reset: #endif /* Set up temporary stack */ - li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET + li t0, -16 + li t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 # force 16 byte alignment + sub sp, sp, GD_SIZE # reserve space for gd + and sp, sp, t0 # force 16 byte alignment + move k0, sp # save gd pointer +#ifdef CONFIG_SYS_MALLOC_F_LEN + li t2, CONFIG_SYS_MALLOC_F_LEN + sub sp, sp, t2 # reserve space for early malloc + and sp, sp, t0 # force 16 byte alignment +#endif move fp, sp + /* Clear gd */ + move t0, k0 +1: + sw zero, 0(t0) + blt t0, t1, 1b + addi t0, 4 + +#ifdef CONFIG_SYS_MALLOC_F_LEN + addu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset + sw sp, 0(t0) +#endif + la t9, board_init_f jr t9 move ra, zero diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/mips32/time.c index 386f45a..553da5f 100644 --- a/arch/mips/cpu/mips32/time.c +++ b/arch/mips/cpu/mips32/time.c @@ -8,63 +8,12 @@ #include <common.h> #include <asm/mipsregs.h> -static unsigned long timestamp; - -/* how many counter cycles in a jiffy */ -#define CYCLES_PER_JIFFY \ - (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ - -/* - * timer without interrupts - */ - -int timer_init(void) -{ - /* Set up the timer for the first expiration. */ - write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY); - - return 0; -} - -ulong get_timer(ulong base) -{ - unsigned int count; - unsigned int expirelo = read_c0_compare(); - - /* Check to see if we have missed any timestamps. */ - count = read_c0_count(); - while ((count - expirelo) < 0x7fffffff) { - expirelo += CYCLES_PER_JIFFY; - timestamp++; - } - write_c0_compare(expirelo); - - return timestamp - base; -} - -void __udelay(unsigned long usec) +unsigned long notrace timer_read_counter(void) { - unsigned int tmo; - - tmo = read_c0_count() + (usec * (CONFIG_SYS_MIPS_TIMER_FREQ / 1000000)); - while ((tmo - read_c0_count()) < 0x7fffffff) - /*NOP*/; + return read_c0_count(); } -/* - * This function is derived from PowerPC code (read timebase as long long). - * On MIPS it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On MIPS it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) +ulong notrace get_tbclk(void) { - return CONFIG_SYS_HZ; + return CONFIG_SYS_MIPS_TIMER_FREQ; } diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 6ff714e..471bc1e 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -15,6 +15,11 @@ #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #endif +#ifndef CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_INIT_SP_OFFSET) +#endif + #ifdef CONFIG_SYS_LITTLE_ENDIAN #define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) @@ -129,9 +134,31 @@ reset: #endif /* Set up temporary stack */ - dli sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET + dli t0, -16 + dli t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 # force 16 byte alignment + dsub sp, sp, GD_SIZE # reserve space for gd + and sp, sp, t0 # force 16 byte alignment + move k0, sp # save gd pointer +#ifdef CONFIG_SYS_MALLOC_F_LEN + dli t2, CONFIG_SYS_MALLOC_F_LEN + dsub sp, sp, t2 # reserve space for early malloc + and sp, sp, t0 # force 16 byte alignment +#endif move fp, sp + /* Clear gd */ + move t0, k0 +1: + sw zero, 0(t0) + blt t0, t1, 1b + daddi t0, 4 + +#ifdef CONFIG_SYS_MALLOC_F_LEN + daddu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset + sw sp, 0(t0) +#endif + dla t9, board_init_f jr t9 move ra, zero diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c index 0497acf..553da5f 100644 --- a/arch/mips/cpu/mips64/time.c +++ b/arch/mips/cpu/mips64/time.c @@ -8,63 +8,12 @@ #include <common.h> #include <asm/mipsregs.h> -static unsigned long timestamp; - -/* how many counter cycles in a jiffy */ -#define CYCLES_PER_JIFFY \ - (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ - -/* - * timer without interrupts - */ - -int timer_init(void) -{ - /* Set up the timer for the first expiration. */ - write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY); - - return 0; -} - -ulong get_timer(ulong base) -{ - unsigned int count; - unsigned int expirelo = read_c0_compare(); - - /* Check to see if we have missed any timestamps. */ - count = read_c0_count(); - while ((count - expirelo) < 0x7fffffff) { - expirelo += CYCLES_PER_JIFFY; - timestamp++; - } - write_c0_compare(expirelo); - - return timestamp - base; -} - -void __udelay(unsigned long usec) +unsigned long notrace timer_read_counter(void) { - unsigned int tmo; - - tmo = read_c0_count() + (usec * (CONFIG_SYS_MIPS_TIMER_FREQ / 1000000)); - while ((tmo - read_c0_count()) < 0x7fffffff) - /*NOP*/; + return read_c0_count(); } -/* - * This function is derived from PowerPC code (read timebase as long long). - * On MIPS it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On MIPS it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) +ulong notrace get_tbclk(void) { - return CONFIG_SYS_HZ; + return CONFIG_SYS_MIPS_TIMER_FREQ; } diff --git a/arch/mips/include/asm/config.h b/arch/mips/include/asm/config.h index 1c8a42b..3a891ba 100644 --- a/arch/mips/include/asm/config.h +++ b/arch/mips/include/asm/config.h @@ -7,8 +7,6 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA - #define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index e0722d2..d9d8396 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -7,6 +7,7 @@ #include <common.h> #include <image.h> +#include <fdt_support.h> #include <asm/addrspace.h> DECLARE_GLOBAL_DATA_PTR; @@ -20,6 +21,18 @@ DECLARE_GLOBAL_DATA_PTR; #define mips_boot_malta 0 #endif +#if defined(CONFIG_MIPS_BOOT_CMDLINE_LEGACY) +#define mips_boot_cmdline_legacy 1 +#else +#define mips_boot_cmdline_legacy 0 +#endif + +#if defined(CONFIG_MIPS_BOOT_ENV_LEGACY) +#define mips_boot_env_legacy 1 +#else +#define mips_boot_env_legacy 0 +#endif + static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -60,9 +73,39 @@ static int boot_setup_linux(bootm_headers_t *images) if (ret) return ret; +#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + if (images->ft_len) { + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); + + ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, + &images->ft_len); + if (ret) + return ret; + } +#endif + return 0; } +static void boot_setup_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + u64 mem_start = 0; + u64 mem_size = gd->ram_size; + + debug("## setup FDT\n"); + + fdt_chosen(images->ft_addr, 1); + fdt_fixup_memory_banks(images->ft_addr, &mem_start, &mem_size, 1); + fdt_fixup_ethernet(images->ft_addr); + fdt_initrd(images->ft_addr, images->initrd_start, images->initrd_end, 1); + +#if defined(CONFIG_OF_BOARD_SETUP) + ft_board_setup(images->ft_addr, gd->bd); +#endif +#endif +} + static void linux_cmdline_init(void) { linux_argc = 1; @@ -92,7 +135,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); } -static void boot_cmdline_linux(bootm_headers_t *images) +static void linux_cmdline_legacy(bootm_headers_t *images) { const char *bootargs, *next, *quote; @@ -130,8 +173,40 @@ static void boot_cmdline_linux(bootm_headers_t *images) bootargs = next; } +} - linux_cmdline_dump(); +static void linux_cmdline_append(bootm_headers_t *images) +{ + char buf[24]; + ulong mem, rd_start, rd_size; + + /* append mem */ + mem = gd->ram_size >> 20; + sprintf(buf, "mem=%luM", mem); + linux_cmdline_set(buf, strlen(buf)); + + /* append rd_start and rd_size */ + rd_start = images->initrd_start; + rd_size = images->initrd_end - images->initrd_start; + + if (rd_size) { + sprintf(buf, "rd_start=0x%08lX", rd_start); + linux_cmdline_set(buf, strlen(buf)); + sprintf(buf, "rd_size=0x%lX", rd_size); + linux_cmdline_set(buf, strlen(buf)); + } +} + +static void boot_cmdline_linux(bootm_headers_t *images) +{ + if (mips_boot_cmdline_legacy && !images->ft_len) { + linux_cmdline_legacy(images); + + if (!mips_boot_env_legacy) + linux_cmdline_append(images); + + linux_cmdline_dump(); + } } static void linux_env_init(void) @@ -165,7 +240,7 @@ static void linux_env_set(const char *env_name, const char *env_val) } } -static void boot_prep_linux(bootm_headers_t *images) +static void linux_env_legacy(bootm_headers_t *images) { char env_buf[12]; const char *cp; @@ -213,6 +288,15 @@ static void boot_prep_linux(bootm_headers_t *images) } } +static void boot_prep_linux(bootm_headers_t *images) +{ + if (mips_boot_env_legacy && !images->ft_len) + linux_env_legacy(images); + + if (images->ft_len) + boot_setup_fdt(images); +} + static void boot_jump_linux(bootm_headers_t *images) { typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong); @@ -226,8 +310,12 @@ static void boot_jump_linux(bootm_headers_t *images) if (mips_boot_malta) linux_extra = gd->ram_size; - /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); +#ifdef CONFIG_BOOTSTAGE_FDT + bootstage_fdt_add_report(); +#endif +#ifdef CONFIG_BOOTSTAGE_REPORT + bootstage_report(); +#endif kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, linux_extra); } diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c index 6fe937b..5b4b76f 100644 --- a/board/compulab/cm_fx6/spl.c +++ b/board/compulab/cm_fx6/spl.c @@ -313,7 +313,6 @@ void board_init_f(ulong dummy) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - gd = &gdata; /* * We don't use DMA in SPL, but we do need it in U-Boot. U-Boot * initializes DMA very early (before all board code), so the only diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index f08e54f..152da2d 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -219,9 +219,6 @@ void board_init_f(ulong dummy) pinctl); #endif - /* Set global data pointer */ - gd = &gdata; - /* Clear the BSS */ memset(__bss_start, 0, __bss_end - __bss_start); diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index 8ab229d..027b67e 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -287,9 +287,6 @@ int board_early_init_f(void) #ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { - /* Set global data pointer */ - gd = &gdata; - /* Clear the BSS */ memset(__bss_start, 0, __bss_end - __bss_start); diff --git a/board/freescale/mpc837xerdb/MAINTAINERS b/board/freescale/mpc837xerdb/MAINTAINERS index 8592a2c..81b4eed 100644 --- a/board/freescale/mpc837xerdb/MAINTAINERS +++ b/board/freescale/mpc837xerdb/MAINTAINERS @@ -1,6 +1,6 @@ MPC837XERDB BOARD -#M: Joe D'Abbraccio <ljd015@freescale.com> -S: Orphan (since 2014-06) +M: Sinan Akman <sinan@writeme.com> +S: Maintained F: board/freescale/mpc837xerdb/ F: include/configs/MPC837XERDB.h F: configs/MPC837XERDB_defconfig diff --git a/board/synopsys/Kconfig b/board/synopsys/Kconfig index a54d3df..f614f88 100644 --- a/board/synopsys/Kconfig +++ b/board/synopsys/Kconfig @@ -1,8 +1,5 @@ if TARGET_ARCANGEL4 -config SYS_CPU - default "arc700" - config SYS_VENDOR default "synopsys" @@ -13,9 +10,6 @@ endif if TARGET_ARCANGEL4_BE -config SYS_CPU - default "arc700" - config SYS_VENDOR default "synopsys" diff --git a/board/synopsys/axs101/Kconfig b/board/synopsys/axs101/Kconfig index 8448265..79e5400 100644 --- a/board/synopsys/axs101/Kconfig +++ b/board/synopsys/axs101/Kconfig @@ -1,8 +1,5 @@ if TARGET_AXS101 -config SYS_CPU - default "arc700" - config SYS_BOARD default "axs101" diff --git a/board/woodburn/woodburn.c b/board/woodburn/woodburn.c index 2744514..3da61a4 100644 --- a/board/woodburn/woodburn.c +++ b/board/woodburn/woodburn.c @@ -137,9 +137,6 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* Set global data pointer. */ - gd = &gdata; - preloader_console_init(); timer_init(); diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 258632e..3a2198f 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -24,6 +24,7 @@ static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10); static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15); static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20); static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30); +static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35); static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45); static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100); #endif @@ -49,6 +50,9 @@ int board_init(void) case XILINX_ZYNQ_7030: fpga = fpga030; break; + case XILINX_ZYNQ_7035: + fpga = fpga035; + break; case XILINX_ZYNQ_7045: fpga = fpga045; break; diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 8c5bf44..484a6c6 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -211,6 +211,7 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) comp = image_get_comp(hdr); if (comp == IH_COMP_GZIP) { +#if defined(CONFIG_GZIP) ulong image_buf = image_get_data(hdr); data = image_get_load(hdr); ulong image_size = ~0UL; @@ -222,6 +223,10 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return 1; } data_size = image_size; +#else + puts("Gunzip image is not supported\n"); + return 1; +#endif } else { data = (ulong)image_get_data(hdr); data_size = image_get_data_size(hdr); diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 96478e4..4e28c9d 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -73,6 +73,8 @@ U_BOOT_CMD( static void print_mmcinfo(struct mmc *mmc) { + int i; + printf("Device: %s\n", mmc->cfg->name); printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24); printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff); @@ -92,6 +94,48 @@ static void print_mmcinfo(struct mmc *mmc) printf("Bus Width: %d-bit%s\n", mmc->bus_width, mmc->ddr_mode ? " DDR" : ""); + + puts("Erase Group Size: "); + print_size(((u64)mmc->erase_grp_size) << 9, "\n"); + + if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) { + bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0; + bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR); + + puts("HC WP Group Size: "); + print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n"); + + puts("User Capacity: "); + print_size(mmc->capacity_user, usr_enh ? " ENH" : ""); + if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR) + puts(" WRREL\n"); + else + putc('\n'); + if (usr_enh) { + puts("User Enhanced Start: "); + print_size(mmc->enh_user_start, "\n"); + puts("User Enhanced Size: "); + print_size(mmc->enh_user_size, "\n"); + } + puts("Boot Capacity: "); + print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n"); + puts("RPMB Capacity: "); + print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n"); + + for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) { + bool is_enh = has_enh && + (mmc->part_attr & EXT_CSD_ENH_GP(i)); + if (mmc->capacity_gp[i]) { + printf("GP%i Capacity: ", i+1); + print_size(mmc->capacity_gp[i], + is_enh ? " ENH" : ""); + if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i)) + puts(" WRREL\n"); + else + putc('\n'); + } + } + } } static struct mmc *init_mmc_device(int dev, bool force_init) { @@ -444,6 +488,157 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag, print_mmc_devices('\n'); return CMD_RET_SUCCESS; } + +static int parse_hwpart_user(struct mmc_hwpart_conf *pconf, + int argc, char * const argv[]) +{ + int i = 0; + + memset(&pconf->user, 0, sizeof(pconf->user)); + + while (i < argc) { + if (!strcmp(argv[i], "enh")) { + if (i + 2 >= argc) + return -1; + pconf->user.enh_start = + simple_strtoul(argv[i+1], NULL, 10); + pconf->user.enh_size = + simple_strtoul(argv[i+2], NULL, 10); + i += 3; + } else if (!strcmp(argv[i], "wrrel")) { + if (i + 1 >= argc) + return -1; + pconf->user.wr_rel_change = 1; + if (!strcmp(argv[i+1], "on")) + pconf->user.wr_rel_set = 1; + else if (!strcmp(argv[i+1], "off")) + pconf->user.wr_rel_set = 0; + else + return -1; + i += 2; + } else { + break; + } + } + return i; +} + +static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx, + int argc, char * const argv[]) +{ + int i; + + memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx])); + + if (1 >= argc) + return -1; + pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10); + + i = 1; + while (i < argc) { + if (!strcmp(argv[i], "enh")) { + pconf->gp_part[pidx].enhanced = 1; + i += 1; + } else if (!strcmp(argv[i], "wrrel")) { + if (i + 1 >= argc) + return -1; + pconf->gp_part[pidx].wr_rel_change = 1; + if (!strcmp(argv[i+1], "on")) + pconf->gp_part[pidx].wr_rel_set = 1; + else if (!strcmp(argv[i+1], "off")) + pconf->gp_part[pidx].wr_rel_set = 0; + else + return -1; + i += 2; + } else { + break; + } + } + return i; +} + +static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct mmc *mmc; + struct mmc_hwpart_conf pconf = { }; + enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK; + int i, r, pidx; + + mmc = init_mmc_device(curr_device, false); + if (!mmc) + return CMD_RET_FAILURE; + + if (argc < 1) + return CMD_RET_USAGE; + i = 1; + while (i < argc) { + if (!strcmp(argv[i], "user")) { + i++; + r = parse_hwpart_user(&pconf, argc-i, &argv[i]); + if (r < 0) + return CMD_RET_USAGE; + i += r; + } else if (!strncmp(argv[i], "gp", 2) && + strlen(argv[i]) == 3 && + argv[i][2] >= '1' && argv[i][2] <= '4') { + pidx = argv[i][2] - '1'; + i++; + r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]); + if (r < 0) + return CMD_RET_USAGE; + i += r; + } else if (!strcmp(argv[i], "check")) { + mode = MMC_HWPART_CONF_CHECK; + i++; + } else if (!strcmp(argv[i], "set")) { + mode = MMC_HWPART_CONF_SET; + i++; + } else if (!strcmp(argv[i], "complete")) { + mode = MMC_HWPART_CONF_COMPLETE; + i++; + } else { + return CMD_RET_USAGE; + } + } + + puts("Partition configuration:\n"); + if (pconf.user.enh_size) { + puts("\tUser Enhanced Start: "); + print_size(((u64)pconf.user.enh_start) << 9, "\n"); + puts("\tUser Enhanced Size: "); + print_size(((u64)pconf.user.enh_size) << 9, "\n"); + } else { + puts("\tNo enhanced user data area\n"); + } + if (pconf.user.wr_rel_change) + printf("\tUser partition write reliability: %s\n", + pconf.user.wr_rel_set ? "on" : "off"); + for (pidx = 0; pidx < 4; pidx++) { + if (pconf.gp_part[pidx].size) { + printf("\tGP%i Capacity: ", pidx+1); + print_size(((u64)pconf.gp_part[pidx].size) << 9, + pconf.gp_part[pidx].enhanced ? + " ENH\n" : "\n"); + } else { + printf("\tNo GP%i partition\n", pidx+1); + } + if (pconf.gp_part[pidx].wr_rel_change) + printf("\tGP%i write reliability: %s\n", pidx+1, + pconf.gp_part[pidx].wr_rel_set ? "on" : "off"); + } + + if (!mmc_hwpart_config(mmc, &pconf, mode)) { + if (mode == MMC_HWPART_CONF_COMPLETE) + puts("Partitioning successful, " + "power-cycle to make effective\n"); + return CMD_RET_SUCCESS; + } else { + puts("Failed!\n"); + return CMD_RET_FAILURE; + } +} + #ifdef CONFIG_SUPPORT_EMMC_BOOT static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -601,6 +796,7 @@ static cmd_tbl_t cmd_mmc[] = { U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""), U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""), U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""), + U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""), #ifdef CONFIG_SUPPORT_EMMC_BOOT U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""), U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""), @@ -640,7 +836,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - mmc, 7, 1, do_mmcops, + mmc, 29, 1, do_mmcops, "MMC sub system", "info - display info of the current MMC device\n" "mmc read addr blk# cnt\n" @@ -650,6 +846,13 @@ U_BOOT_CMD( "mmc part - lists available partition on current mmc device\n" "mmc dev [dev] [part] - show or set current mmc device [partition]\n" "mmc list - lists available devices\n" + "mmc hwpartition [args...] - does hardware partitioning\n" + " arguments (sizes in 512-byte blocks):\n" + " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n" + " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n" + " [check|set|complete] - mode, complete set partitioning completed\n" + " WARNING: Partitioning is a write-once setting once it is set to complete.\n" + " Power cycling is required to initialize partitions after set to complete.\n" #ifdef CONFIG_SUPPORT_EMMC_BOOT "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n" " - Set the BOOT_BUS_WIDTH field of the specified device\n" diff --git a/common/cmd_usb.c b/common/cmd_usb.c index c192498..27813f0 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -441,6 +441,26 @@ static int do_usb_stop_keyboard(int force) return 0; } +static void do_usb_start(void) +{ + bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); + + if (usb_init() < 0) + return; + +#ifdef CONFIG_USB_STORAGE + /* try to recognize storage devices immediately */ + usb_stor_curr_dev = usb_stor_scan(1); +#endif +#ifdef CONFIG_USB_HOST_ETHER + /* try to recognize ethernet devices immediately */ + usb_ether_curr_dev = usb_host_eth_scan(1); +#endif +#ifdef CONFIG_USB_KEYBOARD + drv_usb_kbd_init(); +#endif +} + /****************************************************************************** * usb command intepreter */ @@ -457,26 +477,20 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 2) return CMD_RET_USAGE; - if ((strncmp(argv[1], "reset", 5) == 0) || - (strncmp(argv[1], "start", 5) == 0)) { - bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); + if (strncmp(argv[1], "start", 5) == 0) { + if (usb_started) + return 0; /* Already started */ + printf("starting USB...\n"); + do_usb_start(); + return 0; + } + + if (strncmp(argv[1], "reset", 5) == 0) { + printf("resetting USB...\n"); if (do_usb_stop_keyboard(1) != 0) return 1; usb_stop(); - printf("(Re)start USB...\n"); - if (usb_init() >= 0) { -#ifdef CONFIG_USB_STORAGE - /* try to recognize storage devices immediately */ - usb_stor_curr_dev = usb_stor_scan(1); -#endif -#ifdef CONFIG_USB_HOST_ETHER - /* try to recognize ethernet devices immediately */ - usb_ether_curr_dev = usb_host_eth_scan(1); -#endif -#ifdef CONFIG_USB_KEYBOARD - drv_usb_kbd_init(); -#endif - } + do_usb_start(); return 0; } if (strncmp(argv[1], "stop", 4) == 0) { diff --git a/common/usb.c b/common/usb.c index 736cd9f..32e15cd 100644 --- a/common/usb.c +++ b/common/usb.c @@ -59,6 +59,7 @@ int usb_init(void) void *ctrl; struct usb_device *dev; int i, start_index = 0; + int controllers_initialized = 0; int ret; dev_index = 0; @@ -78,6 +79,7 @@ int usb_init(void) ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl); if (ret == -ENODEV) { /* No such device. */ puts("Port not available.\n"); + controllers_initialized++; continue; } @@ -89,6 +91,7 @@ int usb_init(void) * lowlevel init is OK, now scan the bus for devices * i.e. search HUBs and configure them */ + controllers_initialized++; start_index = dev_index; printf("scanning bus %d for devices... ", i); dev = usb_alloc_new_device(ctrl); @@ -110,12 +113,10 @@ int usb_init(void) debug("scan end\n"); /* if we were not able to find at least one working bus, bail out */ - if (!usb_started) { + if (controllers_initialized == 0) puts("USB error: all controllers failed lowlevel init\n"); - return -1; - } - return 0; + return usb_started ? 0 : -1; } /****************************************************************************** @@ -969,6 +970,8 @@ int usb_new_device(struct usb_device *dev) printf("\n Couldn't reset port %i\n", dev->portnr); return 1; } + } else { + usb_reset_root_port(); } #endif diff --git a/common/usb_kbd.c b/common/usb_kbd.c index bc7145e..ecc3085 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -332,7 +332,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) /* We've consumed all queued int packets, create new */ destroy_int_queue(dev, data->intq); data->intq = create_int_queue(dev, data->intpipe, 1, - USB_KBD_BOOT_REPORT_SIZE, data->new); + USB_KBD_BOOT_REPORT_SIZE, data->new, + data->intinterval); } #endif } @@ -453,7 +454,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) debug("USB KBD: enable interrupt pipe...\n"); #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE data->intq = create_int_queue(dev, data->intpipe, 1, - USB_KBD_BOOT_REPORT_SIZE, data->new); + USB_KBD_BOOT_REPORT_SIZE, data->new, + data->intinterval); if (!data->intq) { #else if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize, @@ -542,6 +544,10 @@ int usb_kbd_deregister(int force) data = usb_kbd_dev->privptr; if (stdio_deregister_dev(dev, force) != 0) return 1; +#ifdef CONFIG_CONSOLE_MUX + if (iomux_doenv(stdin, getenv("stdin")) != 0) + return 1; +#endif #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE destroy_int_queue(usb_kbd_dev, data->intq); #endif diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 37946d5..d94eb5c 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -38,7 +38,7 @@ static void fpga_no_sup(char *fn, char *msg) /* fpga_get_desc * map a device number to a descriptor */ -static const fpga_desc *const fpga_get_desc(int devnum) +const fpga_desc *const fpga_get_desc(int devnum) { fpga_desc *desc = (fpga_desc *)NULL; diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index adb4b8c..c765a74 100644 --- a/drivers/fpga/xilinx.c +++ b/drivers/fpga/xilinx.c @@ -139,6 +139,11 @@ int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize, return FPGA_FAIL; } + if (!desc->operations || !desc->operations->load) { + printf("%s: Missing load operation\n", __func__); + return FPGA_FAIL; + } + return desc->operations->load(desc, buf, bsize, bstype); } @@ -151,8 +156,10 @@ int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, return FPGA_FAIL; } - if (!desc->operations->loadfs) + if (!desc->operations || !desc->operations->loadfs) { + printf("%s: Missing loadfs operation\n", __func__); return FPGA_FAIL; + } return desc->operations->loadfs(desc, buf, bsize, fpga_fsinfo); } @@ -165,6 +172,11 @@ int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize) return FPGA_FAIL; } + if (!desc->operations || !desc->operations->dump) { + printf("%s: Missing dump operation\n", __func__); + return FPGA_FAIL; + } + return desc->operations->dump(desc, buf, bsize); } @@ -226,12 +238,14 @@ int xilinx_info(xilinx_desc *desc) if (desc->name) printf("Device name: \t%s\n", desc->name); - if (desc->iface_fns) { + if (desc->iface_fns) printf ("Device Function Table @ 0x%p\n", desc->iface_fns); - desc->operations->info(desc); - } else + else printf ("No Device Function Table.\n"); + if (desc->operations && desc->operations->info) + desc->operations->info(desc); + ret_val = FPGA_SUCCESS; } else { printf ("%s: Invalid device descriptor\n", __FUNCTION__); diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index e69de29..7ba85a2 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -0,0 +1,9 @@ +menu "MMC Host controller Support" + +config SH_SDHI + bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support" + depends on RMOBILE + help + Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform + +endmenu diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 461d7d8..4ba5878 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_S3C_SDI) += s3c_sdi.o obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o obj-$(CONFIG_SDHCI) += sdhci.o obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o +obj-$(CONFIG_SH_SDHI) += sh_sdhi.o obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 1eb9c27..b8039cd 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc) char cardtype; int err; - mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + mmc->card_caps = 0; if (mmc_host_is_spi(mmc)) return 0; @@ -495,6 +495,8 @@ static int mmc_change_freq(struct mmc *mmc) if (mmc->version < MMC_VERSION_4) return 0; + mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; + err = mmc_send_ext_csd(mmc, ext_csd); if (err) @@ -605,6 +607,200 @@ int mmc_switch_part(int dev_num, unsigned int part_num) return ret; } +int mmc_hwpart_config(struct mmc *mmc, + const struct mmc_hwpart_conf *conf, + enum mmc_hwpart_conf_mode mode) +{ + u8 part_attrs = 0; + u32 enh_size_mult; + u32 enh_start_addr; + u32 gp_size_mult[4]; + u32 max_enh_size_mult; + u32 tot_enh_size_mult = 0; + u8 wr_rel_set; + int i, pidx, err; + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); + + if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE) + return -EINVAL; + + if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) { + printf("eMMC >= 4.4 required for enhanced user data area\n"); + return -EMEDIUMTYPE; + } + + if (!(mmc->part_support & PART_SUPPORT)) { + printf("Card does not support partitioning\n"); + return -EMEDIUMTYPE; + } + + if (!mmc->hc_wp_grp_size) { + printf("Card does not define HC WP group size\n"); + return -EMEDIUMTYPE; + } + + /* check partition alignment and total enhanced size */ + if (conf->user.enh_size) { + if (conf->user.enh_size % mmc->hc_wp_grp_size || + conf->user.enh_start % mmc->hc_wp_grp_size) { + printf("User data enhanced area not HC WP group " + "size aligned\n"); + return -EINVAL; + } + part_attrs |= EXT_CSD_ENH_USR; + enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size; + if (mmc->high_capacity) { + enh_start_addr = conf->user.enh_start; + } else { + enh_start_addr = (conf->user.enh_start << 9); + } + } else { + enh_size_mult = 0; + enh_start_addr = 0; + } + tot_enh_size_mult += enh_size_mult; + + for (pidx = 0; pidx < 4; pidx++) { + if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) { + printf("GP%i partition not HC WP group size " + "aligned\n", pidx+1); + return -EINVAL; + } + gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size; + if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) { + part_attrs |= EXT_CSD_ENH_GP(pidx); + tot_enh_size_mult += gp_size_mult[pidx]; + } + } + + if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) { + printf("Card does not support enhanced attribute\n"); + return -EMEDIUMTYPE; + } + + err = mmc_send_ext_csd(mmc, ext_csd); + if (err) + return err; + + max_enh_size_mult = + (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) + + (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) + + ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT]; + if (tot_enh_size_mult > max_enh_size_mult) { + printf("Total enhanced size exceeds maximum (%u > %u)\n", + tot_enh_size_mult, max_enh_size_mult); + return -EMEDIUMTYPE; + } + + /* The default value of EXT_CSD_WR_REL_SET is device + * dependent, the values can only be changed if the + * EXT_CSD_HS_CTRL_REL bit is set. The values can be + * changed only once and before partitioning is completed. */ + wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; + if (conf->user.wr_rel_change) { + if (conf->user.wr_rel_set) + wr_rel_set |= EXT_CSD_WR_DATA_REL_USR; + else + wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR; + } + for (pidx = 0; pidx < 4; pidx++) { + if (conf->gp_part[pidx].wr_rel_change) { + if (conf->gp_part[pidx].wr_rel_set) + wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx); + else + wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx); + } + } + + if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] && + !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) { + puts("Card does not support host controlled partition write " + "reliability settings\n"); + return -EMEDIUMTYPE; + } + + if (ext_csd[EXT_CSD_PARTITION_SETTING] & + EXT_CSD_PARTITION_SETTING_COMPLETED) { + printf("Card already partitioned\n"); + return -EPERM; + } + + if (mode == MMC_HWPART_CONF_CHECK) + return 0; + + /* Partitioning requires high-capacity size definitions */ + if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ERASE_GROUP_DEF, 1); + + if (err) + return err; + + ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; + + /* update erase group size to be high-capacity */ + mmc->erase_grp_size = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; + + } + + /* all OK, write the configuration */ + for (i = 0; i < 4; i++) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ENH_START_ADDR+i, + (enh_start_addr >> (i*8)) & 0xFF); + if (err) + return err; + } + for (i = 0; i < 3; i++) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ENH_SIZE_MULT+i, + (enh_size_mult >> (i*8)) & 0xFF); + if (err) + return err; + } + for (pidx = 0; pidx < 4; pidx++) { + for (i = 0; i < 3; i++) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_GP_SIZE_MULT+pidx*3+i, + (gp_size_mult[pidx] >> (i*8)) & 0xFF); + if (err) + return err; + } + } + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs); + if (err) + return err; + + if (mode == MMC_HWPART_CONF_SET) + return 0; + + /* The WR_REL_SET is a write-once register but shall be + * written before setting PART_SETTING_COMPLETED. As it is + * write-once we can only write it when completing the + * partitioning. */ + if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_WR_REL_SET, wr_rel_set); + if (err) + return err; + } + + /* Setting PART_SETTING_COMPLETED confirms the partition + * configuration but it only becomes effective after power + * cycle, so we do not adjust the partition related settings + * in the mmc struct. */ + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PARTITION_SETTING, + EXT_CSD_PARTITION_SETTING_COMPLETED); + if (err) + return err; + + return 0; +} + int mmc_getcd(struct mmc *mmc) { int cd; @@ -818,6 +1014,8 @@ static int mmc_startup(struct mmc *mmc) ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); int timeout = 1000; + bool has_parts = false; + bool part_completed; #ifdef CONFIG_MMC_SPI_CRC_ON if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */ @@ -970,7 +1168,9 @@ static int mmc_startup(struct mmc *mmc) if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { /* check ext_csd version and capacity */ err = mmc_send_ext_csd(mmc, ext_csd); - if (!err && (ext_csd[EXT_CSD_REV] >= 2)) { + if (err) + return err; + if (ext_csd[EXT_CSD_REV] >= 2) { /* * According to the JEDEC Standard, the value of * ext_csd's capacity is valid if the value is more @@ -1006,13 +1206,70 @@ static int mmc_startup(struct mmc *mmc) break; } + /* The partition data may be non-zero but it is only + * effective if PARTITION_SETTING_COMPLETED is set in + * EXT_CSD, so ignore any data if this bit is not set, + * except for enabling the high-capacity group size + * definition (see below). */ + part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] & + EXT_CSD_PARTITION_SETTING_COMPLETED); + + /* store the partition info of emmc */ + mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT]; + if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || + ext_csd[EXT_CSD_BOOT_MULT]) + mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; + if (part_completed && + (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT)) + mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]; + + mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; + + mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; + + for (i = 0; i < 4; i++) { + int idx = EXT_CSD_GP_SIZE_MULT + i * 3; + uint mult = (ext_csd[idx + 2] << 16) + + (ext_csd[idx + 1] << 8) + ext_csd[idx]; + if (mult) + has_parts = true; + if (!part_completed) + continue; + mmc->capacity_gp[i] = mult; + mmc->capacity_gp[i] *= + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + mmc->capacity_gp[i] <<= 19; + } + + if (part_completed) { + mmc->enh_user_size = + (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) + + (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) + + ext_csd[EXT_CSD_ENH_SIZE_MULT]; + mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + mmc->enh_user_size <<= 19; + mmc->enh_user_start = + (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) + + (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) + + (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) + + ext_csd[EXT_CSD_ENH_START_ADDR]; + if (mmc->high_capacity) + mmc->enh_user_start <<= 9; + } + /* * Host needs to enable ERASE_GRP_DEF bit if device is * partitioned. This bit will be lost every time after a reset * or power off. This will affect erase size. */ + if (part_completed) + has_parts = true; if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && - (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) { + (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) + has_parts = true; + if (has_parts) { err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1); @@ -1020,19 +1277,18 @@ static int mmc_startup(struct mmc *mmc) return err; else ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; + } + if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) { /* Read out group size from ext_csd */ mmc->erase_grp_size = - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * - MMC_MAX_BLOCK_LEN * 1024; + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; /* * if high capacity and partition setting completed * SEC_COUNT is valid even if it is smaller than 2 GiB * JEDEC Standard JESD84-B45, 6.2.4 */ - if (mmc->high_capacity && - (ext_csd[EXT_CSD_PARTITION_SETTING] & - EXT_CSD_PARTITION_SETTING_COMPLETED)) { + if (mmc->high_capacity && part_completed) { capacity = (ext_csd[EXT_CSD_SEC_CNT]) | (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) | (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) | @@ -1049,23 +1305,11 @@ static int mmc_startup(struct mmc *mmc) * (erase_gmul + 1); } - /* store the partition info of emmc */ - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || - ext_csd[EXT_CSD_BOOT_MULT]) - mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; - - mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; - - mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; + mmc->hc_wp_grp_size = 1024 + * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] + * ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - for (i = 0; i < 4; i++) { - int idx = EXT_CSD_GP_SIZE_MULT + i * 3; - mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) + - (ext_csd[idx + 1] << 8) + ext_csd[idx]; - mmc->capacity_gp[i] *= - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - } + mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; } err = mmc_set_capacity(mmc, mmc->part_num); @@ -1107,7 +1351,8 @@ static int mmc_startup(struct mmc *mmc) mmc->tran_speed = 50000000; else mmc->tran_speed = 25000000; - } else { + } else if (mmc->version >= MMC_VERSION_4) { + /* Only version 4 of MMC supports wider bus widths */ int idx; /* An array of possible bus widths in order of preference */ @@ -1139,6 +1384,18 @@ static int mmc_startup(struct mmc *mmc) unsigned int caps = ext_to_hostcaps[extw]; /* + * If the bus width is still not changed, + * don't try to set the default again. + * Otherwise, recover from switch attempts + * by switching to 1-bit bus width. + */ + if (extw == EXT_CSD_BUS_WIDTH_1 && + mmc->bus_width == 1) { + err = 0; + break; + } + + /* * Check to make sure the card and controller support * these capabilities */ diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c new file mode 100644 index 0000000..cc62c89 --- /dev/null +++ b/drivers/mmc/sh_sdhi.c @@ -0,0 +1,695 @@ +/* + * drivers/mmc/sh_sdhi.c + * + * SD/MMC driver for Renesas rmobile ARM SoCs. + * + * Copyright (C) 2011,2013-2014 Renesas Electronics Corporation + * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * Copyright (C) 2008-2009 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <malloc.h> +#include <mmc.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/rmobile.h> +#include <asm/arch/sh_sdhi.h> + +#define DRIVER_NAME "sh-sdhi" + +struct sh_sdhi_host { + unsigned long addr; + int ch; + int bus_shift; + unsigned long quirks; + unsigned char wait_int; + unsigned char sd_error; + unsigned char detect_waiting; +}; +static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val) +{ + writew(val, host->addr + (reg << host->bus_shift)); +} + +static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg) +{ + return readw(host->addr + (reg << host->bus_shift)); +} + +static void *mmc_priv(struct mmc *mmc) +{ + return (void *)mmc->priv; +} + +static void sh_sdhi_detect(struct sh_sdhi_host *host) +{ + sh_sdhi_writew(host, SDHI_OPTION, + OPT_BUS_WIDTH_1 | sh_sdhi_readw(host, SDHI_OPTION)); + + host->detect_waiting = 0; +} + +static int sh_sdhi_intr(void *dev_id) +{ + struct sh_sdhi_host *host = dev_id; + int state1 = 0, state2 = 0; + + state1 = sh_sdhi_readw(host, SDHI_INFO1); + state2 = sh_sdhi_readw(host, SDHI_INFO2); + + debug("%s: state1 = %x, state2 = %x\n", __func__, state1, state2); + + /* CARD Insert */ + if (state1 & INFO1_CARD_IN) { + sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_IN); + if (!host->detect_waiting) { + host->detect_waiting = 1; + sh_sdhi_detect(host); + } + sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | + INFO1M_ACCESS_END | INFO1M_CARD_IN | + INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); + return -EAGAIN; + } + /* CARD Removal */ + if (state1 & INFO1_CARD_RE) { + sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_CARD_RE); + if (!host->detect_waiting) { + host->detect_waiting = 1; + sh_sdhi_detect(host); + } + sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | + INFO1M_ACCESS_END | INFO1M_CARD_RE | + INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); + sh_sdhi_writew(host, SDHI_SDIO_INFO1_MASK, SDIO_INFO1M_ON); + sh_sdhi_writew(host, SDHI_SDIO_MODE, SDIO_MODE_OFF); + return -EAGAIN; + } + + if (state2 & INFO2_ALL_ERR) { + sh_sdhi_writew(host, SDHI_INFO2, + (unsigned short)~(INFO2_ALL_ERR)); + sh_sdhi_writew(host, SDHI_INFO2_MASK, + INFO2M_ALL_ERR | + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + host->sd_error = 1; + host->wait_int = 1; + return 0; + } + /* Respons End */ + if (state1 & INFO1_RESP_END) { + sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END); + sh_sdhi_writew(host, SDHI_INFO1_MASK, + INFO1M_RESP_END | + sh_sdhi_readw(host, SDHI_INFO1_MASK)); + host->wait_int = 1; + return 0; + } + /* SD_BUF Read Enable */ + if (state2 & INFO2_BRE_ENABLE) { + sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BRE_ENABLE); + sh_sdhi_writew(host, SDHI_INFO2_MASK, + INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ | + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + host->wait_int = 1; + return 0; + } + /* SD_BUF Write Enable */ + if (state2 & INFO2_BWE_ENABLE) { + sh_sdhi_writew(host, SDHI_INFO2, ~INFO2_BWE_ENABLE); + sh_sdhi_writew(host, SDHI_INFO2_MASK, + INFO2_BWE_ENABLE | INFO2M_BUF_ILL_WRITE | + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + host->wait_int = 1; + return 0; + } + /* Access End */ + if (state1 & INFO1_ACCESS_END) { + sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_ACCESS_END); + sh_sdhi_writew(host, SDHI_INFO1_MASK, + INFO1_ACCESS_END | + sh_sdhi_readw(host, SDHI_INFO1_MASK)); + host->wait_int = 1; + return 0; + } + return -EAGAIN; +} + +static int sh_sdhi_wait_interrupt_flag(struct sh_sdhi_host *host) +{ + int timeout = 10000000; + + while (1) { + timeout--; + if (timeout < 0) { + debug(DRIVER_NAME": %s timeout\n", __func__); + return 0; + } + + if (!sh_sdhi_intr(host)) + break; + + udelay(1); /* 1 usec */ + } + + return 1; /* Return value: NOT 0 = complete waiting */ +} + +static int sh_sdhi_clock_control(struct sh_sdhi_host *host, unsigned long clk) +{ + u32 clkdiv, i, timeout; + + if (sh_sdhi_readw(host, SDHI_INFO2) & (1 << 14)) { + printf(DRIVER_NAME": Busy state ! Cannot change the clock\n"); + return -EBUSY; + } + + sh_sdhi_writew(host, SDHI_CLK_CTRL, + ~CLK_ENABLE & sh_sdhi_readw(host, SDHI_CLK_CTRL)); + + if (clk == 0) + return -EIO; + + clkdiv = 0x80; + i = CONFIG_SH_SDHI_FREQ >> (0x8 + 1); + for (; clkdiv && clk >= (i << 1); (clkdiv >>= 1)) + i <<= 1; + + sh_sdhi_writew(host, SDHI_CLK_CTRL, clkdiv); + + timeout = 100000; + /* Waiting for SD Bus busy to be cleared */ + while (timeout--) { + if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000)) + break; + } + + if (timeout) + sh_sdhi_writew(host, SDHI_CLK_CTRL, + CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL)); + else + return -EBUSY; + + return 0; +} + +static int sh_sdhi_sync_reset(struct sh_sdhi_host *host) +{ + u32 timeout; + sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_ON); + sh_sdhi_writew(host, SDHI_SOFT_RST, SOFT_RST_OFF); + sh_sdhi_writew(host, SDHI_CLK_CTRL, + CLK_ENABLE | sh_sdhi_readw(host, SDHI_CLK_CTRL)); + + timeout = 100000; + while (timeout--) { + if (!(sh_sdhi_readw(host, SDHI_INFO2) & INFO2_CBUSY)) + break; + udelay(100); + } + + if (!timeout) + return -EBUSY; + + if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) + sh_sdhi_writew(host, SDHI_HOST_MODE, 1); + + return 0; +} + +static int sh_sdhi_error_manage(struct sh_sdhi_host *host) +{ + unsigned short e_state1, e_state2; + int ret; + + host->sd_error = 0; + host->wait_int = 0; + + e_state1 = sh_sdhi_readw(host, SDHI_ERR_STS1); + e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2); + if (e_state2 & ERR_STS2_SYS_ERROR) { + if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT) + ret = TIMEOUT; + else + ret = -EILSEQ; + debug("%s: ERR_STS2 = %04x\n", + DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS2)); + sh_sdhi_sync_reset(host); + + sh_sdhi_writew(host, SDHI_INFO1_MASK, + INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); + return ret; + } + if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR) + ret = -EILSEQ; + else + ret = TIMEOUT; + + debug("%s: ERR_STS1 = %04x\n", + DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1)); + sh_sdhi_sync_reset(host); + sh_sdhi_writew(host, SDHI_INFO1_MASK, + INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); + return ret; +} + +static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data) +{ + long time; + unsigned short blocksize, i; + unsigned short *p = (unsigned short *)data->dest; + + if ((unsigned long)p & 0x00000001) { + debug(DRIVER_NAME": %s: The data pointer is unaligned.", + __func__); + return -EIO; + } + + host->wait_int = 0; + sh_sdhi_writew(host, SDHI_INFO2_MASK, + ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) & + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + sh_sdhi_writew(host, SDHI_INFO1_MASK, + ~INFO1M_ACCESS_END & + sh_sdhi_readw(host, SDHI_INFO1_MASK)); + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + blocksize = sh_sdhi_readw(host, SDHI_SIZE); + for (i = 0; i < blocksize / 2; i++) + *p++ = sh_sdhi_readw(host, SDHI_BUF0); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + return 0; +} + +static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data) +{ + long time; + unsigned short blocksize, i, sec; + unsigned short *p = (unsigned short *)data->dest; + + if ((unsigned long)p & 0x00000001) { + debug(DRIVER_NAME": %s: The data pointer is unaligned.", + __func__); + return -EIO; + } + + debug("%s: blocks = %d, blocksize = %d\n", + __func__, data->blocks, data->blocksize); + + host->wait_int = 0; + for (sec = 0; sec < data->blocks; sec++) { + sh_sdhi_writew(host, SDHI_INFO2_MASK, + ~(INFO2M_BRE_ENABLE | INFO2M_BUF_ILL_READ) & + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + blocksize = sh_sdhi_readw(host, SDHI_SIZE); + for (i = 0; i < blocksize / 2; i++) + *p++ = sh_sdhi_readw(host, SDHI_BUF0); + } + + return 0; +} + +static int sh_sdhi_single_write(struct sh_sdhi_host *host, + struct mmc_data *data) +{ + long time; + unsigned short blocksize, i; + const unsigned short *p = (const unsigned short *)data->src; + + if ((unsigned long)p & 0x00000001) { + debug(DRIVER_NAME": %s: The data pointer is unaligned.", + __func__); + return -EIO; + } + + debug("%s: blocks = %d, blocksize = %d\n", + __func__, data->blocks, data->blocksize); + + host->wait_int = 0; + sh_sdhi_writew(host, SDHI_INFO2_MASK, + ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) & + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + sh_sdhi_writew(host, SDHI_INFO1_MASK, + ~INFO1M_ACCESS_END & + sh_sdhi_readw(host, SDHI_INFO1_MASK)); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + blocksize = sh_sdhi_readw(host, SDHI_SIZE); + for (i = 0; i < blocksize / 2; i++) + sh_sdhi_writew(host, SDHI_BUF0, *p++); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + return 0; +} + +static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data) +{ + long time; + unsigned short i, sec, blocksize; + const unsigned short *p = (const unsigned short *)data->src; + + debug("%s: blocks = %d, blocksize = %d\n", + __func__, data->blocks, data->blocksize); + + host->wait_int = 0; + for (sec = 0; sec < data->blocks; sec++) { + sh_sdhi_writew(host, SDHI_INFO2_MASK, + ~(INFO2M_BWE_ENABLE | INFO2M_BUF_ILL_WRITE) & + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + host->wait_int = 0; + blocksize = sh_sdhi_readw(host, SDHI_SIZE); + for (i = 0; i < blocksize / 2; i++) + sh_sdhi_writew(host, SDHI_BUF0, *p++); + } + + return 0; +} + +static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd) +{ + unsigned short i, j, cnt = 1; + unsigned short resp[8]; + unsigned long *p1, *p2; + + if (cmd->resp_type & MMC_RSP_136) { + cnt = 4; + resp[0] = sh_sdhi_readw(host, SDHI_RSP00); + resp[1] = sh_sdhi_readw(host, SDHI_RSP01); + resp[2] = sh_sdhi_readw(host, SDHI_RSP02); + resp[3] = sh_sdhi_readw(host, SDHI_RSP03); + resp[4] = sh_sdhi_readw(host, SDHI_RSP04); + resp[5] = sh_sdhi_readw(host, SDHI_RSP05); + resp[6] = sh_sdhi_readw(host, SDHI_RSP06); + resp[7] = sh_sdhi_readw(host, SDHI_RSP07); + + /* SDHI REGISTER SPECIFICATION */ + for (i = 7, j = 6; i > 0; i--) { + resp[i] = (resp[i] << 8) & 0xff00; + resp[i] |= (resp[j--] >> 8) & 0x00ff; + } + resp[0] = (resp[0] << 8) & 0xff00; + + /* SDHI REGISTER SPECIFICATION */ + p1 = ((unsigned long *)resp) + 3; + + } else { + resp[0] = sh_sdhi_readw(host, SDHI_RSP00); + resp[1] = sh_sdhi_readw(host, SDHI_RSP01); + + p1 = ((unsigned long *)resp); + } + + p2 = (unsigned long *)cmd->response; +#if defined(__BIG_ENDIAN_BITFIELD) + for (i = 0; i < cnt; i++) { + *p2++ = ((*p1 >> 16) & 0x0000ffff) | + ((*p1 << 16) & 0xffff0000); + p1--; + } +#else + for (i = 0; i < cnt; i++) + *p2++ = *p1--; +#endif /* __BIG_ENDIAN_BITFIELD */ +} + +static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host, + struct mmc_data *data, unsigned short opc) +{ + switch (opc) { + case SD_CMD_APP_SEND_OP_COND: + case SD_CMD_APP_SEND_SCR: + opc |= SDHI_APP; + break; + case SD_CMD_APP_SET_BUS_WIDTH: + /* SD_APP_SET_BUS_WIDTH*/ + if (!data) + opc |= SDHI_APP; + else /* SD_SWITCH */ + opc = SDHI_SD_SWITCH; + break; + default: + break; + } + return opc; +} + +static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host, + struct mmc_data *data, unsigned short opc) +{ + unsigned short ret; + + switch (opc) { + case MMC_CMD_READ_MULTIPLE_BLOCK: + ret = sh_sdhi_multi_read(host, data); + break; + case MMC_CMD_WRITE_MULTIPLE_BLOCK: + ret = sh_sdhi_multi_write(host, data); + break; + case MMC_CMD_WRITE_SINGLE_BLOCK: + ret = sh_sdhi_single_write(host, data); + break; + case MMC_CMD_READ_SINGLE_BLOCK: + case SDHI_SD_APP_SEND_SCR: + case SDHI_SD_SWITCH: /* SD_SWITCH */ + ret = sh_sdhi_single_read(host, data); + break; + default: + printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); + ret = -EINVAL; + break; + } + return ret; +} + +static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, + struct mmc_data *data, struct mmc_cmd *cmd) +{ + long time; + unsigned short opc = cmd->cmdidx; + int ret = 0; + unsigned long timeout; + + debug("opc = %d, arg = %x, resp_type = %x\n", + opc, cmd->cmdarg, cmd->resp_type); + + if (opc == MMC_CMD_STOP_TRANSMISSION) { + /* SDHI sends the STOP command automatically by STOP reg */ + sh_sdhi_writew(host, SDHI_INFO1_MASK, ~INFO1M_ACCESS_END & + sh_sdhi_readw(host, SDHI_INFO1_MASK)); + + time = sh_sdhi_wait_interrupt_flag(host); + if (time == 0 || host->sd_error != 0) + return sh_sdhi_error_manage(host); + + sh_sdhi_get_response(host, cmd); + return 0; + } + + if (data) { + if ((opc == MMC_CMD_READ_MULTIPLE_BLOCK) || + opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) { + sh_sdhi_writew(host, SDHI_STOP, STOP_SEC_ENABLE); + sh_sdhi_writew(host, SDHI_SECCNT, data->blocks); + } + sh_sdhi_writew(host, SDHI_SIZE, data->blocksize); + } + opc = sh_sdhi_set_cmd(host, data, opc); + + /* + * U-boot cannot use interrupt. + * So this flag may not be clear by timing + */ + sh_sdhi_writew(host, SDHI_INFO1, ~INFO1_RESP_END); + + sh_sdhi_writew(host, SDHI_INFO1_MASK, + INFO1M_RESP_END | sh_sdhi_readw(host, SDHI_INFO1_MASK)); + sh_sdhi_writew(host, SDHI_ARG0, + (unsigned short)(cmd->cmdarg & ARG0_MASK)); + sh_sdhi_writew(host, SDHI_ARG1, + (unsigned short)((cmd->cmdarg >> 16) & ARG1_MASK)); + + timeout = 100000; + /* Waiting for SD Bus busy to be cleared */ + while (timeout--) { + if ((sh_sdhi_readw(host, SDHI_INFO2) & 0x2000)) + break; + } + + sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK)); + + host->wait_int = 0; + sh_sdhi_writew(host, SDHI_INFO1_MASK, + ~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK)); + sh_sdhi_writew(host, SDHI_INFO2_MASK, + ~(INFO2M_CMD_ERROR | INFO2M_CRC_ERROR | + INFO2M_END_ERROR | INFO2M_TIMEOUT | + INFO2M_RESP_TIMEOUT | INFO2M_ILA) & + sh_sdhi_readw(host, SDHI_INFO2_MASK)); + + time = sh_sdhi_wait_interrupt_flag(host); + if (!time) + return sh_sdhi_error_manage(host); + + if (host->sd_error) { + switch (cmd->cmdidx) { + case MMC_CMD_ALL_SEND_CID: + case MMC_CMD_SELECT_CARD: + case SD_CMD_SEND_IF_COND: + case MMC_CMD_APP_CMD: + ret = TIMEOUT; + break; + default: + debug(DRIVER_NAME": Cmd(d'%d) err\n", opc); + debug(DRIVER_NAME": cmdidx = %d\n", cmd->cmdidx); + ret = sh_sdhi_error_manage(host); + break; + } + host->sd_error = 0; + host->wait_int = 0; + return ret; + } + if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) + return -EINVAL; + + if (host->wait_int) { + sh_sdhi_get_response(host, cmd); + host->wait_int = 0; + } + if (data) + ret = sh_sdhi_data_trans(host, data, opc); + + debug("ret = %d, resp = %08x, %08x, %08x, %08x\n", + ret, cmd->response[0], cmd->response[1], + cmd->response[2], cmd->response[3]); + return ret; +} + +static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + int ret; + + host->sd_error = 0; + + ret = sh_sdhi_start_cmd(host, data, cmd); + + return ret; +} + +static void sh_sdhi_set_ios(struct mmc *mmc) +{ + int ret; + struct sh_sdhi_host *host = mmc_priv(mmc); + + ret = sh_sdhi_clock_control(host, mmc->clock); + if (ret) + return; + + if (mmc->bus_width == 4) + sh_sdhi_writew(host, SDHI_OPTION, ~OPT_BUS_WIDTH_1 & + sh_sdhi_readw(host, SDHI_OPTION)); + else + sh_sdhi_writew(host, SDHI_OPTION, OPT_BUS_WIDTH_1 | + sh_sdhi_readw(host, SDHI_OPTION)); + + debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); +} + +static int sh_sdhi_initialize(struct mmc *mmc) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + int ret = sh_sdhi_sync_reset(host); + + sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); + +#if defined(__BIG_ENDIAN_BITFIELD) + sh_sdhi_writew(host, SDHI_EXT_SWAP, SET_SWAP); +#endif + + sh_sdhi_writew(host, SDHI_INFO1_MASK, INFO1M_RESP_END | + INFO1M_ACCESS_END | INFO1M_CARD_RE | + INFO1M_DATA3_CARD_RE | INFO1M_DATA3_CARD_IN); + + return ret; +} + +static const struct mmc_ops sh_sdhi_ops = { + .send_cmd = sh_sdhi_send_cmd, + .set_ios = sh_sdhi_set_ios, + .init = sh_sdhi_initialize, +}; + +static struct mmc_config sh_sdhi_cfg = { + .name = DRIVER_NAME, + .ops = &sh_sdhi_ops, + .f_min = CLKDEV_INIT, + .f_max = CLKDEV_HS_DATA, + .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + .host_caps = MMC_MODE_4BIT | MMC_MODE_HS, + .part_type = PART_TYPE_DOS, + .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, +}; + +int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks) +{ + int ret = 0; + struct mmc *mmc; + struct sh_sdhi_host *host = NULL; + + if (ch >= CONFIG_SYS_SH_SDHI_NR_CHANNEL) + return -ENODEV; + + host = malloc(sizeof(struct sh_sdhi_host)); + if (!host) + return -ENOMEM; + + mmc = mmc_create(&sh_sdhi_cfg, host); + if (!mmc) { + ret = -1; + goto error; + } + + host->ch = ch; + host->addr = addr; + host->quirks = quirks; + + if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) + host->bus_shift = 1; + + return ret; +error: + if (host) + free(host); + return ret; +} diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index fdce2c2..7887f11 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -13,7 +13,7 @@ #include <sdhci.h> #include <asm/arch/sys_proto.h> -int zynq_sdhci_init(u32 regbase) +int zynq_sdhci_init(phys_addr_t regbase) { struct sdhci_host *host = NULL; @@ -40,7 +40,7 @@ int zynq_sdhci_of_init(const void *blob) { int offset = 0; u32 ret = 0; - u32 reg; + phys_addr_t reg; debug("ZYNQ SDHCI: Initialization\n"); diff --git a/drivers/net/xilinx_ll_temac.c b/drivers/net/xilinx_ll_temac.c index dab78d0..7cc8657 100644 --- a/drivers/net/xilinx_ll_temac.c +++ b/drivers/net/xilinx_ll_temac.c @@ -231,7 +231,7 @@ static int ll_temac_init(struct eth_device *dev, bd_t *bis) struct ll_temac *ll_temac = dev->priv; int ret; - printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n", + printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08lx.\n", dev->name, dev->index, dev->iobase); if (!ll_temac_setup_ctrl(dev)) diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 3cadd23..430e228 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -489,7 +489,8 @@ static int zynq_gem_miiphy_write(const char *devname, uchar addr, return phywrite(dev, addr, reg, val); } -int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio) +int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr, + int phy_addr, u32 emio) { struct eth_device *dev; struct zynq_gem_priv *priv; @@ -521,7 +522,7 @@ int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio) priv->phyaddr = phy_addr; priv->emio = emio; - sprintf(dev->name, "Gem.%x", base_addr); + sprintf(dev->name, "Gem.%lx", base_addr); dev->iobase = base_addr; diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c index b8ca720..0ef85db 100644 --- a/drivers/usb/eth/asix88179.c +++ b/drivers/usb/eth/asix88179.c @@ -271,6 +271,19 @@ static int asix_read_mac(struct eth_device *eth) return 0; } +static int asix_write_mac(struct eth_device *eth) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + int ret; + + ret = asix_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, + ETH_ALEN, eth->enetaddr); + if (ret < 0) + debug("Failed to set MAC address: %02x\n", ret); + + return ret; +} + static int asix_basic_reset(struct ueth_data *dev) { struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv; @@ -686,6 +699,7 @@ int ax88179_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->send = asix_send; eth->recv = asix_recv; eth->halt = asix_halt; + eth->write_hwaddr = asix_write_mac; eth->priv = ss; if (asix_basic_reset(ss)) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a4c5606..98c2da6 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -761,6 +761,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value >= 0) value = min(w_length, (u16) value); break; + case USB_DT_BOS: + /* + * The USB compliance test (USB 2.0 Command Verifier) + * issues this request. We should not run into the + * default path here. But return for now until + * the superspeed support is added. + */ + break; default: goto unknown; } diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index ead71eb..77a1567 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -780,6 +780,13 @@ static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return 0; } +static int __dfu_get_alt(struct usb_function *f, unsigned intf) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + + return f_dfu->altsetting; +} + /* TODO: is this really what we need here? */ static void dfu_disable(struct usb_function *f) { @@ -806,6 +813,7 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.bind = dfu_bind; f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; + f_dfu->usb_function.get_alt = __dfu_get_alt; f_dfu->usb_function.disable = dfu_disable; f_dfu->usb_function.strings = dfu_generic_strings; f_dfu->usb_function.setup = dfu_handle; diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 8945c5b..d4460b2 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1950,11 +1950,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) dev->watchdog.period = 5000 * CONFIG_SYS_HZ / 1000000; /* 5 ms */ dev->watchdog.function = udc_watchdog; + dev->mach = &mach_info; + udc_disable(dev); udc_reinit(dev); - dev->mach = &mach_info; - dev->gadget.name = "pxa2xx_udc"; retval = driver->bind(&dev->gadget); if (retval) { diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index bc76066..f1fb190 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1148,7 +1148,7 @@ disable_periodic(struct ehci_ctrl *ctrl) struct int_queue * create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, - int elementsize, void *buffer) + int elementsize, void *buffer, int interval) { struct ehci_ctrl *ctrl = dev->controller; struct int_queue *result = NULL; @@ -1398,7 +1398,7 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); - queue = create_int_queue(dev, pipe, 1, length, buffer); + queue = create_int_queue(dev, pipe, 1, length, buffer, interval); if (!queue) return -1; diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile index 3facf0f..9edeece 100644 --- a/drivers/usb/musb-new/Makefile +++ b/drivers/usb/musb-new/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o +obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o ccflags-y := $(call cc-option,-Wno-unused-variable) \ $(call cc-option,-Wno-unused-but-set-variable) \ diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c index bbcee88..437309c 100644 --- a/drivers/usb/musb-new/musb_host.c +++ b/drivers/usb/musb-new/musb_host.c @@ -2130,8 +2130,6 @@ done: return ret; } - -#ifndef __UBOOT__ /* * abort a transfer that's at the head of a hardware queue. * called with controller locked, irqs blocked @@ -2195,7 +2193,14 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) return status; } -static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) +#ifndef __UBOOT__ +static int musb_urb_dequeue( +#else +int musb_urb_dequeue( +#endif + struct usb_hcd *hcd, + struct urb *urb, + int status) { struct musb *musb = hcd_to_musb(hcd); struct musb_qh *qh; @@ -2253,6 +2258,7 @@ done: return ret; } +#ifndef __UBOOT__ /* disable an endpoint */ static void musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) diff --git a/drivers/usb/musb-new/musb_host.h b/drivers/usb/musb-new/musb_host.h index ebebe0c..546b4a2 100644 --- a/drivers/usb/musb-new/musb_host.h +++ b/drivers/usb/musb-new/musb_host.h @@ -110,5 +110,6 @@ static inline struct urb *next_urb(struct musb_qh *qh) #ifdef __UBOOT__ int musb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); +int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); #endif #endif /* _MUSB_HOST_H */ diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h index 03f2655..27e4ed4 100644 --- a/drivers/usb/musb-new/musb_regs.h +++ b/drivers/usb/musb-new/musb_regs.h @@ -216,6 +216,9 @@ #ifndef CONFIG_BLACKFIN +/* SUNXI has different reg addresses, but identical r/w functions */ +#ifndef CONFIG_ARCH_SUNXI + /* * Common USB registers */ @@ -318,6 +321,85 @@ #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ (0x80 + (8*(_epnum)) + (_offset)) +#else /* CONFIG_ARCH_SUNXI */ + +/* + * Common USB registers + */ + +#define MUSB_FADDR 0x0098 +#define MUSB_POWER 0x0040 + +#define MUSB_INTRTX 0x0044 +#define MUSB_INTRRX 0x0046 +#define MUSB_INTRTXE 0x0048 +#define MUSB_INTRRXE 0x004A +#define MUSB_INTRUSB 0x004C +#define MUSB_INTRUSBE 0x0050 +#define MUSB_FRAME 0x0054 +#define MUSB_INDEX 0x0042 +#define MUSB_TESTMODE 0x007C + +/* Get offset for a given FIFO from musb->mregs */ +#define MUSB_FIFO_OFFSET(epnum) (0x00 + ((epnum) * 4)) + +/* + * Additional Control Registers + */ + +#define MUSB_DEVCTL 0x0041 + +/* These are always controlled through the INDEX register */ +#define MUSB_TXFIFOSZ 0x0090 +#define MUSB_RXFIFOSZ 0x0094 +#define MUSB_TXFIFOADD 0x0092 +#define MUSB_RXFIFOADD 0x0096 + +#define MUSB_EPINFO 0x0078 +#define MUSB_RAMINFO 0x0079 +#define MUSB_LINKINFO 0x007A +#define MUSB_VPLEN 0x007B +#define MUSB_HS_EOF1 0x007C +#define MUSB_FS_EOF1 0x007D +#define MUSB_LS_EOF1 0x007E + +/* Offsets to endpoint registers */ +#define MUSB_TXMAXP 0x0080 +#define MUSB_TXCSR 0x0082 +#define MUSB_CSR0 0x0082 +#define MUSB_RXMAXP 0x0084 +#define MUSB_RXCSR 0x0086 +#define MUSB_RXCOUNT 0x0088 +#define MUSB_COUNT0 0x0088 +#define MUSB_TXTYPE 0x008C +#define MUSB_TYPE0 0x008C +#define MUSB_TXINTERVAL 0x008D +#define MUSB_NAKLIMIT0 0x008D +#define MUSB_RXTYPE 0x008E +#define MUSB_RXINTERVAL 0x008F + +#define MUSB_CONFIGDATA 0x00b0 /* musb_read_configdata adds 0x10 ! */ +#define MUSB_FIFOSIZE 0x0090 + +/* Offsets to endpoint registers in indexed model (using INDEX register) */ +#define MUSB_INDEXED_OFFSET(_epnum, _offset) (_offset) + +#define MUSB_TXCSR_MODE 0x2000 + +/* "bus control"/target registers, for host side multipoint (external hubs) */ +#define MUSB_TXFUNCADDR 0x0098 +#define MUSB_TXHUBADDR 0x009A +#define MUSB_TXHUBPORT 0x009B + +#define MUSB_RXFUNCADDR 0x009C +#define MUSB_RXHUBADDR 0x009E +#define MUSB_RXHUBPORT 0x009F + +/* Endpoint is selected with MUSB_INDEX. */ +#define MUSB_BUSCTL_OFFSET(_epnum, _offset) (_offset) + +#endif /* CONFIG_ARCH_SUNXI */ + static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) { musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); @@ -340,7 +422,9 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) { +#ifndef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */ musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); +#endif } static inline u8 musb_read_txfifosz(void __iomem *mbase) @@ -365,7 +449,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) { +#ifdef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */ + return 0; +#else return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); +#endif } static inline u8 musb_read_configdata(void __iomem *mbase) @@ -376,7 +464,11 @@ static inline u8 musb_read_configdata(void __iomem *mbase) static inline u16 musb_read_hwvers(void __iomem *mbase) { +#ifdef CONFIG_ARCH_SUNXI + return 0; /* Unknown version */ +#else return musb_readw(mbase, MUSB_HWVERS); +#endif } static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index 2676f09..6e58ddf 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -12,6 +12,11 @@ #include "musb_gadget.h" #ifdef CONFIG_MUSB_HOST +struct int_queue { + struct usb_host_endpoint hep; + struct urb urb; +}; + static struct musb *host; static struct usb_hcd hcd; static enum usb_device_speed host_speed; @@ -25,45 +30,42 @@ static void musb_host_complete_urb(struct urb *urb) static struct usb_host_endpoint hep; static struct urb urb; -static struct urb *construct_urb(struct usb_device *dev, int endpoint_type, - unsigned long pipe, void *buffer, int len, - struct devrequest *setup, int interval) +static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep, + struct usb_device *dev, int endpoint_type, + unsigned long pipe, void *buffer, int len, + struct devrequest *setup, int interval) { int epnum = usb_pipeendpoint(pipe); int is_in = usb_pipein(pipe); - memset(&urb, 0, sizeof(struct urb)); - memset(&hep, 0, sizeof(struct usb_host_endpoint)); - INIT_LIST_HEAD(&hep.urb_list); - INIT_LIST_HEAD(&urb.urb_list); - urb.ep = &hep; - urb.complete = musb_host_complete_urb; - urb.status = -EINPROGRESS; - urb.dev = dev; - urb.pipe = pipe; - urb.transfer_buffer = buffer; - urb.transfer_dma = (unsigned long)buffer; - urb.transfer_buffer_length = len; - urb.setup_packet = (unsigned char *)setup; - - urb.ep->desc.wMaxPacketSize = + memset(urb, 0, sizeof(struct urb)); + memset(hep, 0, sizeof(struct usb_host_endpoint)); + INIT_LIST_HEAD(&hep->urb_list); + INIT_LIST_HEAD(&urb->urb_list); + urb->ep = hep; + urb->complete = musb_host_complete_urb; + urb->status = -EINPROGRESS; + urb->dev = dev; + urb->pipe = pipe; + urb->transfer_buffer = buffer; + urb->transfer_dma = (unsigned long)buffer; + urb->transfer_buffer_length = len; + urb->setup_packet = (unsigned char *)setup; + + urb->ep->desc.wMaxPacketSize = __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] : dev->epmaxpacketout[epnum]); - urb.ep->desc.bmAttributes = endpoint_type; - urb.ep->desc.bEndpointAddress = + urb->ep->desc.bmAttributes = endpoint_type; + urb->ep->desc.bEndpointAddress = (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum; - urb.ep->desc.bInterval = interval; - - return &urb; + urb->ep->desc.bInterval = interval; } -#define MUSB_HOST_TIMEOUT 0x3ffffff - static int submit_urb(struct usb_hcd *hcd, struct urb *urb) { struct musb *host = hcd->hcd_priv; int ret; - int timeout; + unsigned long timeout; ret = musb_urb_enqueue(hcd, urb, 0); if (ret < 0) { @@ -71,12 +73,16 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb) return ret; } - timeout = MUSB_HOST_TIMEOUT; + timeout = get_timer(0) + USB_TIMEOUT_MS(urb->pipe); do { if (ctrlc()) return -EIO; host->isr(0, host); - } while ((urb->dev->status & USB_ST_NOT_PROC) && --timeout); + } while (urb->status == -EINPROGRESS && + get_timer(0) < timeout); + + if (urb->status == -EINPROGRESS) + musb_urb_dequeue(hcd, urb, -ETIME); return urb->status; } @@ -84,38 +90,117 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb) int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len, struct devrequest *setup) { - struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_CONTROL, pipe, - buffer, len, setup, 0); + construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_CONTROL, pipe, + buffer, len, setup, 0); /* Fix speed for non hub-attached devices */ if (!dev->parent) dev->speed = host_speed; - return submit_urb(&hcd, urb); + return submit_urb(&hcd, &urb); } int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len) { - struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_BULK, pipe, - buffer, len, NULL, 0); - return submit_urb(&hcd, urb); + construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_BULK, pipe, + buffer, len, NULL, 0); + return submit_urb(&hcd, &urb); } int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len, int interval) { - struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_INT, pipe, - buffer, len, NULL, interval); - return submit_urb(&hcd, urb); + construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_INT, pipe, + buffer, len, NULL, interval); + return submit_urb(&hcd, &urb); } -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, + int queuesize, int elementsize, void *buffer, int interval) +{ + struct int_queue *queue; + int ret, index = usb_pipein(pipe) * 16 + usb_pipeendpoint(pipe); + + if (queuesize != 1) { + printf("ERROR musb int-queues only support queuesize 1\n"); + return NULL; + } + + if (dev->int_pending & (1 << index)) { + printf("ERROR int-urb is already pending on pipe %lx\n", pipe); + return NULL; + } + + queue = malloc(sizeof(*queue)); + if (!queue) + return NULL; + + construct_urb(&queue->urb, &queue->hep, dev, USB_ENDPOINT_XFER_INT, + pipe, buffer, elementsize, NULL, interval); + + ret = musb_urb_enqueue(&hcd, &queue->urb, 0); + if (ret < 0) { + printf("Failed to enqueue URB to controller\n"); + free(queue); + return NULL; + } + + dev->int_pending |= 1 << index; + return queue; +} + +int destroy_int_queue(struct usb_device *dev, struct int_queue *queue) +{ + int index = usb_pipein(queue->urb.pipe) * 16 + + usb_pipeendpoint(queue->urb.pipe); + + if (queue->urb.status == -EINPROGRESS) + musb_urb_dequeue(&hcd, &queue->urb, -ETIME); + + dev->int_pending &= ~(1 << index); + free(queue); + return 0; +} + +void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) { + if (queue->urb.status != -EINPROGRESS) + return NULL; /* URB has already completed in a prev. poll */ + + host->isr(0, host); + + if (queue->urb.status != -EINPROGRESS) + return queue->urb.transfer_buffer; /* Done */ + + return NULL; /* URB still pending */ +} + +void usb_reset_root_port(void) +{ + void *mbase = host->mregs; u8 power; + + power = musb_readb(mbase, MUSB_POWER); + power &= 0xf0; + musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power); + mdelay(50); + power = musb_readb(mbase, MUSB_POWER); + musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power); + host->isr(0, host); + host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ? + USB_SPEED_HIGH : + (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ? + USB_SPEED_FULL : USB_SPEED_LOW; + mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50); +} + +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ void *mbase; - int timeout = MUSB_HOST_TIMEOUT; + /* USB spec says it may take up to 1 second for a device to connect */ + unsigned long timeout = get_timer(0) + 1000; if (!host) { printf("MUSB host is not registered\n"); @@ -127,20 +212,11 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) do { if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM) break; - } while (--timeout); - if (!timeout) + } while (get_timer(0) < timeout); + if (get_timer(0) >= timeout) return -ENODEV; - power = musb_readb(mbase, MUSB_POWER); - musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power); - udelay(30000); - power = musb_readb(mbase, MUSB_POWER); - musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power); - host->isr(0, host); - host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ? - USB_SPEED_HIGH : - (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ? - USB_SPEED_FULL : USB_SPEED_LOW; + usb_reset_root_port(); host->is_active = 1; hcd.hcd_priv = host; diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c new file mode 100644 index 0000000..778916d --- /dev/null +++ b/drivers/usb/musb-new/sunxi.c @@ -0,0 +1,279 @@ +/* + * Allwinner SUNXI "glue layer" + * + * Copyright © 2015 Hans de Goede <hdegoede@redhat.com> + * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> + * + * Based on the sw_usb "Allwinner OTG Dual Role Controller" code. + * Copyright 2007-2012 (C) Allwinner Technology Co., Ltd. + * javen <javen@allwinnertech.com> + * + * Based on the DA8xx "glue layer" code. + * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com> + * Copyright (C) 2005-2006 by Texas Instruments + * + * This file is part of the Inventra Controller Driver for Linux. + * + * The Inventra Controller Driver for Linux is free software; you + * can redistribute it and/or modify it under the terms of the GNU + * General Public License version 2 as published by the Free Software + * Foundation. + * + */ +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/usbc.h> +#include "linux-compat.h" +#include "musb_core.h" + +/****************************************************************************** + ****************************************************************************** + * From the Allwinner driver + ****************************************************************************** + ******************************************************************************/ + +/****************************************************************************** + * From include/sunxi_usb_bsp.h + ******************************************************************************/ + +/* reg offsets */ +#define USBC_REG_o_ISCR 0x0400 +#define USBC_REG_o_PHYCTL 0x0404 +#define USBC_REG_o_PHYBIST 0x0408 +#define USBC_REG_o_PHYTUNE 0x040c + +#define USBC_REG_o_VEND0 0x0043 + +/* Interface Status and Control */ +#define USBC_BP_ISCR_VBUS_VALID_FROM_DATA 30 +#define USBC_BP_ISCR_VBUS_VALID_FROM_VBUS 29 +#define USBC_BP_ISCR_EXT_ID_STATUS 28 +#define USBC_BP_ISCR_EXT_DM_STATUS 27 +#define USBC_BP_ISCR_EXT_DP_STATUS 26 +#define USBC_BP_ISCR_MERGED_VBUS_STATUS 25 +#define USBC_BP_ISCR_MERGED_ID_STATUS 24 + +#define USBC_BP_ISCR_ID_PULLUP_EN 17 +#define USBC_BP_ISCR_DPDM_PULLUP_EN 16 +#define USBC_BP_ISCR_FORCE_ID 14 +#define USBC_BP_ISCR_FORCE_VBUS_VALID 12 +#define USBC_BP_ISCR_VBUS_VALID_SRC 10 + +#define USBC_BP_ISCR_HOSC_EN 7 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT 6 +#define USBC_BP_ISCR_ID_CHANGE_DETECT 5 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT 4 +#define USBC_BP_ISCR_IRQ_ENABLE 3 +#define USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN 2 +#define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1 +#define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0 + +/****************************************************************************** + * From usbc/usbc.c + ******************************************************************************/ + +static u32 USBC_WakeUp_ClearChangeDetect(u32 reg_val) +{ + u32 temp = reg_val; + + temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT); + temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT); + + return temp; +} + +static void USBC_EnableIdPullUp(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val |= (1 << USBC_BP_ISCR_ID_PULLUP_EN); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_DisableIdPullUp(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(1 << USBC_BP_ISCR_ID_PULLUP_EN); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_EnableDpDmPullUp(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_DisableDpDmPullUp(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(1 << USBC_BP_ISCR_DPDM_PULLUP_EN); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_ForceIdToLow(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID); + reg_val |= (0x02 << USBC_BP_ISCR_FORCE_ID); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_ForceIdToHigh(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID); + reg_val |= (0x03 << USBC_BP_ISCR_FORCE_ID); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_ForceVbusValidDisable(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_ForceVbusValidToHigh(__iomem void *base) +{ + u32 reg_val; + + reg_val = musb_readl(base, USBC_REG_o_ISCR); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); + reg_val |= (0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); + reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); + musb_writel(base, USBC_REG_o_ISCR, reg_val); +} + +static void USBC_ConfigFIFO_Base(void) +{ + u32 reg_value; + + /* config usb fifo, 8kb mode */ + reg_value = readl(SUNXI_SRAMC_BASE + 0x04); + reg_value &= ~(0x03 << 0); + reg_value |= (1 << 0); + writel(reg_value, SUNXI_SRAMC_BASE + 0x04); +} + +/****************************************************************************** + * MUSB Glue code + ******************************************************************************/ + +static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) +{ + struct musb *musb = __hci; + irqreturn_t retval = IRQ_NONE; + + /* read and flush interrupts */ + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + if (musb->int_usb) + musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + if (musb->int_tx) + musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + if (musb->int_rx) + musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval |= musb_interrupt(musb); + + return retval; +} + +static void sunxi_musb_enable(struct musb *musb) +{ + pr_debug("%s():\n", __func__); + + /* select PIO mode */ + musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0); + + if (is_host_enabled(musb)) { + /* port power on */ + sunxi_usbc_vbus_enable(0); + } +} + +static void sunxi_musb_disable(struct musb *musb) +{ + pr_debug("%s():\n", __func__); + + /* Put the controller back in a pristane state for "usb reset" */ + if (musb->is_active) { + sunxi_usbc_disable(0); + sunxi_usbc_enable(0); + musb->is_active = 0; + } +} + +static int sunxi_musb_init(struct musb *musb) +{ + int err; + + pr_debug("%s():\n", __func__); + + err = sunxi_usbc_request_resources(0); + if (err) + return err; + + musb->isr = sunxi_musb_interrupt; + sunxi_usbc_enable(0); + + USBC_ConfigFIFO_Base(); + USBC_EnableDpDmPullUp(musb->mregs); + USBC_EnableIdPullUp(musb->mregs); + + if (is_host_enabled(musb)) { + /* Host mode */ + USBC_ForceIdToLow(musb->mregs); + USBC_ForceVbusValidToHigh(musb->mregs); + } else { + /* Peripheral mode */ + USBC_ForceIdToHigh(musb->mregs); + USBC_ForceVbusValidDisable(musb->mregs); + } + + return 0; +} + +static int sunxi_musb_exit(struct musb *musb) +{ + pr_debug("%s():\n", __func__); + + USBC_DisableDpDmPullUp(musb->mregs); + USBC_DisableIdPullUp(musb->mregs); + sunxi_usbc_vbus_disable(0); + sunxi_usbc_disable(0); + + return sunxi_usbc_free_resources(0); +} + +const struct musb_platform_ops sunxi_musb_ops = { + .init = sunxi_musb_init, + .exit = sunxi_musb_exit, + + .enable = sunxi_musb_enable, + .disable = sunxi_musb_disable, +}; diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h index 27f656f..50bad37 100644 --- a/drivers/usb/musb-new/usb-compat.h +++ b/drivers/usb/musb-new/usb-compat.h @@ -48,6 +48,7 @@ struct urb { list_add_tail(&urb->urb_list, &urb->ep->urb_list); \ ret; }) #define usb_hcd_unlink_urb_from_ep(hcd, urb) list_del_init(&urb->urb_list) +#define usb_hcd_check_unlink_urb(hdc, urb, status) 0 static inline void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index be616e8..becbe3f 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -90,15 +90,8 @@ #endif #ifdef CONFIG_CMD_USB -#define BOOTENV_RUN_USB_INIT "run usb_init; " -#define BOOTENV_SET_USB_NEED_INIT "setenv usb_need_init; " +#define BOOTENV_RUN_USB_INIT "usb start; " #define BOOTENV_SHARED_USB \ - "usb_init=" \ - "if ${usb_need_init}; then " \ - "setenv usb_need_init false; " \ - "usb start 0; " \ - "fi\0" \ - \ "usb_boot=" \ BOOTENV_RUN_USB_INIT \ BOOTENV_SHARED_BLKDEV_BODY(usb) @@ -106,7 +99,6 @@ #define BOOTENV_DEV_NAME_USB BOOTENV_DEV_NAME_BLKDEV #else #define BOOTENV_RUN_USB_INIT -#define BOOTENV_SET_USB_NEED_INIT #define BOOTENV_SHARED_USB #define BOOTENV_DEV_USB \ BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB @@ -202,7 +194,7 @@ \ BOOT_TARGET_DEVICES(BOOTENV_DEV) \ \ - "bootcmd=" BOOTENV_SET_USB_NEED_INIT BOOTENV_SET_SCSI_NEED_INIT \ + "bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ "for target in ${boot_targets}; do " \ "run bootcmd_${target}; " \ "done\0" diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index 8ed0f7c..19e0e30 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -15,6 +15,8 @@ #define CONFIG_E300 1 /* E300 family */ #define CONFIG_MPC837x 1 /* MPC837x CPU specific */ #define CONFIG_MPC837XERDB 1 +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0xFE000000 diff --git a/include/configs/malta.h b/include/configs/malta.h index a29b86b..684d249 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -38,8 +38,6 @@ #define CONFIG_SYS_MHZ 250 /* arbitrary value */ #define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -#define CONFIG_SWAP_IO_SPACE - /* * Memory map */ diff --git a/include/fpga.h b/include/fpga.h index 914024c..e0d1298 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -49,18 +49,19 @@ typedef enum { } bitstream_type; /* root function definitions */ -extern void fpga_init(void); -extern int fpga_add(fpga_type devtype, void *desc); -extern int fpga_count(void); -extern int fpga_load(int devnum, const void *buf, size_t bsize, - bitstream_type bstype); -extern int fpga_fsload(int devnum, const void *buf, size_t size, - fpga_fs_info *fpga_fsinfo); -extern int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, - bitstream_type bstype); -extern int fpga_dump(int devnum, const void *buf, size_t bsize); -extern int fpga_info(int devnum); -extern const fpga_desc *const fpga_validate(int devnum, const void *buf, - size_t bsize, char *fn); +void fpga_init(void); +int fpga_add(fpga_type devtype, void *desc); +int fpga_count(void); +const fpga_desc *const fpga_get_desc(int devnum); +int fpga_load(int devnum, const void *buf, size_t bsize, + bitstream_type bstype); +int fpga_fsload(int devnum, const void *buf, size_t size, + fpga_fs_info *fpga_fsinfo); +int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, + bitstream_type bstype); +int fpga_dump(int devnum, const void *buf, size_t bsize); +int fpga_info(int devnum); +const fpga_desc *const fpga_validate(int devnum, const void *buf, + size_t bsize, char *fn); #endif /* _FPGA_H_ */ diff --git a/include/mmc.h b/include/mmc.h index 7ec255d..09101e2 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -147,11 +147,16 @@ /* * EXT_CSD fields */ +#define EXT_CSD_ENH_START_ADDR 136 /* R/W */ +#define EXT_CSD_ENH_SIZE_MULT 140 /* R/W */ #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ #define EXT_CSD_PARTITION_SETTING 155 /* R/W */ #define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ +#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* R */ #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ #define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ +#define EXT_CSD_WR_REL_PARAM 166 /* R */ +#define EXT_CSD_WR_REL_SET 167 /* R/W */ #define EXT_CSD_RPMB_MULT 168 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_BOOT_BUS_WIDTH 177 @@ -201,6 +206,14 @@ #define EXT_CSD_PARTITION_SETTING_COMPLETED (1 << 0) +#define EXT_CSD_ENH_USR (1 << 0) /* user data area is enhanced */ +#define EXT_CSD_ENH_GP(x) (1 << ((x)+1)) /* GP part (x+1) is enhanced */ + +#define EXT_CSD_HS_CTRL_REL (1 << 0) /* host controlled WR_REL_SET */ + +#define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */ +#define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x)+1)) /* GP part (x+1) WR_REL */ + #define R1_ILLEGAL_COMMAND (1 << 22) #define R1_APP_CMD (1 << 5) @@ -224,6 +237,7 @@ #define MMCPART_NOAVAILABLE (0xff) #define PART_ACCESS_MASK (0x7) #define PART_SUPPORT (0x1) +#define ENHNCD_SUPPORT (0x2) #define PART_ENH_ATTRIB (0x1f) /* Maximum block size for MMC */ @@ -302,17 +316,23 @@ struct mmc { uint csd[4]; uint cid[4]; ushort rca; + u8 part_support; + u8 part_attr; + u8 wr_rel_set; char part_config; char part_num; uint tran_speed; uint read_bl_len; uint write_bl_len; - uint erase_grp_size; + uint erase_grp_size; /* in 512-byte sectors */ + uint hc_wp_grp_size; /* in 512-byte sectors */ u64 capacity; u64 capacity_user; u64 capacity_boot; u64 capacity_rpmb; u64 capacity_gp[4]; + u64 enh_user_start; + u64 enh_user_size; block_dev_desc_t block_dev; char op_cond_pending; /* 1 if we are waiting on an op_cond command */ char init_in_progress; /* 1 if we have done mmc_start_init() */ @@ -321,6 +341,27 @@ struct mmc { int ddr_mode; }; +struct mmc_hwpart_conf { + struct { + uint enh_start; /* in 512-byte sectors */ + uint enh_size; /* in 512-byte sectors, if 0 no enh area */ + unsigned wr_rel_change : 1; + unsigned wr_rel_set : 1; + } user; + struct { + uint size; /* in 512-byte sectors */ + unsigned enhanced : 1; + unsigned wr_rel_change : 1; + unsigned wr_rel_set : 1; + } gp_part[4]; +}; + +enum mmc_hwpart_conf_mode { + MMC_HWPART_CONF_CHECK, + MMC_HWPART_CONF_SET, + MMC_HWPART_CONF_COMPLETE, +}; + int mmc_register(struct mmc *mmc); struct mmc *mmc_create(const struct mmc_config *cfg, void *priv); void mmc_destroy(struct mmc *mmc); @@ -333,6 +374,8 @@ int mmc_set_dev(int dev_num); void print_mmc_devices(char separator); int get_mmc_num(void); int mmc_switch_part(int dev_num, unsigned int part_num); +int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, + enum mmc_hwpart_conf_mode mode); int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); diff --git a/include/netdev.h b/include/netdev.h index 34651ab..daffc12 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -93,7 +93,8 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, unsigned long ctrl_addr); int zynq_gem_of_init(const void *blob); -int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio); +int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr, + int phy_addr, u32 emio); /* * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface * exported by a public hader file, we need a global definition at this point. diff --git a/include/spartan2.h b/include/spartan2.h index 2aca954..14606c3 100644 --- a/include/spartan2.h +++ b/include/spartan2.h @@ -38,7 +38,12 @@ typedef struct { xilinx_post_fn post; } xilinx_spartan2_slave_serial_fns; +#if defined(CONFIG_FPGA_SPARTAN2) extern struct xilinx_fpga_op spartan2_op; +# define FPGA_SPARTAN2_OPS &spartan2_op +#else +# define FPGA_SPARTAN2_OPS NULL +#endif /* Device Image Sizes *********************************************************************/ @@ -61,36 +66,47 @@ extern struct xilinx_fpga_op spartan2_op; *********************************************************************/ /* Spartan-II devices */ #define XILINX_XC2S15_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S30_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S50_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S100_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S150_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S200_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S200_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S200_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S50E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S50E_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S50E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S100E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S100E_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S100E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S150E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S150E_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S150E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S200E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S200E_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S200E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #define XILINX_XC2S300E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan2, iface, XILINX_XC2S300E_SIZE, fn_table, cookie, &spartan2_op } +{ xilinx_spartan2, iface, XILINX_XC2S300E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN2_OPS } #endif /* _SPARTAN2_H_ */ diff --git a/include/spartan3.h b/include/spartan3.h index d6d67a6..fcb27b0 100644 --- a/include/spartan3.h +++ b/include/spartan3.h @@ -40,7 +40,12 @@ typedef struct { xilinx_abort_fn abort; } xilinx_spartan3_slave_serial_fns; +#if defined(CONFIG_FPGA_SPARTAN3) extern struct xilinx_fpga_op spartan3_op; +# define FPGA_SPARTAN3_OPS &spartan3_op +#else +# define FPGA_SPARTAN3_OPS NULL +#endif /* Device Image Sizes *********************************************************************/ @@ -71,48 +76,60 @@ extern struct xilinx_fpga_op spartan3_op; *********************************************************************/ /* Spartan-III devices */ #define XILINX_XC3S50_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S50_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S50_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S200_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S200_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S200_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S400_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S400_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S400_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S1000_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S1000_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S1000_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S1500_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S1500_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S1500_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S2000_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S2000_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S2000_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S4000_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S4000_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S4000_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S5000_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S5000_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S5000_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } /* Spartan-3E devices */ #define XILINX_XC3S100E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S100E_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S100E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S250E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S250E_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S250E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S500E_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINX_XC3S500E_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINX_XC3S500E_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #define XILINX_XC3S1200E_DESC(iface, fn_table, cookie) \ { xilinx_spartan3, iface, XILINX_XC3S1200E_SIZE, fn_table, cookie, \ - &spartan3_op } + FPGA_SPARTAN3_OPS } #define XILINX_XC3S1600E_DESC(iface, fn_table, cookie) \ { xilinx_spartan3, iface, XILINX_XC3S1600E_SIZE, fn_table, cookie, \ - &spartan3_op } + FPGA_SPARTAN3_OPS } #define XILINX_XC6SLX4_DESC(iface, fn_table, cookie) \ -{ xilinx_spartan3, iface, XILINK_XC6SLX4_SIZE, fn_table, cookie, &spartan3_op } +{ xilinx_spartan3, iface, XILINK_XC6SLX4_SIZE, fn_table, cookie, \ + FPGA_SPARTAN3_OPS } #endif /* _SPARTAN3_H_ */ diff --git a/include/usb.h b/include/usb.h index d3c7415..a8fee0b 100644 --- a/include/usb.h +++ b/include/usb.h @@ -120,6 +120,7 @@ struct usb_device { * Each instance needs its own set of data structures. */ unsigned long status; + unsigned long int_pending; /* 1 bit per ep, used by int_queue */ int act_len; /* transfered bytes */ int maxchild; /* Number of ports if hub */ int portnr; @@ -154,11 +155,16 @@ enum usb_init_type { defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \ defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \ defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \ - defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) || \ - defined(CONFIG_USB_DWC2) + defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \ + defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) int usb_lowlevel_init(int index, enum usb_init_type init, void **controller); int usb_lowlevel_stop(int index); +#ifdef CONFIG_MUSB_HOST +void usb_reset_root_port(void); +#else +#define usb_reset_root_port() +#endif int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len); @@ -167,9 +173,9 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval); -#ifdef CONFIG_USB_EHCI /* Only the ehci code has pollable int support */ +#if defined CONFIG_USB_EHCI || defined CONFIG_MUSB_HOST struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, - int queuesize, int elementsize, void *buffer); + int queuesize, int elementsize, void *buffer, int interval); int destroy_int_queue(struct usb_device *dev, struct int_queue *queue); void *poll_int_queue(struct usb_device *dev, struct int_queue *queue); #endif diff --git a/include/virtex2.h b/include/virtex2.h index 7b7825f..503df9a 100644 --- a/include/virtex2.h +++ b/include/virtex2.h @@ -11,8 +11,6 @@ #include <xilinx.h> -extern struct xilinx_fpga_op virtex2_op; - /* * Slave SelectMap Implementation function table. */ @@ -40,12 +38,19 @@ typedef struct { xilinx_wdata_fn wdata; } xilinx_virtex2_slave_serial_fns; +#if defined(CONFIG_FPGA_VIRTEX2) +extern struct xilinx_fpga_op virtex2_op; +# define FPGA_VIRTEX2_OPS &virtex2_op +#else +# define FPGA_VIRTEX2_OPS NULL +#endif + /* Device Image Sizes (in bytes) *********************************************************************/ -#define XILINX_XC2V40_SIZE (338208 / 8) -#define XILINX_XC2V80_SIZE (597408 / 8) -#define XILINX_XC2V250_SIZE (1591584 / 8) -#define XILINX_XC2V500_SIZE (2557857 / 8) +#define XILINX_XC2V40_SIZE (338208 / 8) +#define XILINX_XC2V80_SIZE (597408 / 8) +#define XILINX_XC2V250_SIZE (1591584 / 8) +#define XILINX_XC2V500_SIZE (2557857 / 8) #define XILINX_XC2V1000_SIZE (3749408 / 8) #define XILINX_XC2V1500_SIZE (5166240 / 8) #define XILINX_XC2V2000_SIZE (6808352 / 8) @@ -58,39 +63,51 @@ typedef struct { /* Descriptor Macros *********************************************************************/ #define XILINX_XC2V40_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V80_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V250_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V500_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V1000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V1500_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V2000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V3000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V4000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V6000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V8000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #define XILINX_XC2V10000_DESC(iface, fn_table, cookie) \ -{ xilinx_virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie, &virtex2_op } +{ xilinx_virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie, \ + FPGA_VIRTEX2_OPS } #endif /* _VIRTEX2_H_ */ diff --git a/include/zynqpl.h b/include/zynqpl.h index 8a9ec32..1d37a51 100644 --- a/include/zynqpl.h +++ b/include/zynqpl.h @@ -12,12 +12,18 @@ #include <xilinx.h> +#if defined(CONFIG_FPGA_ZYNQPL) extern struct xilinx_fpga_op zynq_op; +# define FPGA_ZYNQPL_OPS &zynq_op +#else +# define FPGA_ZYNQPL_OPS NULL +#endif #define XILINX_ZYNQ_7010 0x2 #define XILINX_ZYNQ_7015 0x1b #define XILINX_ZYNQ_7020 0x7 #define XILINX_ZYNQ_7030 0xc +#define XILINX_ZYNQ_7035 0x12 #define XILINX_ZYNQ_7045 0x11 #define XILINX_ZYNQ_7100 0x16 @@ -26,26 +32,37 @@ extern struct xilinx_fpga_op zynq_op; #define XILINX_XC7Z015_SIZE 28085344/8 #define XILINX_XC7Z020_SIZE 32364512/8 #define XILINX_XC7Z030_SIZE 47839328/8 +#define XILINX_XC7Z035_SIZE 106571232/8 #define XILINX_XC7Z045_SIZE 106571232/8 #define XILINX_XC7Z100_SIZE 139330784/8 /* Descriptor Macros */ #define XILINX_XC7Z010_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie, &zynq_op, "7z010" } +{ xilinx_zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z010" } #define XILINX_XC7Z015_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z015_SIZE, NULL, cookie, &zynq_op, "7z015" } +{ xilinx_zynq, devcfg, XILINX_XC7Z015_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z015" } #define XILINX_XC7Z020_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie, &zynq_op, "7z020" } +{ xilinx_zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z020" } #define XILINX_XC7Z030_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie, &zynq_op, "7z030" } +{ xilinx_zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z030" } + +#define XILINX_XC7Z035_DESC(cookie) \ +{ xilinx_zynq, devcfg, XILINX_XC7Z035_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z035" } #define XILINX_XC7Z045_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie, &zynq_op, "7z045" } +{ xilinx_zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z045" } #define XILINX_XC7Z100_DESC(cookie) \ -{ xilinx_zynq, devcfg, XILINX_XC7Z100_SIZE, NULL, cookie, &zynq_op, "7z100" } +{ xilinx_zynq, devcfg, XILINX_XC7Z100_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \ + "7z100" } #endif /* _ZYNQPL_H_ */ |