Date:2012-12-28 02:57:26 (1 year 6 months ago)
Author:Xiangfu
Commit:5938c827edeb1bab6471384cdb67d06dbb393f24
Message:uboot-xburst: update to 2012.10-rc2

Files: package/boot/uboot-xburst/Makefile (5 diffs)
package/boot/uboot-xburst/files/board/n516/Makefile (1 diff)
package/boot/uboot-xburst/files/board/n516/config.mk (1 diff)
package/boot/uboot-xburst/files/board/n516/flash.c (1 diff)
package/boot/uboot-xburst/files/board/n516/n516.c (1 diff)
package/boot/uboot-xburst/files/board/n516/u-boot-nand.lds (1 diff)
package/boot/uboot-xburst/files/board/n516/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/board/nanonote/Makefile (1 diff)
package/boot/uboot-xburst/files/board/nanonote/config.mk (1 diff)
package/boot/uboot-xburst/files/board/nanonote/nanonote.c (1 diff)
package/boot/uboot-xburst/files/board/nanonote/u-boot-nand.lds (1 diff)
package/boot/uboot-xburst/files/board/nanonote/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/board/sakc/Makefile (1 diff)
package/boot/uboot-xburst/files/board/sakc/config.mk (1 diff)
package/boot/uboot-xburst/files/board/sakc/sakc.c (1 diff)
package/boot/uboot-xburst/files/board/sakc/u-boot-nand.lds (1 diff)
package/boot/uboot-xburst/files/board/sakc/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz4740.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz4740_nand.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz_lcd.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz_lcd.h (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz_mmc.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz_mmc.h (1 diff)
package/boot/uboot-xburst/files/cpu/mips/jz_serial.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/mmc_protocol.h (1 diff)
package/boot/uboot-xburst/files/cpu/mips/nanonote_gpm940b0.c (1 diff)
package/boot/uboot-xburst/files/cpu/mips/nanonote_gpm940b0.h (1 diff)
package/boot/uboot-xburst/files/cpu/mips/usb_boot.S (1 diff)
package/boot/uboot-xburst/files/include/asm-mips/jz4740.h (1 diff)
package/boot/uboot-xburst/files/include/configs/avt2.h (1 diff)
package/boot/uboot-xburst/files/include/configs/n516.h (1 diff)
package/boot/uboot-xburst/files/include/configs/nanonote.h (1 diff)
package/boot/uboot-xburst/files/include/configs/qi_lb60.h (1 diff)
package/boot/uboot-xburst/files/include/configs/sakc.h (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/n516/Makefile (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/n516/config.mk (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/n516/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/nanonote/Makefile (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/nanonote/config.mk (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/nanonote/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/sakc/Makefile (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/sakc/config.mk (1 diff)
package/boot/uboot-xburst/files/nand_spl/board/sakc/u-boot.lds (1 diff)
package/boot/uboot-xburst/files/nand_spl/nand_boot_jz4740.c (1 diff)
package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch (1 diff)
package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch (1 diff)
package/boot/uboot-xburst/patches/0003-add-mmc-support.patch (1 diff)
package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch (1 diff)
package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch (1 diff)
package/boot/uboot-xburst/patches/0006-enable-silent-console.patch (1 diff)
package/boot/uboot-xburst/patches/001-xburst.patch (1 diff)
package/boot/uboot-xburst/patches/005-i2c.patch (1 diff)
package/boot/uboot-xburst/patches/009-n516.patch (1 diff)
package/boot/uboot-xburst/patches/010-sakc.patch (1 diff)

Change Details

package/boot/uboot-xburst/Makefile
99include $(INCLUDE_DIR)/kernel.mk
1010
1111PKG_NAME:=u-boot
12PKG_VERSION:=2009.11
12PKG_VERSION:=2012.10-rc2
1313PKG_RELEASE:=1
1414
1515PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
1616PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
1717PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
18PKG_MD5SUM:=
18PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b
1919PKG_TARGETS:=bin
2020
2121include $(INCLUDE_DIR)/package.mk
...... 
3030  TITLE:=U-boot for the qi_lb60 board
3131endef
3232
33define uboot/avt2
34  TITLE:=U-boot for the avt2 board
35endef
36
37define uboot/sakc
38  TITLE:=U-boot for the sakc board
39endef
40
41define uboot/n516
42  TITLE:=U-boot for the N516 e-book reader
43  CONFIG:=n516_nand
44endef
45
46UBOOTS:=qi_lb60 n516 avt2 sakc
33UBOOTS:=qi_lb60
4734
4835define Package/uboot/template
4936define Package/uboot-xburst-$(1)
...... 
5138  CATEGORY:=Boot Loaders
5239  DEPENDS:=@TARGET_xburst
5340  TITLE:=$(2)
54  URL:=http://www.denx.de/wiki/U-Boot
41  URL:=http://www.denx.de/wiki/UBoot/WebHome
5542  VARIANT:=$(1)
5643endef
5744endef
...... 
6653ifdef BUILD_VARIANT
6754$(eval $(call uboot/$(BUILD_VARIANT)))
6855UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
69UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
56UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_BARIANT)-u-boot.bin)
7057endif
7158
72define Build/Prepare
73    $(call Build/Prepare/Default)
74    $(CP) ./files/* $(PKG_BUILD_DIR)
75    find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
76endef
77
7859define Build/Configure
7960    $(MAKE) -C $(PKG_BUILD_DIR) \
8061        $(UBOOT_CONFIG)_config
...... 
8768
8869define Package/uboot/install/template
8970define Package/uboot-xburst-$(1)/install
90    $(INSTALL_DIR) $$(1)
91    $(CP) $(PKG_BUILD_DIR)/u-boot-nand.bin $(BIN_DIR)/$(2)
71    $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2)
72    rmdir $$(1)
9273endef
9374endef
9475
package/boot/uboot-xburst/files/board/n516/Makefile
1#
2# (C) Copyright 2006
3# Ingenic Semiconductor, <jlwei@ingenic.cn>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21include $(TOPDIR)/config.mk
22
23LIB = $(obj)lib$(BOARD).a
24
25COBJS = $(BOARD).o flash.o
26
27OBJS = $(addprefix $(obj),$(COBJS))
28SOBJS =
29
30$(LIB): $(obj).depend $(OBJS) $(SOBJS)
31    $(AR) crv $@ $(OBJS) $(SOBJS)
32
33#########################################################################
34
35$(obj).depend: Makefile $(SOBJS:.o=.S) $(COBJS:.o=.c)
36        $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(COBJS:.o=.c) > $@
37
38sinclude $(obj).depend
39
40#########################################################################
package/boot/uboot-xburst/files/board/n516/config.mk
1#
2# (C) Copyright 2006
3# Ingenic Semiconductor, <jlwei@ingenic.cn>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21#
22# Hanvon n516 e-book, MIPS32 core
23#
24
25sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
26
27ifndef TEXT_BASE
28# ROM version
29TEXT_BASE = 0x88000000
30
31# RAM version
32#TEXT_BASE = 0x80100000
33endif
package/boot/uboot-xburst/files/board/n516/flash.c
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21#include <common.h>
22
23flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
24
25/*-----------------------------------------------------------------------
26 * flash_init()
27 *
28 * sets up flash_info and returns size of FLASH (bytes)
29 */
30unsigned long flash_init (void)
31{
32    return (0);
33}
34
35int flash_erase (flash_info_t * info, int s_first, int s_last)
36{
37    printf ("flash_erase not implemented\n");
38    return 0;
39}
40
41void flash_print_info (flash_info_t * info)
42{
43    printf ("flash_print_info not implemented\n");
44}
45
46int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
47{
48    printf ("write_buff not implemented\n");
49    return (-1);
50}
package/boot/uboot-xburst/files/board/n516/n516.c
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21#include <common.h>
22#include <command.h>
23#include <asm/mipsregs.h>
24#include <asm/jz4740.h>
25#include <asm/addrspace.h>
26#include <asm/cacheops.h>
27
28void _machine_restart(void)
29{
30    __wdt_select_extalclk();
31    __wdt_select_clk_div64();
32    __wdt_set_data(100);
33    __wdt_set_count(0);
34    __tcu_start_wdt_clock();
35    __wdt_start();
36    while(1);
37
38}
39
40static void gpio_init(void)
41{
42
43    REG_GPIO_PXPES(0) = 0xffffffff;
44    REG_GPIO_PXPES(1) = 0xffffffff;
45    REG_GPIO_PXPES(2) = 0xffffffff;
46    REG_GPIO_PXPES(3) = 0xffffffff;
47
48    /*
49     * Initialize NAND Flash Pins
50     */
51    __gpio_as_nand();
52
53    /*
54     * Initialize SDRAM pins
55     */
56    __gpio_as_sdram_32bit();
57
58    /*
59     * Initialize UART0 pins
60     */
61    __gpio_as_uart0();
62
63    /*
64     * Initialize MSC pins
65     */
66    __gpio_as_msc();
67
68    /*
69     * Initialize LCD pins
70     */
71    __gpio_as_lcd_16bit();
72
73    /*
74     * Initialize Other pins
75     */
76    __gpio_as_output(GPIO_SD_VCC_EN_N);
77    __gpio_clear_pin(GPIO_SD_VCC_EN_N);
78
79    __gpio_as_input(GPIO_SD_CD_N);
80    __gpio_disable_pull(GPIO_SD_CD_N);
81
82    __gpio_as_output(GPIO_DISP_OFF_N);
83
84    __gpio_as_output(GPIO_LED_EN);
85    __gpio_set_pin(GPIO_LED_EN);
86
87    __gpio_as_input(127);
88}
89
90static void cpm_init(void)
91{
92    __cpm_stop_ipu();
93    __cpm_stop_cim();
94    __cpm_stop_i2c();
95    __cpm_stop_ssi();
96    __cpm_stop_uart1();
97    __cpm_stop_sadc();
98    __cpm_stop_uhc();
99    __cpm_stop_udc();
100    __cpm_stop_aic1();
101    __cpm_stop_aic2();
102    __cpm_suspend_udcphy();
103    __cpm_suspend_usbphy();
104}
105
106//----------------------------------------------------------------------
107// board early init routine
108
109void board_early_init(void)
110{
111    gpio_init();
112    cpm_init();
113}
114
115//----------------------------------------------------------------------
116// U-Boot common routines
117
118int checkboard (void)
119{
120    DECLARE_GLOBAL_DATA_PTR;
121
122    printf("Board: Hanvon n516 e-book (CPU Speed %d MHz)\n",
123           gd->cpu_clk/1000000);
124
125    return 0; /* success */
126}
package/boot/uboot-xburst/files/board/n516/u-boot-nand.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/board/n516/u-boot.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/board/nanonote/Makefile
1#
2# (C) Copyright 2006
3# Ingenic Semiconductor, <jlwei@ingenic.cn>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21include $(TOPDIR)/config.mk
22
23LIB = lib$(BOARD).a
24
25OBJS = $(BOARD).o
26SOBJS =
27
28$(LIB): .depend $(OBJS) $(SOBJS)
29    $(AR) crv $@ $(OBJS) $(SOBJS)
30
31#########################################################################
32
33.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
34        $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
35
36sinclude .depend
37
38#########################################################################
package/boot/uboot-xburst/files/board/nanonote/config.mk
1#
2# (C) Copyright 2006 Qi Hardware, Inc.
3# Author: Xiangfu Liu <xiangfu.z@gmail.com>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21#
22# Qi Hardware, Inc. Ben NanoNote (QI_LB60)
23#
24
25ifndef TEXT_BASE
26# ROM version
27# TEXT_BASE = 0x88000000
28
29# RAM version
30TEXT_BASE = 0x80100000
31endif
package/boot/uboot-xburst/files/board/nanonote/nanonote.c
1/*
2 * Authors: Xiangfu Liu <xiangfu.z@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 3 of the License, or (at your option) any later version.
8 */
9
10#include <common.h>
11#include <command.h>
12#include <asm/mipsregs.h>
13#include <asm/jz4740.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17static void gpio_init(void)
18{
19    /*
20     * Initialize NAND Flash Pins
21     */
22    __gpio_as_nand();
23
24    /*
25     * Initialize SDRAM pins
26     */
27    __gpio_as_sdram_32bit();
28
29    /*
30     * Initialize LCD pins
31     */
32    __gpio_as_lcd_8bit();
33
34    /*
35     * Initialize MSC pins
36     */
37    __gpio_as_msc();
38
39    /*
40     * Initialize Other pins
41     */
42    unsigned int i;
43    for (i = 0; i < 7; i++){
44        __gpio_as_input(GPIO_KEYIN_BASE + i);
45        __gpio_enable_pull(GPIO_KEYIN_BASE + i);
46    }
47
48    for (i = 0; i < 8; i++) {
49        __gpio_as_output(GPIO_KEYOUT_BASE + i);
50        __gpio_clear_pin(GPIO_KEYOUT_BASE + i);
51    }
52
53    /*
54     * Initialize UART0 pins, in Ben NanoNote uart0 and keyin8 use the
55     * same gpio, init the gpio as uart0 cause a keyboard bug. so for
56     * end user we disable the uart0
57     */
58    if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
59        /* if pressed [S] */
60        printf("[S] pressed, enable UART0\n");
61        gd->boot_option = 5;
62        __gpio_as_uart0();
63    } else {
64        printf("[S] not pressed, disable UART0\n");
65        __gpio_as_input(GPIO_KEYIN_8);
66        __gpio_enable_pull(GPIO_KEYIN_8);
67    }
68
69    __gpio_as_output(GPIO_AUDIO_POP);
70    __gpio_set_pin(GPIO_AUDIO_POP);
71
72    __gpio_as_output(GPIO_LCD_CS);
73    __gpio_clear_pin(GPIO_LCD_CS);
74
75    __gpio_as_output(GPIO_AMP_EN);
76    __gpio_clear_pin(GPIO_AMP_EN);
77
78    __gpio_as_output(GPIO_SDPW_EN);
79    __gpio_disable_pull(GPIO_SDPW_EN);
80    __gpio_clear_pin(GPIO_SDPW_EN);
81
82    __gpio_as_input(GPIO_SD_DETECT);
83    __gpio_disable_pull(GPIO_SD_DETECT);
84
85    __gpio_as_input(GPIO_USB_DETECT);
86    __gpio_enable_pull(GPIO_USB_DETECT);
87
88    if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) {
89        printf("[M] pressed, boot from sd card\n");
90        gd->boot_option = 1;
91    }
92}
93
94static void cpm_init(void)
95{
96    __cpm_stop_ipu();
97    __cpm_stop_cim();
98    __cpm_stop_i2c();
99    __cpm_stop_ssi();
100    __cpm_stop_uart1();
101    __cpm_stop_sadc();
102    __cpm_stop_uhc();
103    __cpm_stop_udc();
104    __cpm_stop_aic1();
105/* __cpm_stop_aic2();*/
106}
107
108void board_early_init(void)
109{
110    gpio_init();
111    cpm_init();
112}
113
114/* U-Boot common routines */
115
116int checkboard (void)
117{
118
119    printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %d MHz)\n",
120           gd->cpu_clk/1000000);
121
122    return 0; /* success */
123}
package/boot/uboot-xburst/files/board/nanonote/u-boot-nand.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/board/nanonote/u-boot.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/board/sakc/Makefile
1#
2# (C) Copyright 2006
3# Ingenic Semiconductor, <jlwei@ingenic.cn>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21include $(TOPDIR)/config.mk
22
23LIB = lib$(BOARD).a
24
25OBJS = $(BOARD).o
26SOBJS =
27
28$(LIB): .depend $(OBJS) $(SOBJS)
29    $(AR) crv $@ $(OBJS) $(SOBJS)
30
31#########################################################################
32
33.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
34        $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
35
36sinclude .depend
37
38#########################################################################
package/boot/uboot-xburst/files/board/sakc/config.mk
1#
2# (C) Copyright 2006 Qi Hardware, Inc.
3# Author: Xiangfu Liu <xiangfu.z@gmail.com>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of
8# the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18# MA 02111-1307 USA
19#
20
21#
22# SAKC Board
23#
24
25ifndef TEXT_BASE
26# ROM version
27# TEXT_BASE = 0x88000000
28
29# RAM version
30TEXT_BASE = 0x80100000
31endif
package/boot/uboot-xburst/files/board/sakc/sakc.c
1/*
2 * Authors: Xiangfu Liu <xiangfu.z@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 3 of the License, or (at your option) any later version.
8 */
9
10#include <common.h>
11#include <command.h>
12#include <asm/mipsregs.h>
13#include <asm/jz4740.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17static void gpio_init(void)
18{
19    /*
20     * Initialize NAND Flash Pins
21     */
22    __gpio_as_nand();
23
24    /*
25     * Initialize SDRAM pins
26     */
27    __gpio_as_sdram_16bit_4725();
28
29    /*
30     * Initialize UART0 pins
31     */
32    __gpio_as_uart0();
33
34    /*
35     * Initialize LCD pins
36     */
37    __gpio_as_lcd_18bit();
38
39    /*
40     * Initialize MSC pins
41     */
42    __gpio_as_msc();
43
44    /*
45     * Initialize SSI pins
46     */
47    __gpio_as_ssi();
48
49    /*
50     * Initialize I2C pins
51     */
52    __gpio_as_i2c();
53
54    /*
55     * Initialize MSC pins
56     */
57    __gpio_as_msc();
58
59    /*
60     * Initialize Other pins
61     */
62    __gpio_as_input(GPIO_SD_DETECT);
63    __gpio_disable_pull(GPIO_SD_DETECT);
64}
65/* TODO SAKC
66static void cpm_init(void)
67{
68    __cpm_stop_ipu();
69    __cpm_stop_cim();
70    __cpm_stop_i2c();
71    __cpm_stop_ssi();
72    __cpm_stop_uart1();
73    __cpm_stop_sadc();
74    __cpm_stop_uhc();
75    __cpm_stop_aic1();
76    __cpm_stop_aic2();
77}*/
78
79void board_early_init(void)
80{
81    gpio_init();
82    //cpm_init(); //TODO SAKC
83}
84
85/* U-Boot common routines */
86
87int checkboard (void)
88{
89
90    printf("Board: SAKC (Ingenic XBurst Jz4725 SoC, Speed %d MHz)\n",
91           gd->cpu_clk/1000000);
92
93    return 0; /* success */
94}
package/boot/uboot-xburst/files/board/sakc/u-boot-nand.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/board/sakc/u-boot.lds
1/*
2 * (C) Copyright 2006
3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
22
23OUTPUT_ARCH(mips)
24ENTRY(_start)
25SECTIONS
26{
27    . = 0x00000000;
28
29    . = ALIGN(4);
30    .text :
31    {
32      *(.text)
33    }
34
35    . = ALIGN(4);
36    .rodata : { *(.rodata) }
37
38    . = ALIGN(4);
39    .data : { *(.data) }
40
41    . = ALIGN(4);
42    .sdata : { *(.sdata) }
43
44    _gp = ALIGN(16);
45
46    __got_start = .;
47    .got : { *(.got) }
48    __got_end = .;
49
50    .sdata : { *(.sdata) }
51
52    __u_boot_cmd_start = .;
53    .u_boot_cmd : { *(.u_boot_cmd) }
54    __u_boot_cmd_end = .;
55
56    uboot_end_data = .;
57    num_got_entries = (__got_end - __got_start) >> 2;
58
59    . = ALIGN(4);
60    .sbss : { *(.sbss) }
61    .bss : { *(.bss) }
62    uboot_end = .;
63}
package/boot/uboot-xburst/files/cpu/mips/jz4740.c
1/*
2 * Jz4740 common routines
3 *
4 * Copyright (c) 2006
5 * Ingenic Semiconductor, <jlwei@ingenic.cn>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <config.h>
24
25#ifdef CONFIG_JZ4740
26#include <common.h>
27#include <command.h>
28#include <asm/jz4740.h>
29
30extern void board_early_init(void);
31
32/* PLL output clock = EXTAL * NF / (NR * NO)
33 *
34 * NF = FD + 2, NR = RD + 2
35 * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
36 */
37void pll_init(void)
38{
39    register unsigned int cfcr, plcr1;
40    int n2FR[33] = {
41        0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
42        7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
43        9
44    };
45    int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
46    int nf, pllout2;
47
48    cfcr = CPM_CPCCR_CLKOEN |
49        CPM_CPCCR_PCS |
50        (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
51        (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
52        (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
53        (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
54        (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
55
56    pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
57
58    /* Init USB Host clock, pllout2 must be n*48MHz */
59    REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
60
61    nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
62    plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
63        (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
64        (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
65        (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
66        CPM_CPPCR_PLLEN; /* enable PLL */
67
68    /* init PLL */
69    REG_CPM_CPCCR = cfcr;
70    REG_CPM_CPPCR = plcr1;
71}
72
73void pll_add_test(int new_freq)
74{
75    register unsigned int cfcr, plcr1;
76    int n2FR[33] = {
77        0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
78        7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
79        9
80    };
81    int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:M:L */
82    int nf, pllout2;
83
84    cfcr = CPM_CPCCR_CLKOEN |
85        (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
86        (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
87        (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
88        (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
89        (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
90
91    pllout2 = (cfcr & CPM_CPCCR_PCS) ? new_freq : (new_freq / 2);
92
93    /* Init UHC clock */
94    REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
95
96    /* nf = new_freq * 2 / CONFIG_SYS_EXTAL; */
97    nf = new_freq / 1000000; /* step length is 1M */
98    plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
99        (10 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
100        (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
101        (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
102        CPM_CPPCR_PLLEN; /* enable PLL */
103
104    /* init PLL */
105    REG_CPM_CPCCR = cfcr;
106    REG_CPM_CPPCR = plcr1;
107}
108
109void calc_clocks_add_test(void)
110{
111    DECLARE_GLOBAL_DATA_PTR;
112
113    unsigned int pllout;
114    unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
115
116    pllout = __cpm_get_pllout();
117
118    gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
119    gd->sys_clk = pllout / div[__cpm_get_hdiv()];
120    gd->per_clk = pllout / div[__cpm_get_pdiv()];
121    gd->mem_clk = pllout / div[__cpm_get_mdiv()];
122    gd->dev_clk = CONFIG_SYS_EXTAL;
123}
124
125void sdram_add_test(int new_freq)
126{
127    register unsigned int dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
128
129    unsigned int cas_latency_sdmr[2] = {
130        EMC_SDMR_CAS_2,
131        EMC_SDMR_CAS_3,
132    };
133
134    unsigned int cas_latency_dmcr[2] = {
135        1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
136        2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
137    };
138
139    int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
140
141    cpu_clk = new_freq;
142    mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
143
144    REG_EMC_RTCSR = EMC_RTCSR_CKS_DISABLE;
145    REG_EMC_RTCOR = 0;
146    REG_EMC_RTCNT = 0;
147
148    /* Basic DMCR register value. */
149    dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
150        ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
151        (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
152        (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
153        EMC_DMCR_EPIN |
154        cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
155
156    /* SDRAM timimg parameters */
157    ns = 1000000000 / mem_clk;
158
159#if 0
160    tmp = SDRAM_TRAS/ns;
161    if (tmp < 4) tmp = 4;
162    if (tmp > 11) tmp = 11;
163    dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
164
165    tmp = SDRAM_RCD/ns;
166    if (tmp > 3) tmp = 3;
167    dmcr |= (tmp << EMC_DMCR_RCD_BIT);
168
169    tmp = SDRAM_TPC/ns;
170    if (tmp > 7) tmp = 7;
171    dmcr |= (tmp << EMC_DMCR_TPC_BIT);
172
173    tmp = SDRAM_TRWL/ns;
174    if (tmp > 3) tmp = 3;
175    dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
176
177    tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
178    if (tmp > 14) tmp = 14;
179    dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
180#else
181    dmcr |= 0xfffc;
182#endif
183
184    /* First, precharge phase */
185    REG_EMC_DMCR = dmcr;
186
187    /* Set refresh registers */
188    tmp = SDRAM_TREF/ns;
189    tmp = tmp/64 + 1;
190    if (tmp > 0xff) tmp = 0xff;
191
192    REG_EMC_RTCOR = tmp;
193    REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
194
195    /* SDRAM mode values */
196    sdmode = EMC_SDMR_BT_SEQ |
197         EMC_SDMR_OM_NORMAL |
198         EMC_SDMR_BL_4 |
199         cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
200
201    /* precharge all chip-selects */
202    REG8(EMC_SDMR0|sdmode) = 0;
203
204    /* wait for precharge, > 200us */
205    tmp = (cpu_clk / 1000000) * 200;
206    while (tmp--);
207
208    /* enable refresh and set SDRAM mode */
209    REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
210
211    /* write sdram mode register for each chip-select */
212    REG8(EMC_SDMR0|sdmode) = 0;
213
214    /* everything is ok now */
215}
216
217void sdram_init(void)
218{
219    register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
220
221    unsigned int cas_latency_sdmr[2] = {
222        EMC_SDMR_CAS_2,
223        EMC_SDMR_CAS_3,
224    };
225
226    unsigned int cas_latency_dmcr[2] = {
227        1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
228        2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
229    };
230
231    int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
232
233    cpu_clk = CONFIG_SYS_CPU_SPEED;
234    mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
235
236    REG_EMC_BCR = 0; /* Disable bus release */
237    REG_EMC_RTCSR = 0; /* Disable clock for counting */
238
239    /* Fault DMCR value for mode register setting*/
240#define SDRAM_ROW0 11
241#define SDRAM_COL0 8
242#define SDRAM_BANK40 0
243
244    dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
245        ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
246        (SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
247        (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
248        EMC_DMCR_EPIN |
249        cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
250
251    /* Basic DMCR value */
252    dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
253        ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
254        (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
255        (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
256        EMC_DMCR_EPIN |
257        cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
258
259    /* SDRAM timimg */
260    ns = 1000000000 / mem_clk;
261    tmp = SDRAM_TRAS/ns;
262    if (tmp < 4) tmp = 4;
263    if (tmp > 11) tmp = 11;
264    dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
265    tmp = SDRAM_RCD/ns;
266    if (tmp > 3) tmp = 3;
267    dmcr |= (tmp << EMC_DMCR_RCD_BIT);
268    tmp = SDRAM_TPC/ns;
269    if (tmp > 7) tmp = 7;
270    dmcr |= (tmp << EMC_DMCR_TPC_BIT);
271    tmp = SDRAM_TRWL/ns;
272    if (tmp > 3) tmp = 3;
273    dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
274    tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
275    if (tmp > 14) tmp = 14;
276    dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
277
278    /* SDRAM mode value */
279    sdmode = EMC_SDMR_BT_SEQ |
280         EMC_SDMR_OM_NORMAL |
281         EMC_SDMR_BL_4 |
282         cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
283
284    /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
285    REG_EMC_DMCR = dmcr;
286    REG8(EMC_SDMR0|sdmode) = 0;
287
288    /* Wait for precharge, > 200us */
289    tmp = (cpu_clk / 1000000) * 1000;
290    while (tmp--);
291
292    /* Stage 2. Enable auto-refresh */
293    REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
294
295    tmp = SDRAM_TREF/ns;
296    tmp = tmp/64 + 1;
297    if (tmp > 0xff) tmp = 0xff;
298    REG_EMC_RTCOR = tmp;
299    REG_EMC_RTCNT = 0;
300    REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
301
302    /* Wait for number of auto-refresh cycles */
303    tmp = (cpu_clk / 1000000) * 1000;
304    while (tmp--);
305
306     /* Stage 3. Mode Register Set */
307    REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
308    REG8(EMC_SDMR0|sdmode) = 0;
309
310        /* Set back to basic DMCR value */
311    REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
312
313    /* everything is ok now */
314}
315
316#ifndef CONFIG_NAND_SPL
317
318static void calc_clocks(void)
319{
320    DECLARE_GLOBAL_DATA_PTR;
321
322    unsigned int pllout;
323    unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
324
325    pllout = __cpm_get_pllout();
326
327    gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
328    gd->sys_clk = pllout / div[__cpm_get_hdiv()];
329    gd->per_clk = pllout / div[__cpm_get_pdiv()];
330    gd->mem_clk = pllout / div[__cpm_get_mdiv()];
331    gd->dev_clk = CONFIG_SYS_EXTAL;
332}
333
334static void rtc_init(void)
335{
336    unsigned long rtcsta;
337
338    while ( !__rtc_write_ready()) ;
339    __rtc_enable_alarm(); /* enable alarm */
340
341    while ( !__rtc_write_ready())
342        ;
343    REG_RTC_RGR = 0x00007fff; /* type value */
344
345    while ( !__rtc_write_ready())
346        ;
347    REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */
348
349    while ( !__rtc_write_ready())
350        ;
351    REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */
352#if 0
353    while ( !__rtc_write_ready())
354        ;
355    rtcsta = REG_RTC_HWRSR;
356    while ( !__rtc_write_ready())
357        ;
358    if (rtcsta & 0x33) {
359        if (rtcsta & 0x10) {
360            while ( !__rtc_write_ready())
361                ;
362            REG_RTC_RSR = 0x0;
363        }
364        while ( !__rtc_write_ready())
365            ;
366        REG_RTC_HWRSR = 0x0;
367    }
368#endif
369}
370
371/*
372 * jz4740 board init routine
373 */
374int jz_board_init(void)
375{
376    board_early_init(); /* init gpio, pll etc. */
377#ifndef CONFIG_NAND_U_BOOT
378    pll_init(); /* init PLL */
379    sdram_init(); /* init sdram memory */
380#endif
381    calc_clocks(); /* calc the clocks */
382    rtc_init(); /* init rtc on any reset: */
383    return 0;
384}
385
386/* U-Boot common routines */
387phys_size_t initdram(int board_type)
388{
389    u32 dmcr;
390    u32 rows, cols, dw, banks;
391    ulong size;
392
393    dmcr = REG_EMC_DMCR;
394    rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
395    cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
396    dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
397    banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
398
399    size = (1 << (rows + cols)) * dw * banks;
400
401    return size;
402}
403
404/*
405 * Timer routines
406 */
407
408#define TIMER_CHAN 0
409#define TIMER_FDATA 0xffff /* Timer full data value */
410#define TIMER_HZ CONFIG_SYS_HZ
411
412#define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */
413
414static ulong timestamp;
415static ulong lastdec;
416
417void reset_timer_masked (void);
418ulong get_timer_masked (void);
419void udelay_masked (unsigned long usec);
420
421/*
422 * timer without interrupts
423 */
424
425int timer_init(void)
426{
427    REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN;
428    REG_TCU_TCNT(TIMER_CHAN) = 0;
429    REG_TCU_TDHR(TIMER_CHAN) = 0;
430    REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA;
431
432    REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */
433    REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */
434    REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */
435
436    lastdec = 0;
437    timestamp = 0;
438
439    return 0;
440}
441
442void reset_timer(void)
443{
444    reset_timer_masked ();
445}
446
447ulong get_timer(ulong base)
448{
449    return get_timer_masked () - base;
450}
451
452void set_timer(ulong t)
453{
454    timestamp = t;
455}
456
457void udelay (unsigned long usec)
458{
459    ulong tmo,tmp;
460
461    /* normalize */
462    if (usec >= 1000) {
463        tmo = usec / 1000;
464        tmo *= TIMER_HZ;
465        tmo /= 1000;
466    }
467    else {
468        if (usec >= 1) {
469            tmo = usec * TIMER_HZ;
470            tmo /= (1000*1000);
471        }
472        else
473            tmo = 1;
474    }
475
476    /* check for rollover during this delay */
477    tmp = get_timer (0);
478    if ((tmp + tmo) < tmp )
479        reset_timer_masked(); /* timer would roll over */
480    else
481        tmo += tmp;
482
483    while (get_timer_masked () < tmo);
484}
485
486void reset_timer_masked (void)
487{
488    /* reset time */
489    lastdec = READ_TIMER;
490    timestamp = 0;
491}
492
493ulong get_timer_masked (void)
494{
495    ulong now = READ_TIMER;
496
497    if (lastdec <= now) {
498        /* normal mode */
499        timestamp += (now - lastdec);
500    } else {
501        /* we have an overflow ... */
502        timestamp += TIMER_FDATA + now - lastdec;
503    }
504    lastdec = now;
505
506    return timestamp;
507}
508
509void udelay_masked (unsigned long usec)
510{
511    ulong tmo;
512    ulong endtime;
513    signed long diff;
514
515    /* normalize */
516    if (usec >= 1000) {
517        tmo = usec / 1000;
518        tmo *= TIMER_HZ;
519        tmo /= 1000;
520    } else {
521        if (usec > 1) {
522            tmo = usec * TIMER_HZ;
523            tmo /= (1000*1000);
524        } else {
525            tmo = 1;
526        }
527    }
528
529    endtime = get_timer_masked () + tmo;
530
531    do {
532        ulong now = get_timer_masked ();
533        diff = endtime - now;
534    } while (diff >= 0);
535}
536
537/*
538 * This function is derived from PowerPC code (read timebase as long long).
539 * On MIPS it just returns the timer value.
540 */
541unsigned long long get_ticks(void)
542{
543    return get_timer(0);
544}
545
546/*
547 * This function is derived from PowerPC code (timebase clock frequency).
548 * On MIPS it returns the number of timer ticks per second.
549 */
550ulong get_tbclk (void)
551{
552    return TIMER_HZ;
553}
554
555#endif /* CONFIG_NAND_SPL */
556
557/* End of timer routine. */
558
559#endif
package/boot/uboot-xburst/files/cpu/mips/jz4740_nand.c
1/*
2 * Platform independend driver for JZ4740.
3 *
4 * Copyright (c) 2007 Ingenic Semiconductor Inc.
5 * Author: <jlwei@ingenic.cn>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 */
12#include <common.h>
13
14#if defined(CONFIG_CMD_NAND) && defined(CONFIG_JZ4740)
15
16#include <nand.h>
17#include <asm/jz4740.h>
18#include <asm/io.h>
19
20#define PAR_SIZE 9
21#define __nand_ecc_enable() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST )
22#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
23
24#define __nand_select_rs_ecc() (REG_EMC_NFECR |= EMC_NFECR_RS)
25
26#define __nand_rs_ecc_encoding() (REG_EMC_NFECR |= EMC_NFECR_RS_ENCODING)
27#define __nand_rs_ecc_decoding() (REG_EMC_NFECR |= EMC_NFECR_RS_DECODING)
28#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
29#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
30
31static void jz_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
32{
33    struct nand_chip *this = mtd->priv;
34    unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
35
36    if (ctrl & NAND_CTRL_CHANGE) {
37        /* Change this to use I/O accessors. */
38        if (ctrl & NAND_NCE)
39            REG_EMC_NFCSR |= EMC_NFCSR_NFCE1;
40        else
41            REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
42    }
43
44    if (cmd == NAND_CMD_NONE)
45        return;
46
47    if (ctrl & NAND_CLE)
48        nandaddr |= 0x00008000;
49    else /* must be ALE */
50        nandaddr |= 0x00010000;
51
52    writeb(cmd, (uint8_t *)nandaddr);
53}
54
55static int jz_device_ready(struct mtd_info *mtd)
56{
57    int ready;
58    udelay(20); /* FIXME: add 20us delay */
59    ready = (REG_GPIO_PXPIN(2) & 0x40000000) ? 1 : 0;
60    return ready;
61}
62
63/*
64 * EMC setup
65 */
66static void jz_device_setup(void)
67{
68    /* Set NFE bit */
69    REG_EMC_NFCSR |= EMC_NFCSR_NFE1;
70    REG_EMC_SMCR1 = 0x094c4400;
71    /* REG_EMC_SMCR3 = 0x04444400; */
72}
73
74void board_nand_select_device(struct nand_chip *nand, int chip)
75{
76    /*
77     * Don't use "chip" to address the NAND device,
78     * generate the cs from the address where it is encoded.
79     */
80}
81
82static int jzsoc_nand_calculate_rs_ecc(struct mtd_info* mtd, const u_char* dat,
83                u_char* ecc_code)
84{
85    volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
86    short i;
87
88    __nand_ecc_encode_sync()
89    __nand_ecc_disable();
90
91    for(i = 0; i < PAR_SIZE; i++)
92        ecc_code[i] = *paraddr++;
93
94    return 0;
95}
96
97static void jzsoc_nand_enable_rs_hwecc(struct mtd_info* mtd, int mode)
98{
99     __nand_ecc_enable();
100    __nand_select_rs_ecc();
101
102    REG_EMC_NFINTS = 0x0;
103    if (NAND_ECC_READ == mode){
104        __nand_rs_ecc_decoding();
105    }
106    if (NAND_ECC_WRITE == mode){
107        __nand_rs_ecc_encoding();
108    }
109}
110
111/* Correct 1~9-bit errors in 512-bytes data */
112static void jzsoc_rs_correct(unsigned char *dat, int idx, int mask)
113{
114    int i;
115
116    idx--;
117
118    i = idx + (idx >> 3);
119    if (i >= 512)
120        return;
121
122    mask <<= (idx & 0x7);
123
124    dat[i] ^= mask & 0xff;
125    if (i < 511)
126        dat[i+1] ^= (mask >> 8) & 0xff;
127}
128
129static int jzsoc_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
130                 u_char *read_ecc, u_char *calc_ecc)
131{
132    volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
133    short k;
134    u32 stat;
135    /* Set PAR values */
136
137    for (k = 0; k < PAR_SIZE; k++) {
138        *paraddr++ = read_ecc[k];
139    }
140
141    /* Set PRDY */
142    REG_EMC_NFECR |= EMC_NFECR_PRDY;
143
144    /* Wait for completion */
145    __nand_ecc_decode_sync();
146    __nand_ecc_disable();
147
148    /* Check decoding */
149    stat = REG_EMC_NFINTS;
150    if (stat & EMC_NFINTS_ERR) {
151        if (stat & EMC_NFINTS_UNCOR) {
152            printk("Uncorrectable error occurred\n");
153            return -1;
154        }
155        else {
156            u32 errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
157            switch (errcnt) {
158            case 4:
159                jzsoc_rs_correct(dat, (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
160            case 3:
161                jzsoc_rs_correct(dat, (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
162            case 2:
163                jzsoc_rs_correct(dat, (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
164            case 1:
165                jzsoc_rs_correct(dat, (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
166                return 0;
167            default:
168                break;
169               }
170        }
171    }
172    /* no error need to be correct */
173    return 0;
174}
175
176/*
177 * Main initialization routine
178 */
179int board_nand_init(struct nand_chip *nand)
180{
181    jz_device_setup();
182
183    nand->cmd_ctrl = jz_hwcontrol;
184    nand->dev_ready = jz_device_ready;
185
186    /* FIXME: should use NAND_ECC_SOFT */
187    nand->ecc.hwctl = jzsoc_nand_enable_rs_hwecc;
188    nand->ecc.correct = jzsoc_nand_rs_correct_data;
189    nand->ecc.calculate = jzsoc_nand_calculate_rs_ecc;
190    nand->ecc.mode = NAND_ECC_HW;
191    nand->ecc.size = 512;
192    nand->ecc.bytes = 9;
193
194    /* 20 us command delay time */
195    nand->chip_delay = 20;
196
197    return 0;
198}
199#endif /* (CONFIG_SYS_CMD_NAND) */
package/boot/uboot-xburst/files/cpu/mips/jz_lcd.c
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22/*
23 * Fallowing macro may be used:
24 * CONFIG_LCD : LCD support
25 * LCD_BPP : Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8
26 * CONFIG_LCD_LOGO : show logo
27 */
28
29#include <config.h>
30#include <common.h>
31#include <lcd.h>
32
33#include <asm/io.h> /* virt_to_phys() */
34
35#if defined(CONFIG_LCD) && !defined(CONFIG_SLCD)
36
37#if defined(CONFIG_JZ4740)
38#include <asm/jz4740.h>
39#endif
40
41#include "jz_lcd.h"
42
43
44struct jzfb_info {
45    unsigned int cfg; /* panel mode and pin usage etc. */
46    unsigned int w;
47    unsigned int h;
48    unsigned int bpp; /* bit per pixel */
49    unsigned int fclk; /* frame clk */
50    unsigned int hsw; /* hsync width, in pclk */
51    unsigned int vsw; /* vsync width, in line count */
52    unsigned int elw; /* end of line, in pclk */
53    unsigned int blw; /* begin of line, in pclk */
54    unsigned int efw; /* end of frame, in line count */
55    unsigned int bfw; /* begin of frame, in line count */
56};
57
58static struct jzfb_info jzfb = {
59   #if defined(CONFIG_NANONOTE)
60    MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
61    320, 240, 32, 70, 1, 1, 273, 140, 1, 20
62   #endif
63
64};
65
66/************************************************************************/
67
68vidinfo_t panel_info = {
69#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01)
70    320, 240, LCD_BPP,
71#endif
72};
73
74/*----------------------------------------------------------------------*/
75
76int lcd_line_length;
77
78int lcd_color_fg;
79int lcd_color_bg;
80
81/*
82 * Frame buffer memory information
83 */
84void *lcd_base; /* Start of framebuffer memory */
85void *lcd_console_address; /* Start of console buffer */
86
87short console_col;
88short console_row;
89
90/*----------------------------------------------------------------------*/
91
92void lcd_ctrl_init (void *lcdbase);
93
94void lcd_enable (void);
95void lcd_disable (void);
96
97/*----------------------------------------------------------------------*/
98
99static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid);
100static void jz_lcd_desc_init(vidinfo_t *vid);
101static int jz_lcd_hw_init( vidinfo_t *vid );
102extern int flush_cache_all(void);
103
104#if LCD_BPP == LCD_COLOR8
105void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue);
106#endif
107#if LCD_BPP == LCD_MONOCHROME
108void lcd_initcolregs (void);
109#endif
110
111/*-----------------------------------------------------------------------*/
112
113void lcd_ctrl_init (void *lcdbase)
114{
115    __lcd_display_pin_init();
116
117    jz_lcd_init_mem(lcdbase, &panel_info);
118    jz_lcd_desc_init(&panel_info);
119    jz_lcd_hw_init(&panel_info);
120
121    __lcd_display_on() ;
122}
123
124/*----------------------------------------------------------------------*/
125#if LCD_BPP == LCD_COLOR8
126void
127lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
128{
129}
130#endif
131/*----------------------------------------------------------------------*/
132
133#if LCD_BPP == LCD_MONOCHROME
134static
135void lcd_initcolregs (void)
136{
137}
138#endif
139
140/*
141 * Before enabled lcd controller, lcd registers should be configured correctly.
142 */
143
144void lcd_enable (void)
145{
146    REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
147    REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
148}
149
150void lcd_disable (void)
151{
152    REG_LCD_CTRL |= (1<<4); /* LCDCTRL.DIS, regular disable */
153    /* REG_LCD_CTRL |= (1<<3); */ /* LCDCTRL.DIS, quikly disable */
154}
155
156static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
157{
158    u_long palette_mem_size;
159    struct jz_fb_info *fbi = &vid->jz_fb;
160    int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
161
162    fbi->screen = (u_long)lcdbase;
163    fbi->palette_size = 256;
164    palette_mem_size = fbi->palette_size * sizeof(u16);
165
166    debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
167    /* locate palette and descs at end of page following fb */
168    fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
169
170    return 0;
171}
172
173static void jz_lcd_desc_init(vidinfo_t *vid)
174{
175    struct jz_fb_info * fbi;
176    fbi = &vid->jz_fb;
177    fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
178    fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
179    fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
180
181    #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
182
183    /* populate descriptors */
184    fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
185    fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
186    fbi->dmadesc_fblow->fidr = 0;
187    fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
188
189    fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
190
191    fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
192    fbi->dmadesc_fbhigh->fidr = 0;
193    fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
194
195    fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
196    fbi->dmadesc_palette->fidr = 0;
197    fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
198
199    if( NBITS(vid->vl_bpix) < 12)
200    {
201        /* assume any mode with <12 bpp is palette driven */
202        fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
203        fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
204        /* flips back and forth between pal and fbhigh */
205        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
206    } else {
207        /* palette shouldn't be loaded in true-color mode */
208        fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
209        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
210    }
211
212    flush_cache_all();
213}
214
215static int jz_lcd_hw_init(vidinfo_t *vid)
216{
217    struct jz_fb_info *fbi = &vid->jz_fb;
218    unsigned int val = 0;
219    unsigned int pclk;
220    unsigned int stnH;
221#if defined(CONFIG_MIPS_JZ4740)
222    int pll_div;
223#endif
224
225    /* Setting Control register */
226    switch (jzfb.bpp) {
227    case 1:
228        val |= LCD_CTRL_BPP_1;
229        break;
230    case 2:
231        val |= LCD_CTRL_BPP_2;
232        break;
233    case 4:
234        val |= LCD_CTRL_BPP_4;
235        break;
236    case 8:
237        val |= LCD_CTRL_BPP_8;
238        break;
239    case 15:
240        val |= LCD_CTRL_RGB555;
241    case 16:
242        val |= LCD_CTRL_BPP_16;
243        break;
244#if defined(CONFIG_MIPS_JZ4740)
245    case 17 ... 32:
246        val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
247        break;
248#endif
249    default:
250        printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
251        val |= LCD_CTRL_BPP_16;
252        break;
253    }
254
255    switch (jzfb.cfg & MODE_MASK) {
256    case MODE_STN_MONO_DUAL:
257    case MODE_STN_COLOR_DUAL:
258    case MODE_STN_MONO_SINGLE:
259    case MODE_STN_COLOR_SINGLE:
260        switch (jzfb.bpp) {
261        case 1:
262            /* val |= LCD_CTRL_PEDN; */
263        case 2:
264            val |= LCD_CTRL_FRC_2;
265            break;
266        case 4:
267            val |= LCD_CTRL_FRC_4;
268            break;
269        case 8:
270        default:
271            val |= LCD_CTRL_FRC_16;
272            break;
273        }
274        break;
275    }
276
277    val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
278    val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
279
280    switch (jzfb.cfg & MODE_MASK) {
281    case MODE_STN_MONO_DUAL:
282    case MODE_STN_COLOR_DUAL:
283    case MODE_STN_MONO_SINGLE:
284    case MODE_STN_COLOR_SINGLE:
285        switch (jzfb.cfg & STN_DAT_PINMASK) {
286#define align2(n) (n)=((((n)+1)>>1)<<1)
287#define align4(n) (n)=((((n)+3)>>2)<<2)
288#define align8(n) (n)=((((n)+7)>>3)<<3)
289        case STN_DAT_PIN1:
290            /* Do not adjust the hori-param value. */
291            break;
292        case STN_DAT_PIN2:
293            align2(jzfb.hsw);
294            align2(jzfb.elw);
295            align2(jzfb.blw);
296            break;
297        case STN_DAT_PIN4:
298            align4(jzfb.hsw);
299            align4(jzfb.elw);
300            align4(jzfb.blw);
301            break;
302        case STN_DAT_PIN8:
303            align8(jzfb.hsw);
304            align8(jzfb.elw);
305            align8(jzfb.blw);
306            break;
307        }
308        break;
309    }
310
311    REG_LCD_CTRL = val;
312
313    switch (jzfb.cfg & MODE_MASK) {
314    case MODE_STN_MONO_DUAL:
315    case MODE_STN_COLOR_DUAL:
316    case MODE_STN_MONO_SINGLE:
317    case MODE_STN_COLOR_SINGLE:
318        if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
319            ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
320            stnH = jzfb.h >> 1;
321        else
322            stnH = jzfb.h;
323
324        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
325        REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
326
327        /* Screen setting */
328        REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
329        REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
330        REG_LCD_DAV = (0 << 16) | (stnH);
331
332        /* AC BIAs signal */
333        REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
334
335        break;
336
337    case MODE_TFT_GEN:
338    case MODE_TFT_SHARP:
339    case MODE_TFT_CASIO:
340    case MODE_TFT_SAMSUNG:
341    case MODE_8BIT_SERIAL_TFT:
342    case MODE_TFT_18BIT:
343        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
344        REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
345#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)
346        REG_LCD_DAV = (0 << 16) | ( jzfb.h );
347#else
348        REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
349#endif /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/
350        REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
351        REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
352            | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
353        break;
354    }
355
356    switch (jzfb.cfg & MODE_MASK) {
357    case MODE_TFT_SAMSUNG:
358    {
359        unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
360        unsigned int rev_s, rev_e, inv_s, inv_e;
361
362        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
363            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
364
365        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
366        tp_s = jzfb.blw + jzfb.w + 1;
367        tp_e = tp_s + 1;
368        /* ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100); */
369        ckv_s = tp_s - pclk/(1000000000/4100);
370        ckv_e = tp_s + total;
371        rev_s = tp_s - 11; /* -11.5 clk */
372        rev_e = rev_s + total;
373        inv_s = tp_s;
374        inv_e = inv_s + total;
375        REG_LCD_CLS = (tp_s << 16) | tp_e;
376        REG_LCD_PS = (ckv_s << 16) | ckv_e;
377        REG_LCD_SPL = (rev_s << 16) | rev_e;
378        REG_LCD_REV = (inv_s << 16) | inv_e;
379        jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
380        break;
381    }
382    case MODE_TFT_SHARP:
383    {
384        unsigned int total, cls_s, cls_e, ps_s, ps_e;
385        unsigned int spl_s, spl_e, rev_s, rev_e;
386        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
387#if !defined(CONFIG_JZLCD_INNOLUX_AT080TN42)
388        spl_s = 1;
389        spl_e = spl_s + 1;
390        cls_s = 0;
391        cls_e = total - 60; /* > 4us (pclk = 80ns) */
392        ps_s = cls_s;
393        ps_e = cls_e;
394        rev_s = total - 40; /* > 3us (pclk = 80ns) */
395        rev_e = rev_s + total;
396        jzfb.cfg |= STFT_PSHI;
397#else /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/
398        spl_s = total - 5; /* LD */
399        spl_e = total -3;
400        cls_s = 32; /* CKV */
401        cls_e = 145;
402        ps_s = 0; /* OEV */
403        ps_e = 45;
404        rev_s = 0; /* POL */
405        rev_e = 0;
406#endif /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/
407        REG_LCD_SPL = (spl_s << 16) | spl_e;
408        REG_LCD_CLS = (cls_s << 16) | cls_e;
409        REG_LCD_PS = (ps_s << 16) | ps_e;
410        REG_LCD_REV = (rev_s << 16) | rev_e;
411        break;
412    }
413    case MODE_TFT_CASIO:
414        break;
415    }
416
417    /* Configure the LCD panel */
418    REG_LCD_CFG = jzfb.cfg;
419
420    /* Timing setting */
421    __cpm_stop_lcd();
422
423    val = jzfb.fclk; /* frame clk */
424    if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
425        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
426            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
427    }
428    else {
429        /* serial mode: Hsync period = 3*Width_Pixel */
430        pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
431            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
432    }
433
434    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
435        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
436        pclk = (pclk * 3);
437
438    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
439        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
440        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
441        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
442        pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
443
444    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
445        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
446        pclk >>= 1;
447
448    pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source,0:pllout/2 1: pllout */
449    pll_div = pll_div ? 1 : 2 ;
450    val = ( __cpm_get_pllout()/pll_div ) / pclk;
451    val--;
452    if ( val > 0x1ff ) {
453        printf("CPM_LPCDR too large, set it to 0x1ff\n");
454        val = 0x1ff;
455    }
456    __cpm_set_pixdiv(val);
457
458    val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
459    if ( val > 150000000 ) {
460        printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
461        printf("Change LCDClock to 150MHz\n");
462        val = 150000000;
463    }
464    val = ( __cpm_get_pllout()/pll_div ) / val;
465    val--;
466    if ( val > 0x1f ) {
467        printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
468        val = 0x1f;
469    }
470    __cpm_set_ldiv( val );
471    REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
472
473    __cpm_start_lcd();
474    udelay(1000);
475
476    REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
477
478    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
479        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
480        REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
481
482    return 0;
483}
484
package/boot/uboot-xburst/files/cpu/mips/jz_lcd.h
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#ifndef __JZLCD_H__
23#define __JZLCD_H__
24
25#include <asm/io.h>
26/*
27 * change u-boot macro to celinux macro
28 */
29/* Chip type */
30#if defined(CONFIG_JZ4740)
31#define CONFIG_MIPS_JZ4740 1
32#endif
33
34/* board type */
35#if defined(CONFIG_NANONOTE)
36#define CONFIG_MIPS_JZ4740_PI 1
37#endif
38
39#define mdelay(n) udelay((n)*1000)
40
41/*
42 * change u-boot macro to celinux macro
43 */
44
45#define NR_PALETTE 256
46
47struct lcd_desc{
48    unsigned int next_desc; /* LCDDAx */
49    unsigned int databuf; /* LCDSAx */
50    unsigned int frame_id; /* LCDFIDx */
51    unsigned int cmd; /* LCDCMDx */
52};
53
54#define MODE_MASK 0x0f
55#define MODE_TFT_GEN 0x00
56#define MODE_TFT_SHARP 0x01
57#define MODE_TFT_CASIO 0x02
58#define MODE_TFT_SAMSUNG 0x03
59#define MODE_CCIR656_NONINT 0x04
60#define MODE_CCIR656_INT 0x05
61#define MODE_STN_COLOR_SINGLE 0x08
62#define MODE_STN_MONO_SINGLE 0x09
63#define MODE_STN_COLOR_DUAL 0x0a
64#define MODE_STN_MONO_DUAL 0x0b
65#define MODE_8BIT_SERIAL_TFT 0x0c
66
67#define MODE_TFT_18BIT (1<<7)
68
69#define STN_DAT_PIN1 (0x00 << 4)
70#define STN_DAT_PIN2 (0x01 << 4)
71#define STN_DAT_PIN4 (0x02 << 4)
72#define STN_DAT_PIN8 (0x03 << 4)
73#define STN_DAT_PINMASK STN_DAT_PIN8
74
75#define STFT_PSHI (1 << 15)
76#define STFT_CLSHI (1 << 14)
77#define STFT_SPLHI (1 << 13)
78#define STFT_REVHI (1 << 12)
79
80#define SYNC_MASTER (0 << 16)
81#define SYNC_SLAVE (1 << 16)
82
83#define DE_P (0 << 9)
84#define DE_N (1 << 9)
85
86#define PCLK_P (0 << 10)
87#define PCLK_N (1 << 10)
88
89#define HSYNC_P (0 << 11)
90#define HSYNC_N (1 << 11)
91
92#define VSYNC_P (0 << 8)
93#define VSYNC_N (1 << 8)
94
95#define DATA_NORMAL (0 << 17)
96#define DATA_INVERSE (1 << 17)
97
98
99/* Jz LCDFB supported I/O controls. */
100#define FBIOSETBACKLIGHT 0x4688
101#define FBIODISPON 0x4689
102#define FBIODISPOFF 0x468a
103#define FBIORESET 0x468b
104#define FBIOPRINT_REG 0x468c
105
106/*
107 * LCD panel specific definition
108 */
109
110#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) || defined(CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL)
111
112#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) /* board pmp */
113#define MODE 0xcd /* 24bit parellel RGB */
114#endif
115#if defined(CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL)
116#define MODE 0xc9 /* 8bit serial RGB */
117#endif
118
119#if defined(CONFIG_MIPS_JZ4740_PI) /* board pavo */
120    #define SPEN (32*2+21) /*LCD_SPL */
121    #define SPCK (32*2+23) /*LCD_CLS */
122    #define SPDA (32*2+22) /*LCD_D12 */
123    #define LCD_RET (32*3+27)
124#else
125#error "cpu/misp/Jzlcd.h, please define SPI pins on your board."
126#endif
127
128    #define __spi_write_reg1(reg, val) \
129    do { \
130        unsigned char no;\
131        unsigned short value;\
132        unsigned char a=0;\
133        unsigned char b=0;\
134        a=reg;\
135        b=val;\
136        __gpio_set_pin(SPEN);\
137        __gpio_set_pin(SPCK);\
138        __gpio_clear_pin(SPDA);\
139        __gpio_clear_pin(SPEN);\
140        udelay(25);\
141        value=((a<<8)|(b&0xFF));\
142        for(no=0;no<16;no++)\
143        {\
144            __gpio_clear_pin(SPCK);\
145            if((value&0x8000)==0x8000)\
146            __gpio_set_pin(SPDA);\
147            else\
148            __gpio_clear_pin(SPDA);\
149            udelay(25);\
150            __gpio_set_pin(SPCK);\
151            value=(value<<1); \
152            udelay(25);\
153         }\
154        __gpio_set_pin(SPEN);\
155        udelay(100);\
156    } while (0)
157
158    #define __spi_write_reg(reg, val) \
159    do {\
160        __spi_write_reg1((reg<<2|2), val);\
161        udelay(100); \
162    }while(0)
163
164
165    #define __lcd_special_pin_init() \
166    do { \
167        __gpio_as_output(SPEN); /* use SPDA */\
168        __gpio_as_output(SPCK); /* use SPCK */\
169        __gpio_as_output(SPDA); /* use SPDA */\
170        __gpio_as_output(LCD_RET);\
171    } while (0)
172
173#if defined(CONFIG_NANONOTE)
174    #define __lcd_special_on() \
175        do { \
176        udelay(50);\
177        __spi_write_reg1(0x05, 0x16); \
178        __spi_write_reg1(0x04, 0x0b); \
179        __spi_write_reg1(0x07, 0x8d); \
180        __spi_write_reg1(0x01, 0x95); \
181        __spi_write_reg1(0x08, 0xc0); \
182        __spi_write_reg1(0x03, 0x40); \
183        __spi_write_reg1(0x06, 0x15); \
184        __spi_write_reg1(0x05, 0xd7); \
185        } while (0) /* reg 0x0a is control the display direction:DB0->horizontal level DB1->vertical level */
186
187    #define __lcd_special_off() \
188              do { \
189                  __spi_write_reg1(0x05, 0x5e); \
190              } while (0)
191#endif /* CONFIG_NANONOTE */
192#endif /* CONFIG_JZLCD_FOXCONN_PT035TN01 or CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL */
193
194#ifndef __lcd_special_pin_init
195#define __lcd_special_pin_init()
196#endif
197#ifndef __lcd_special_on
198#define __lcd_special_on()
199#endif
200#ifndef __lcd_special_off
201#define __lcd_special_off()
202#endif
203
204
205/*
206 * Platform specific definition
207 */
208
209#if defined(CONFIG_MIPS_JZ4740_PI)
210
211    /* 100 level: 0,1,...,100 */
212    #define __lcd_set_backlight_level(n)\
213    do { \
214    __gpio_as_output(32*3+27); \
215    __gpio_set_pin(32*3+27); \
216    } while (0)
217
218    #define __lcd_close_backlight() \
219    do { \
220    __gpio_as_output(GPIO_PWM); \
221    __gpio_clear_pin(GPIO_PWM); \
222    } while (0)
223
224    #define __lcd_display_pin_init() \
225    do { \
226        __gpio_as_output(GPIO_DISP_OFF_N); \
227        __cpm_start_tcu(); \
228        __lcd_special_pin_init(); \
229    } while (0)
230    /* __lcd_set_backlight_level(100); \*/
231    #define __lcd_display_on() \
232    do { \
233        __gpio_set_pin(GPIO_DISP_OFF_N); \
234        __lcd_special_on(); \
235    } while (0)
236
237    #define __lcd_display_off() \
238    do { \
239        __lcd_special_off(); \
240        __gpio_clear_pin(GPIO_DISP_OFF_N); \
241    } while (0)
242
243#endif /* CONFIG_MIPS_JZ4740_PI) */
244
245/*****************************************************************************
246 * LCD display pin dummy macros
247 *****************************************************************************/
248#ifndef __lcd_display_pin_init
249#define __lcd_display_pin_init()
250#endif
251#ifndef __lcd_display_on
252#define __lcd_display_on()
253#endif
254#ifndef __lcd_display_off
255#define __lcd_display_off()
256#endif
257#ifndef __lcd_set_backlight_level
258#define __lcd_set_backlight_level(n)
259#endif
260
package/boot/uboot-xburst/files/cpu/mips/jz_mmc.c
1/*
2 * (C) Copyright 2003
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <config.h>
25#include <common.h>
26#include <part.h>
27
28#if defined CONFIG_JZ4740
29#include <asm-mips/jz4740.h>
30
31#include "jz_mmc.h"
32
33#define CFG_MMC_BASE 0x80600000
34static int sd2_0 = 0;
35
36/*
37 * GPIO definition
38 */
39#if defined(CONFIG_SAKC)
40
41#define __msc_init_io() \
42do { \
43    __gpio_as_input(GPIO_SD_CD_N); \
44} while (0)
45
46#else
47#define __msc_init_io() \
48do { \
49    __gpio_as_output(GPIO_SD_VCC_EN_N); \
50    __gpio_as_input(GPIO_SD_CD_N); \
51} while (0)
52
53#define __msc_enable_power() \
54do { \
55    __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
56} while (0)
57
58#define __msc_disable_power() \
59do { \
60    __gpio_set_pin(GPIO_SD_VCC_EN_N); \
61} while (0)
62
63#endif /* CONFIG_SAKE */
64
65#define __msc_card_detected() \
66({ \
67    int detected = 1; \
68    __gpio_as_input(GPIO_SD_CD_N); \
69    __gpio_disable_pull(GPIO_SD_CD_N); \
70    if (!__gpio_get_pin(GPIO_SD_CD_N)) \
71        detected = 0; \
72    detected; \
73})
74
75/*
76 * Local functions
77 */
78
79#ifdef CONFIG_MMC
80extern int
81fat_register_device(block_dev_desc_t *dev_desc, int part_no);
82
83static block_dev_desc_t mmc_dev;
84
85block_dev_desc_t * mmc_get_dev(int dev)
86{
87    return ((block_dev_desc_t *)&mmc_dev);
88}
89
90/*
91 * FIXME needs to read cid and csd info to determine block size
92 * and other parameters
93 */
94static uchar mmc_buf[MMC_BLOCK_SIZE];
95static int mmc_ready = 0;
96static mmc_csd_t mmc_csd;
97static int use_4bit; /* Use 4-bit data bus */
98/*
99 * MMC Events
100 */
101#define MMC_EVENT_NONE 0x00 /* No events */
102#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
103#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
104#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
105
106
107#define MMC_IRQ_MASK() \
108do { \
109          REG_MSC_IMASK = 0xffff; \
110          REG_MSC_IREG = 0xffff; \
111} while (0)
112
113/* Stop the MMC clock and wait while it happens */
114static inline int jz_mmc_stop_clock(void)
115{
116    int timeout = 1000;
117
118    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
119
120    while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
121        timeout--;
122        if (timeout == 0) {
123            return MMC_ERROR_TIMEOUT;
124        }
125        udelay(1);
126    }
127        return MMC_NO_ERROR;
128}
129
130/* Start the MMC clock and operation */
131static inline int jz_mmc_start_clock(void)
132{
133    REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
134    return MMC_NO_ERROR;
135}
136
137static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
138{
139    u32 clkrt;
140    u32 clk_src = is_sd ? 24000000: 16000000;
141
142    clkrt = 0;
143      while (rate < clk_src)
144        {
145              clkrt ++;
146              clk_src >>= 1;
147        }
148    return clkrt;
149}
150
151/* Set the MMC clock frequency */
152void jz_mmc_set_clock(int sd, u32 rate)
153{
154    jz_mmc_stop_clock();
155
156    /* Select clock source of MSC */
157    __cpm_select_msc_clk(sd);
158
159    /* Set clock dividor of MSC */
160    REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
161}
162
163static int jz_mmc_check_status(struct mmc_request *request)
164{
165    u32 status = REG_MSC_STAT;
166
167    /* Checking for response or data timeout */
168    if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
169        printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
170        return MMC_ERROR_TIMEOUT;
171    }
172
173    /* Checking for CRC error */
174    if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
175        printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
176        return MMC_ERROR_CRC;
177    }
178
179    return MMC_NO_ERROR;
180}
181
182/* Obtain response to the command and store it to response buffer */
183static void jz_mmc_get_response(struct mmc_request *request)
184{
185    int i;
186    u8 *buf;
187    u32 data;
188
189    DEBUG(3, "fetch response for request %d, cmd %d\n", request->rtype, request->cmd);
190
191    buf = request->response;
192    request->result = MMC_NO_ERROR;
193
194    switch (request->rtype) {
195    case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
196    case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
197    {
198        data = REG_MSC_RES;
199        buf[0] = (data >> 8) & 0xff;
200        buf[1] = data & 0xff;
201        data = REG_MSC_RES;
202        buf[2] = (data >> 8) & 0xff;
203        buf[3] = data & 0xff;
204        data = REG_MSC_RES;
205        buf[4] = data & 0xff;
206
207        DEBUG(3, "request %d, response [%02x %02x %02x %02x %02x]\n",
208              request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
209        break;
210    }
211    case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
212    {
213        for (i = 0; i < 16; i += 2) {
214            data = REG_MSC_RES;
215            buf[i] = (data >> 8) & 0xff;
216            buf[i+1] = data & 0xff;
217        }
218        DEBUG(3, "request %d, response [", request->rtype);
219#if CONFIG_MMC_DEBUG_VERBOSE > 2
220        if (g_mmc_debug >= 3) {
221            int n;
222            for (n = 0; n < 17; n++)
223                printk("%02x ", buf[n]);
224            printk("]\n");
225        }
226#endif
227        break;
228    }
229    case RESPONSE_NONE:
230        DEBUG(3, "No response\n");
231        break;
232
233    default:
234        DEBUG(3, "unhandled response type for request %d\n", request->rtype);
235        break;
236    }
237}
238
239static int jz_mmc_receive_data(struct mmc_request *req)
240{
241    u32 stat, timeout, data, cnt;
242    u8 *buf = req->buffer;
243    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
244
245    timeout = 0x3ffffff;
246
247    while (timeout) {
248        timeout--;
249        stat = REG_MSC_STAT;
250
251        if (stat & MSC_STAT_TIME_OUT_READ)
252            return MMC_ERROR_TIMEOUT;
253        else if (stat & MSC_STAT_CRC_READ_ERROR)
254            return MMC_ERROR_CRC;
255        else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
256             || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
257            /* Ready to read data */
258            break;
259        }
260        udelay(1);
261    }
262    if (!timeout)
263        return MMC_ERROR_TIMEOUT;
264
265    /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
266    cnt = wblocklen;
267    while (cnt) {
268        data = REG_MSC_RXFIFO;
269        {
270            *buf++ = (u8)(data >> 0);
271            *buf++ = (u8)(data >> 8);
272            *buf++ = (u8)(data >> 16);
273            *buf++ = (u8)(data >> 24);
274        }
275        cnt --;
276        while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
277            ;
278    }
279    return MMC_NO_ERROR;
280}
281
282static int jz_mmc_transmit_data(struct mmc_request *req)
283{
284#if 0
285    u32 nob = req->nob;
286    u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
287    u8 *buf = req->buffer;
288    u32 *wbuf = (u32 *)buf;
289    u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
290    u32 stat, timeout, data, cnt;
291
292    for (nob; nob >= 1; nob--) {
293        timeout = 0x3FFFFFF;
294
295        while (timeout) {
296            timeout--;
297            stat = REG_MSC_STAT;
298
299            if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
300                return MMC_ERROR_CRC;
301            else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
302                /* Ready to write data */
303                break;
304            }
305
306            udelay(1);
307        }
308
309        if (!timeout)
310            return MMC_ERROR_TIMEOUT;
311
312        /* Write data to TXFIFO */
313        cnt = wblocklen;
314        while (cnt) {
315            while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
316                ;
317
318            if (waligned) {
319                REG_MSC_TXFIFO = *wbuf++;
320            }
321            else {
322                data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
323                REG_MSC_TXFIFO = data;
324            }
325
326            cnt--;
327        }
328    }
329#endif
330    return MMC_NO_ERROR;
331}
332
333
334/*
335 * Name: int jz_mmc_exec_cmd()
336 * Function: send command to the card, and get a response
337 * Input: struct mmc_request *req : MMC/SD request
338 * Output: 0: right >0: error code
339 */
340int jz_mmc_exec_cmd(struct mmc_request *request)
341{
342    u32 cmdat = 0, events = 0;
343    int retval, timeout = 0x3fffff;
344
345    /* Indicate we have no result yet */
346    request->result = MMC_NO_RESPONSE;
347    if (request->cmd == MMC_CIM_RESET) {
348        /* On reset, 1-bit bus width */
349        use_4bit = 0;
350
351        /* Reset MMC/SD controller */
352        __msc_reset();
353
354        /* On reset, drop MMC clock down */
355        jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
356
357        /* On reset, stop MMC clock */
358        jz_mmc_stop_clock();
359    }
360    if (request->cmd == MMC_SEND_OP_COND) {
361        DEBUG(3, "Have an MMC card\n");
362        /* always use 1bit for MMC */
363        use_4bit = 0;
364    }
365    if (request->cmd == SET_BUS_WIDTH) {
366        if (request->arg == 0x2) {
367            printf("Use 4-bit bus width\n");
368            use_4bit = 1;
369        }
370        else {
371            printf("Use 1-bit bus width\n");
372            use_4bit = 0;
373        }
374    }
375
376    /* stop clock */
377    jz_mmc_stop_clock();
378
379    /* mask all interrupts */
380    REG_MSC_IMASK = 0xffff;
381
382    /* clear status */
383    REG_MSC_IREG = 0xffff;
384
385    /* use 4-bit bus width when possible */
386    if (use_4bit)
387        cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
388
389        /* Set command type and events */
390    switch (request->cmd) {
391    /* MMC core extra command */
392    case MMC_CIM_RESET:
393        cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
394        break;
395
396    /* bc - broadcast - no response */
397    case MMC_GO_IDLE_STATE:
398    case MMC_SET_DSR:
399        break;
400
401    /* bcr - broadcast with response */
402    case MMC_SEND_OP_COND:
403    case MMC_ALL_SEND_CID:
404    case MMC_GO_IRQ_STATE:
405        break;
406
407    /* adtc - addressed with data transfer */
408    case MMC_READ_DAT_UNTIL_STOP:
409    case MMC_READ_SINGLE_BLOCK:
410    case MMC_READ_MULTIPLE_BLOCK:
411    case SEND_SCR:
412        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
413        events = MMC_EVENT_RX_DATA_DONE;
414        break;
415
416    case MMC_WRITE_DAT_UNTIL_STOP:
417    case MMC_WRITE_BLOCK:
418    case MMC_WRITE_MULTIPLE_BLOCK:
419    case MMC_PROGRAM_CID:
420    case MMC_PROGRAM_CSD:
421    case MMC_SEND_WRITE_PROT:
422    case MMC_GEN_CMD:
423    case MMC_LOCK_UNLOCK:
424        cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
425        events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
426
427        break;
428
429    case MMC_STOP_TRANSMISSION:
430        events = MMC_EVENT_PROG_DONE;
431        break;
432
433    /* ac - no data transfer */
434    default:
435        break;
436    }
437
438    /* Set response type */
439    switch (request->rtype) {
440    case RESPONSE_NONE:
441        break;
442
443    case RESPONSE_R1B:
444        cmdat |= MSC_CMDAT_BUSY;
445        /*FALLTHRU*/
446    case RESPONSE_R1:
447        cmdat |= MSC_CMDAT_RESPONSE_R1;
448        break;
449    case RESPONSE_R2_CID:
450    case RESPONSE_R2_CSD:
451        cmdat |= MSC_CMDAT_RESPONSE_R2;
452        break;
453    case RESPONSE_R3:
454        cmdat |= MSC_CMDAT_RESPONSE_R3;
455        break;
456    case RESPONSE_R4:
457        cmdat |= MSC_CMDAT_RESPONSE_R4;
458        break;
459    case RESPONSE_R5:
460        cmdat |= MSC_CMDAT_RESPONSE_R5;
461        break;
462    case RESPONSE_R6:
463        cmdat |= MSC_CMDAT_RESPONSE_R6;
464        break;
465    default:
466        break;
467    }
468
469    /* Set command index */
470    if (request->cmd == MMC_CIM_RESET) {
471        REG_MSC_CMD = MMC_GO_IDLE_STATE;
472    } else {
473        REG_MSC_CMD = request->cmd;
474    }
475
476        /* Set argument */
477    REG_MSC_ARG = request->arg;
478
479    /* Set block length and nob */
480    if (request->cmd == SEND_SCR) { /* get SCR from DataFIFO */
481        REG_MSC_BLKLEN = 8;
482        REG_MSC_NOB = 1;
483    } else {
484        REG_MSC_BLKLEN = request->block_len;
485        REG_MSC_NOB = request->nob;
486    }
487
488    /* Set command */
489    REG_MSC_CMDAT = cmdat;
490
491    DEBUG(1, "Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
492          cmdat, request->arg, request->rtype);
493
494        /* Start MMC/SD clock and send command to card */
495    jz_mmc_start_clock();
496
497    /* Wait for command completion */
498    while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
499        ;
500
501    if (timeout == 0)
502        return MMC_ERROR_TIMEOUT;
503
504    REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
505
506    /* Check for status */
507    retval = jz_mmc_check_status(request);
508    if (retval) {
509        return retval;
510    }
511
512    /* Complete command with no response */
513    if (request->rtype == RESPONSE_NONE) {
514        return MMC_NO_ERROR;
515    }
516
517    /* Get response */
518    jz_mmc_get_response(request);
519
520    /* Start data operation */
521    if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
522        if (events & MMC_EVENT_RX_DATA_DONE) {
523            if (request->cmd == SEND_SCR) {
524                /* SD card returns SCR register as data.
525                   MMC core expect it in the response buffer,
526                   after normal response. */
527                request->buffer = (u8 *)((u32)request->response + 5);
528            }
529            jz_mmc_receive_data(request);
530        }
531
532        if (events & MMC_EVENT_TX_DATA_DONE) {
533            jz_mmc_transmit_data(request);
534        }
535
536        /* Wait for Data Done */
537        while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
538            ;
539        REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
540    }
541
542    /* Wait for Prog Done event */
543    if (events & MMC_EVENT_PROG_DONE) {
544        while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
545            ;
546        REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
547    }
548
549    /* Command completed */
550
551    return MMC_NO_ERROR; /* return successfully */
552}
553
554int mmc_block_read(u8 *dst, ulong src, ulong len)
555{
556
557    struct mmc_request request;
558    struct mmc_response_r1 r1;
559    int retval;
560
561    if (len == 0) {
562        return 0;
563    }
564    mmc_simple_cmd(&request, MMC_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
565    retval = mmc_unpack_r1(&request, &r1, 0);
566    if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) {
567        return retval;
568    }
569
570    mmc_simple_cmd(&request, MMC_SET_BLOCKLEN, len, RESPONSE_R1);
571    if ((retval = mmc_unpack_r1(&request, &r1, 0))) {
572        return retval;
573    }
574
575    if (sd2_0)
576        src /= len;
577
578    mmc_send_cmd(&request, MMC_READ_SINGLE_BLOCK, src, 1,len, RESPONSE_R1, dst);
579    if ((retval = mmc_unpack_r1(&request, &r1, 0))) {
580        return retval;
581    }
582    return retval;
583}
584
585int mmc_block_write(ulong dst, uchar *src, int len)
586{
587    return 0;
588}
589
590int mmc_read(ulong src, uchar *dst, int size)
591{
592    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
593    ulong mmc_block_size, mmc_block_address;
594
595    if (size == 0) {
596        return 0;
597    }
598
599    if (!mmc_ready) {
600        printf("MMC card is not ready\n");
601        return -1;
602    }
603
604    mmc_block_size = MMC_BLOCK_SIZE;
605    mmc_block_address = ~(mmc_block_size - 1);
606
607    src -= CFG_MMC_BASE;
608    end = src + size;
609    part_start = ~mmc_block_address & src;
610    part_end = ~mmc_block_address & end;
611    aligned_start = mmc_block_address & src;
612    aligned_end = mmc_block_address & end;
613    /* all block aligned accesses */
614    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
615    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
616    if (part_start) {
617        part_len = mmc_block_size - part_start;
618        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
619        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
620        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
621            return -1;
622        }
623        memcpy(dst, mmc_buf+part_start, part_len);
624        dst += part_len;
625        src += part_len;
626    }
627    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
628    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
629    for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
630        debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
631        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
632
633        if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) {
634            return -1;
635        }
636    }
637    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
638    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
639
640    if (part_end && src < end) {
641        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
642            return -1;
643        }
644        memcpy(dst, mmc_buf, part_end);
645    }
646    return 0;
647
648}
649
650int mmc_write(uchar *src, ulong dst, int size)
651{
652    ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
653    ulong mmc_block_size, mmc_block_address;
654
655    if (size == 0) {
656        return 0;
657    }
658
659    if (!mmc_ready) {
660        printf("MMC card is not ready\n");
661        return -1;
662    }
663
664    mmc_block_size = MMC_BLOCK_SIZE;
665    mmc_block_address = ~(mmc_block_size - 1);
666
667    dst -= CFG_MMC_BASE;
668    end = dst + size;
669    part_start = ~mmc_block_address & dst;
670    part_end = ~mmc_block_address & end;
671    aligned_start = mmc_block_address & dst;
672    aligned_end = mmc_block_address & end;
673
674    /* all block aligned accesses */
675    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
676    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
677    if (part_start) {
678        part_len = mmc_block_size - part_start;
679        debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
680        (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
681        if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
682            return -1;
683        }
684        memcpy(mmc_buf+part_start, src, part_len);
685        if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
686            return -1;
687        }
688        dst += part_len;
689        src += part_len;
690    }
691    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
692    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
693    for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
694        debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
695        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
696        if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
697            return -1;
698        }
699    }
700    debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
701    src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
702    if (part_end && dst < end) {
703        debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
704        src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
705        if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
706            return -1;
707        }
708        memcpy(mmc_buf, src, part_end);
709        if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
710            return -1;
711        }
712    }
713    return 0;
714}
715
716ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
717{
718    ulong src;
719    int mmc_block_size = MMC_BLOCK_SIZE;
720
721    src = blknr * mmc_block_size + CFG_MMC_BASE;
722    mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
723    return blkcnt;
724}
725
726int mmc_select_card(void)
727{
728    struct mmc_request request;
729    struct mmc_response_r1 r1;
730    int retval;
731
732    mmc_simple_cmd(&request, MMC_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
733    retval = mmc_unpack_r1(&request, &r1, 0);
734    if (retval) {
735        return retval;
736    }
737
738    if (mmcinfo.sd) {
739        mmc_simple_cmd(&request, MMC_APP_CMD, mmcinfo.rca, RESPONSE_R1);
740        retval = mmc_unpack_r1(&request,&r1,0);
741        if (retval) {
742            return retval;
743        }
744#if defined(MMC_BUS_WIDTH_1BIT)
745        mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
746#else
747        mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
748#endif
749                retval = mmc_unpack_r1(&request,&r1,0);
750                if (retval) {
751            return retval;
752        }
753    }
754    return 0;
755}
756
757/*
758 * Configure card
759 */
760static void mmc_configure_card(void)
761{
762    u32 rate;
763
764    /* Get card info */
765    if (sd2_0)
766        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
767    else
768        mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
769
770    mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
771
772    /* Fix the clock rate */
773    rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
774    if (rate < MMC_CLOCK_SLOW)
775        rate = MMC_CLOCK_SLOW;
776    if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
777        rate = MMC_CLOCK_FAST;
778        if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
779        rate = SD_CLOCK_FAST;
780
781    DEBUG(2,"mmc_configure_card: block_len=%d block_num=%d rate=%d\n", mmcinfo.block_len, mmcinfo.block_num, rate);
782
783    jz_mmc_set_clock(mmcinfo.sd, rate);
784}
785
786/*
787 * State machine routines to initialize card(s)
788 */
789
790/*
791  CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
792  --- Must enter from GO_IDLE_STATE ---
793  1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
794  2. SEND_OP_COND (Full Range) [CMD1] {optional}
795  3. SEND_OP_COND (Set Range ) [CMD1]
796     If busy, delay and repeat step 2
797  4. ALL_SEND_CID [CMD2]
798     If timeout, set an error (no cards found)
799  5. SET_RELATIVE_ADDR [CMD3]
800  6. SEND_CSD [CMD9]
801  7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
802  8. Set clock frequency (check available in csd.tran_speed)
803 */
804
805#define MMC_INIT_DOING 0
806#define MMC_INIT_PASSED 1
807#define MMC_INIT_FAILED 2
808
809static int mmc_init_card_state(struct mmc_request *request)
810{
811    struct mmc_response_r1 r1;
812    struct mmc_response_r3 r3;
813    int retval;
814    int ocr = 0x40300000;
815    int limit_41 = 0;
816
817    DEBUG(2,"mmc_init_card_state\n");
818
819    switch (request->cmd) {
820    case MMC_GO_IDLE_STATE: /* No response to parse */
821        if (mmcinfo.sd)
822            mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
823        else
824            mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
825        break;
826
827    case 8:
828            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
829        mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1);
830        break;
831
832        case MMC_APP_CMD:
833            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
834        if (retval & (limit_41 < 100)) {
835            DEBUG(0, "mmc_init_card_state: unable to MMC_APP_CMD error=%d (%s)\n",
836                  retval, mmc_result_to_string(retval));
837            limit_41++;
838            mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3);
839        } else if (limit_41 < 100) {
840            limit_41++;
841            mmc_simple_cmd(request, SD_SEND_OP_COND, ocr, RESPONSE_R3);
842        } else{
843            /* reset the card to idle*/
844            mmc_simple_cmd(request, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE);
845            mmcinfo.sd = 0;
846        }
847        break;
848
849        case SD_SEND_OP_COND:
850                retval = mmc_unpack_r3(request, &r3);
851                if (retval) {
852                  /* Try MMC card */
853                    mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
854                    break;
855        }
856
857                DEBUG(2,"mmc_init_card_state: read ocr value = 0x%08x\n", r3.ocr);
858
859        if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
860            udelay(10000);
861            mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1);
862        }
863        else {
864          /* Set the data bus width to 4 bits */
865                  mmcinfo.sd = 1; /* SD Card ready */
866                  mmcinfo.state = CARD_STATE_READY;
867          mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);
868        }
869        break;
870
871    case MMC_SEND_OP_COND:
872        retval = mmc_unpack_r3(request, &r3);
873        if (retval) {
874            DEBUG(0,"mmc_init_card_state: failed SEND_OP_COND error=%d (%s)\n",
875                  retval, mmc_result_to_string(retval));
876            return MMC_INIT_FAILED;
877        }
878
879        DEBUG(2,"mmc_init_card_state: read ocr value = 0x%08x\n", r3.ocr);
880        if (!(r3.ocr & MMC_CARD_BUSY)) {
881                    mmc_simple_cmd(request, MMC_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
882        }
883        else {
884                mmcinfo.sd = 0; /* MMC Card ready */
885            mmcinfo.state = CARD_STATE_READY;
886            mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);
887        }
888        break;
889
890    case MMC_ALL_SEND_CID:
891        retval = mmc_unpack_cid( request, &mmcinfo.cid );
892        mmc_dev.if_type = IF_TYPE_MMC;
893        mmc_dev.part_type = PART_TYPE_DOS;
894        mmc_dev.dev = 0;
895        mmc_dev.lun = 0;
896        mmc_dev.type = 0;
897        /* FIXME fill in the correct size (is set to 32MByte) */
898        mmc_dev.blksz = 512;
899        mmc_dev.lba = 0x10000;
900        mmc_dev.removable = 0;
901
902        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
903        if ( retval && (retval != MMC_ERROR_CRC)) {
904            DEBUG(0,"mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
905                  retval, mmc_result_to_string(retval));
906            return MMC_INIT_FAILED;
907        }
908        mmcinfo.state = CARD_STATE_IDENT;
909        if(mmcinfo.sd)
910            mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
911                else
912            mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
913        break;
914
915        case MMC_SET_RELATIVE_ADDR:
916            if (mmcinfo.sd) {
917            retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
918            mmcinfo.rca = mmcinfo.rca << 16;
919            DEBUG(2, "mmc_init_card_state: Get RCA from SD: 0x%04x Status: %x\n", mmcinfo.rca, r1.status);
920                } else {
921            retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
922            mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
923            }
924        if (retval) {
925            DEBUG(0, "mmc_init_card_state: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
926                  retval, mmc_result_to_string(retval));
927            return MMC_INIT_FAILED;
928        }
929
930        mmcinfo.state = CARD_STATE_STBY;
931                mmc_simple_cmd(request, MMC_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
932
933        break;
934
935    case MMC_SEND_CSD:
936        retval = mmc_unpack_csd(request, &mmcinfo.csd);
937            mmc_csd_t *csd = (mmc_csd_t *)retval;
938            memcpy(&mmc_csd, csd, sizeof(csd));
939            mmc_ready = 1;
940
941            printf("MMC card is ready\n");
942            /* FIXME add verbose printout for csd */
943
944        /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
945            if (retval && (retval != MMC_ERROR_CRC)) {
946            DEBUG(0, "mmc_init_card_state: unable to SEND_CSD error=%d (%s)\n",
947                  retval, mmc_result_to_string(retval));
948            return MMC_INIT_FAILED;
949        }
950        if (mmcinfo.csd.dsr_imp) {
951            DEBUG(0, "mmc_init_card_state: driver doesn't support setting DSR\n");
952        }
953        mmc_configure_card();
954        return MMC_INIT_PASSED;
955
956    default:
957        DEBUG(0, "mmc_init_card_state: error! Illegal last cmd %d\n", request->cmd);
958        return MMC_INIT_FAILED;
959    }
960
961    return MMC_INIT_DOING;
962}
963
964int mmc_init_card(void)
965{
966    struct mmc_request request;
967    int retval;
968
969    mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
970    mmc_simple_cmd(&request, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE);
971    mmcinfo.sd = 1; /* assuming a SD card */
972
973    while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
974        ;
975
976    if (retval == MMC_INIT_PASSED)
977        return MMC_NO_ERROR;
978    else
979        return MMC_NO_RESPONSE;
980}
981
982int mmc_legacy_init(int verbose)
983{
984    if (!__msc_card_detected())
985        return 1;
986
987    printf("MMC card found\n");
988
989    /* Step-1: init GPIO */
990    __gpio_as_msc();
991
992    __msc_init_io();
993
994    /* Step-2: turn on power of card */
995#if !defined(CONFIG_SAKC)
996    __msc_enable_power();
997#endif
998
999    /* Step-3: Reset MSC Controller. */
1000    __msc_reset();
1001
1002    /* Step-3: mask all IRQs. */
1003    MMC_IRQ_MASK();
1004
1005    /* Step-4: stop MMC/SD clock */
1006    jz_mmc_stop_clock();
1007    mmc_init_card();
1008    mmc_select_card();
1009
1010    mmc_dev.block_read = mmc_bread;
1011    fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
1012
1013    return 0;
1014}
1015
1016int mmc_ident(block_dev_desc_t *dev)
1017{
1018    return 0;
1019}
1020
1021int mmc2info(ulong addr)
1022{
1023    /* FIXME hard codes to 32 MB device */
1024    if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
1025    return 1;
1026    }
1027    return 0;
1028}
1029/*
1030 * Debugging functions
1031 */
1032
1033static char * mmc_result_strings[] = {
1034    "NO_RESPONSE",
1035    "NO_ERROR",
1036    "ERROR_OUT_OF_RANGE",
1037    "ERROR_ADDRESS",
1038    "ERROR_BLOCK_LEN",
1039    "ERROR_ERASE_SEQ",
1040    "ERROR_ERASE_PARAM",
1041    "ERROR_WP_VIOLATION",
1042    "ERROR_CARD_IS_LOCKED",
1043    "ERROR_LOCK_UNLOCK_FAILED",
1044    "ERROR_COM_CRC",
1045    "ERROR_ILLEGAL_COMMAND",
1046    "ERROR_CARD_ECC_FAILED",
1047    "ERROR_CC",
1048    "ERROR_GENERAL",
1049    "ERROR_UNDERRUN",
1050    "ERROR_OVERRUN",
1051    "ERROR_CID_CSD_OVERWRITE",
1052    "ERROR_STATE_MISMATCH",
1053    "ERROR_HEADER_MISMATCH",
1054    "ERROR_TIMEOUT",
1055    "ERROR_CRC",
1056    "ERROR_DRIVER_FAILURE",
1057};
1058
1059char * mmc_result_to_string(int i)
1060{
1061    return mmc_result_strings[i+1];
1062}
1063
1064static char * card_state_strings[] = {
1065    "empty",
1066    "idle",
1067    "ready",
1068    "ident",
1069    "stby",
1070    "tran",
1071    "data",
1072    "rcv",
1073    "prg",
1074    "dis",
1075};
1076
1077static inline char * card_state_to_string(int i)
1078{
1079    return card_state_strings[i+1];
1080}
1081
1082/*
1083 * Utility functions
1084 */
1085
1086#define PARSE_U32(_buf,_index) \
1087    (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
1088        (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
1089
1090#define PARSE_U16(_buf,_index) \
1091    (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
1092
1093int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
1094{
1095    u8 *buf = request->response;
1096    int num = 0;
1097
1098    if (request->result)
1099        return request->result;
1100
1101    csd->csd_structure = (buf[1] & 0xc0) >> 6;
1102    if (csd->csd_structure)
1103        sd2_0 = 1;
1104    else
1105        sd2_0 = 0;
1106
1107    switch (csd->csd_structure) {
1108    case 0 :
1109        csd->taac = buf[2];
1110        csd->nsac = buf[3];
1111        csd->tran_speed = buf[4];
1112        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1113        csd->read_bl_len = buf[6] & 0x0f;
1114        /* for support 2GB card*/
1115        if (csd->read_bl_len >= 10)
1116        {
1117            num = csd->read_bl_len - 9;
1118            csd->read_bl_len = 9;
1119        }
1120
1121        csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
1122        csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
1123        csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
1124        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1125        csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
1126
1127        if (num)
1128            csd->c_size = csd->c_size << num;
1129
1130
1131        csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
1132        csd->vdd_r_curr_max = buf[9] & 0x07;
1133        csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
1134        csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
1135        csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
1136        switch (csd->csd_structure) {
1137        case CSD_STRUCT_VER_1_0:
1138        case CSD_STRUCT_VER_1_1:
1139            csd->erase.v22.sector_size = (buf[11] & 0x7c) >> 2;
1140            csd->erase.v22.erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
1141
1142            break;
1143        case CSD_STRUCT_VER_1_2:
1144        default:
1145            csd->erase.v31.erase_grp_size = (buf[11] & 0x7c) >> 2;
1146            csd->erase.v31.erase_grp_mult = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
1147            break;
1148        }
1149        csd->wp_grp_size = buf[12] & 0x1f;
1150        csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
1151        csd->default_ecc = (buf[13] & 0x60) >> 5;
1152        csd->r2w_factor = (buf[13] & 0x1c) >> 2;
1153        csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
1154        if (csd->write_bl_len >= 10)
1155            csd->write_bl_len = 9;
1156
1157        csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
1158        csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
1159        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1160        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1161        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1162        csd->file_format = (buf[15] & 0x0c) >> 2;
1163        csd->ecc = buf[15] & 0x03;
1164
1165        DEBUG(2," csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x\n"
1166              " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n"
1167              " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n"
1168              " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n"
1169              " wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d\n"
1170              " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n"
1171              " perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d\n",
1172              csd->csd_structure, csd->spec_vers,
1173              csd->taac, csd->nsac, csd->tran_speed,
1174              csd->ccc, csd->read_bl_len,
1175              csd->read_bl_partial, csd->write_blk_misalign,
1176              csd->read_blk_misalign, csd->dsr_imp,
1177              csd->c_size, csd->vdd_r_curr_min,
1178              csd->vdd_r_curr_max, csd->vdd_w_curr_min,
1179              csd->vdd_w_curr_max, csd->c_size_mult,
1180              csd->wp_grp_size, csd->wp_grp_enable,
1181              csd->default_ecc, csd->r2w_factor,
1182              csd->write_bl_len, csd->write_bl_partial,
1183              csd->file_format_grp, csd->copy,
1184              csd->perm_write_protect, csd->tmp_write_protect,
1185              csd->file_format, csd->ecc);
1186        switch (csd->csd_structure) {
1187        case CSD_STRUCT_VER_1_0:
1188        case CSD_STRUCT_VER_1_1:
1189            DEBUG(2," V22 sector_size=%d erase_grp_size=%d\n",
1190                  csd->erase.v22.sector_size,
1191                  csd->erase.v22.erase_grp_size);
1192            break;
1193        case CSD_STRUCT_VER_1_2:
1194        default:
1195            DEBUG(2," V31 erase_grp_size=%d erase_grp_mult=%d\n",
1196                  csd->erase.v31.erase_grp_size,
1197                  csd->erase.v31.erase_grp_mult);
1198            break;
1199
1200        }
1201        break;
1202
1203    case 1 :
1204        csd->taac = 0;
1205        csd->nsac = 0;
1206        csd->tran_speed = buf[4];
1207        csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
1208
1209        csd->read_bl_len = 9;
1210        csd->read_bl_partial = 0;
1211        csd->write_blk_misalign = 0;
1212        csd->read_blk_misalign = 0;
1213        csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
1214        csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
1215        switch (csd->csd_structure) {
1216        case CSD_STRUCT_VER_1_0:
1217        case CSD_STRUCT_VER_1_1:
1218            csd->erase.v22.sector_size = 0x7f;
1219            csd->erase.v22.erase_grp_size = 0;
1220            break;
1221        case CSD_STRUCT_VER_1_2:
1222        default:
1223            csd->erase.v31.erase_grp_size = 0x7f;
1224            csd->erase.v31.erase_grp_mult = 0;
1225            break;
1226        }
1227        csd->wp_grp_size = 0;
1228        csd->wp_grp_enable = 0;
1229        csd->default_ecc = (buf[13] & 0x60) >> 5;
1230        csd->r2w_factor = 4;/* Unused */
1231        csd->write_bl_len = 9;
1232
1233        csd->write_bl_partial = 0;
1234        csd->file_format_grp = 0;
1235        csd->copy = (buf[15] & 0x40) ? 1 : 0;
1236        csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
1237        csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
1238        csd->file_format = 0;
1239        csd->ecc = buf[15] & 0x03;
1240
1241        DEBUG(2," csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x\n"
1242              " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n"
1243              " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n"
1244              " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n"
1245              " wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d\n"
1246              " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n"
1247              " perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d\n",
1248              csd->csd_structure, csd->spec_vers,
1249              csd->taac, csd->nsac, csd->tran_speed,
1250              csd->ccc, csd->read_bl_len,
1251              csd->read_bl_partial, csd->write_blk_misalign,
1252              csd->read_blk_misalign, csd->dsr_imp,
1253              csd->c_size, csd->vdd_r_curr_min,
1254              csd->vdd_r_curr_max, csd->vdd_w_curr_min,
1255              csd->vdd_w_curr_max, csd->c_size_mult,
1256              csd->wp_grp_size, csd->wp_grp_enable,
1257              csd->default_ecc, csd->r2w_factor,
1258              csd->write_bl_len, csd->write_bl_partial,
1259              csd->file_format_grp, csd->copy,
1260              csd->perm_write_protect, csd->tmp_write_protect,
1261              csd->file_format, csd->ecc);
1262        switch (csd->csd_structure) {
1263        case CSD_STRUCT_VER_1_0:
1264        case CSD_STRUCT_VER_1_1:
1265            DEBUG(2," V22 sector_size=%d erase_grp_size=%d\n",
1266                  csd->erase.v22.sector_size,
1267                  csd->erase.v22.erase_grp_size);
1268            break;
1269        case CSD_STRUCT_VER_1_2:
1270        default:
1271            DEBUG(2," V31 erase_grp_size=%d erase_grp_mult=%d\n",
1272                  csd->erase.v31.erase_grp_size,
1273                  csd->erase.v31.erase_grp_mult);
1274            break;
1275        }
1276    }
1277
1278    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1279
1280    return 0;
1281}
1282
1283int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
1284{
1285    u8 *buf = request->response;
1286
1287    if (request->result) return request->result;
1288
1289    r1->cmd = buf[0];
1290    r1->status = PARSE_U32(buf,1);
1291
1292    DEBUG(2, "mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
1293
1294    if (R1_STATUS(r1->status)) {
1295        if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
1296        if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
1297        if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
1298        if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
1299        if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
1300        if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
1301        /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
1302        if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
1303        if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
1304        if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
1305        if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
1306        if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
1307        if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
1308        if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
1309        if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
1310        if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
1311    }
1312
1313    if (buf[0] != request->cmd) return MMC_ERROR_HEADER_MISMATCH;
1314
1315    /* This should be last - it's the least dangerous error */
1316
1317    return 0;
1318}
1319
1320int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
1321{
1322        u8 *buf = request->response;
1323    if (request->result) return request->result;
1324
1325        *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
1326        return mmc_unpack_r1(request, r1, state);
1327
1328}
1329
1330int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
1331{
1332    u8 *buf = request->response;
1333
1334    if (request->result) return request->result;
1335
1336        *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
1337
1338        *(buf+1) = 0;
1339        *(buf+2) = 0;
1340
1341        return mmc_unpack_r1(request, r1, state);
1342}
1343
1344int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
1345{
1346    u8 *buf = request->response;
1347    int i;
1348
1349    if (request->result) return request->result;
1350
1351    cid->mid = buf[1];
1352    cid->oid = PARSE_U16(buf,2);
1353    for (i = 0 ; i < 6 ; i++)
1354        cid->pnm[i] = buf[4+i];
1355    cid->pnm[6] = 0;
1356    cid->prv = buf[10];
1357    cid->psn = PARSE_U32(buf,11);
1358    cid->mdt = buf[15];
1359
1360    DEBUG(2,"mmc_unpack_cid: mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d\n",
1361          cid->mid, cid->oid, cid->pnm,
1362          (cid->prv>>4), (cid->prv&0xf),
1363          cid->psn, (cid->mdt>>4), (cid->mdt&0xf)+1997);
1364
1365    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1366          return 0;
1367}
1368
1369int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
1370{
1371    u8 *buf = request->response;
1372
1373    if (request->result) return request->result;
1374
1375    r3->ocr = PARSE_U32(buf,1);
1376    DEBUG(2,"mmc_unpack_r3: ocr=%08x\n", r3->ocr);
1377
1378    if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
1379    return 0;
1380}
1381
1382#define KBPS 1
1383#define MBPS 1000
1384
1385static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
1386static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
1387            3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
1388
1389u32 mmc_tran_speed(u8 ts)
1390{
1391    u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
1392
1393    if (rate <= 0) {
1394        DEBUG(0, "mmc_tran_speed: error - unrecognized speed 0x%02x\n", ts);
1395        return 1;
1396    }
1397
1398    return rate;
1399}
1400
1401void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
1402           u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
1403{
1404    request->cmd = cmd;
1405    request->arg = arg;
1406    request->rtype = rtype;
1407    request->nob = nob;
1408    request->block_len = block_len;
1409    request->buffer = buffer;
1410    request->cnt = nob * block_len;
1411
1412    jz_mmc_exec_cmd(request);
1413}
1414
1415#endif /* CONFIG_MMC */
1416#endif /* CONFIG_JZ4740 */
package/boot/uboot-xburst/files/cpu/mips/jz_mmc.h
1/*
2 * linux/drivers/mmc/jz_mmc.h
3 *
4 * Author: Vladimir Shebordaev, Igor Oblakov
5 * Copyright: MontaVista Software Inc.
6 *
7 * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef __MMC_JZMMC_H__
14#define __MMC_JZMMC_H__
15
16#include "mmc_protocol.h"
17
18#define MMC_DEBUG_LEVEL 0 /* Enable Debug: 0 - no debug */
19
20#define MMC_BLOCK_SIZE 512 /* MMC/SD Block Size */
21
22#define ID_TO_RCA(x) ((x)+1)
23
24#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
25
26enum mmc_result_t {
27    MMC_NO_RESPONSE = -1,
28    MMC_NO_ERROR = 0,
29    MMC_ERROR_OUT_OF_RANGE,
30    MMC_ERROR_ADDRESS,
31    MMC_ERROR_BLOCK_LEN,
32    MMC_ERROR_ERASE_SEQ,
33    MMC_ERROR_ERASE_PARAM,
34    MMC_ERROR_WP_VIOLATION,
35    MMC_ERROR_CARD_IS_LOCKED,
36    MMC_ERROR_LOCK_UNLOCK_FAILED,
37    MMC_ERROR_COM_CRC,
38    MMC_ERROR_ILLEGAL_COMMAND,
39    MMC_ERROR_CARD_ECC_FAILED,
40    MMC_ERROR_CC,
41    MMC_ERROR_GENERAL,
42    MMC_ERROR_UNDERRUN,
43    MMC_ERROR_OVERRUN,
44    MMC_ERROR_CID_CSD_OVERWRITE,
45    MMC_ERROR_STATE_MISMATCH,
46    MMC_ERROR_HEADER_MISMATCH,
47    MMC_ERROR_TIMEOUT,
48    MMC_ERROR_CRC,
49    MMC_ERROR_DRIVER_FAILURE,
50};
51
52/* the information structure of MMC/SD Card */
53typedef struct MMC_INFO
54{
55    int id; /* Card index */
56        int sd; /* MMC or SD card */
57        int rca; /* RCA */
58        u32 scr; /* SCR 63:32*/
59    int flags; /* Ejected, inserted */
60    enum card_state state; /* empty, ident, ready, whatever */
61
62    /* Card specific information */
63    struct mmc_cid cid;
64    struct mmc_csd csd;
65    u32 block_num;
66    u32 block_len;
67    u32 erase_unit;
68} mmc_info;
69
70mmc_info mmcinfo;
71
72struct mmc_request {
73    int index; /* Slot index - used for CS lines */
74    int cmd; /* Command to send */
75    u32 arg; /* Argument to send */
76    enum mmc_rsp_t rtype; /* Response type expected */
77
78    /* Data transfer (these may be modified at the low level) */
79    u16 nob; /* Number of blocks to transfer*/
80    u16 block_len; /* Block length */
81    u8 *buffer; /* Data buffer */
82    u32 cnt; /* Data length, for PIO */
83
84    /* Results */
85    u8 response[18]; /* Buffer to store response - CRC is optional */
86    enum mmc_result_t result;
87};
88
89char * mmc_result_to_string(int);
90int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
91int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
92int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
93int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
94int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
95int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
96
97void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
98             u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
99u32 mmc_tran_speed(u8 ts);
100void jz_mmc_set_clock(int sd, u32 rate);
101void jz_mmc_hardware_init(void);
102
103static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
104{
105    mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
106}
107
108int mmc_legacy_init(int verbose);
109int mmc_read(ulong src, uchar *dst, int size);
110int mmc_write(uchar *src, ulong dst, int size);
111int mmc2info(ulong addr);
112
113#endif /* __MMC_JZMMC_H__ */
package/boot/uboot-xburst/files/cpu/mips/jz_serial.c
1/*
2 * Jz47xx UART support
3 *
4 * Hardcoded to UART 0 for now
5 * Options also hardcoded to 8N1
6 *
7 * Copyright (c) 2005
8 * Ingenic Semiconductor, <jlwei@ingenic.cn>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26#include <config.h>
27
28#if defined(CONFIG_JZ4740)
29
30#include <common.h>
31
32#include <asm/jz4740.h>
33
34#undef UART_BASE
35#ifndef CONFIG_SYS_UART_BASE
36#define UART_BASE UART0_BASE
37#else
38#define UART_BASE CONFIG_SYS_UART_BASE
39#endif
40
41/******************************************************************************
42*
43* serial_init - initialize a channel
44*
45* This routine initializes the number of data bits, parity
46* and set the selected baud rate. Interrupts are disabled.
47* Set the modem control signals if the option is selected.
48*
49* RETURNS: N/A
50*/
51
52int serial_init (void)
53{
54#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
55    volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR);
56    volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR);
57    volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER);
58    volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR);
59
60    /* Disable port interrupts while changing hardware */
61    *uart_ier = 0;
62
63    /* Disable UART unit function */
64    *uart_fcr = ~UART_FCR_UUE;
65
66    /* Set both receiver and transmitter in UART mode (not SIR) */
67    *uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE);
68
69    /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
70    *uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1;
71
72    /* Set baud rate */
73    serial_setbrg();
74
75    /* Enable UART unit, enable and clear FIFO */
76    *uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS;
77#endif
78    return 0;
79}
80
81void serial_setbrg (void)
82{
83    volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR);
84    volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR);
85    volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR);
86    u32 baud_div, tmp;
87
88    baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE;
89
90    tmp = *uart_lcr;
91    tmp |= UART_LCR_DLAB;
92    *uart_lcr = tmp;
93
94    *uart_dlhr = (baud_div >> 8) & 0xff;
95    *uart_dllr = baud_div & 0xff;
96
97    tmp &= ~UART_LCR_DLAB;
98    *uart_lcr = tmp;
99}
100
101void serial_putc (const char c)
102{
103    volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR);
104    volatile u8 *uart_tdr = (volatile u8 *)(UART_BASE + OFF_TDR);
105
106    if (c == '\n') serial_putc ('\r');
107
108    /* Wait for fifo to shift out some bytes */
109    while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) );
110
111    *uart_tdr = (u8)c;
112}
113
114void serial_puts (const char *s)
115{
116    while (*s) {
117        serial_putc (*s++);
118    }
119}
120
121int serial_getc (void)
122{
123    volatile u8 *uart_rdr = (volatile u8 *)(UART_BASE + OFF_RDR);
124
125    while (!serial_tstc());
126
127    return *uart_rdr;
128}
129
130int serial_tstc (void)
131{
132    volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR);
133
134    if (*uart_lsr & UART_LSR_DR) {
135        /* Data in rfifo */
136        return (1);
137    }
138    return 0;
139}
140
141#endif
package/boot/uboot-xburst/files/cpu/mips/mmc_protocol.h
1/*
2**********************************************************************
3*
4* uC/MMC
5*
6* (c) Copyright 2005 - 2007, Ingenic Semiconductor, Inc
7* All rights reserved.
8*
9***********************************************************************
10
11File : mmc_protocol.h
12Purpose : MMC protocol definitions.
13
14Version-Date-----Author-Explanation
151.00.00 20060831 WeiJianli First release
16
17Known problems or limitations with current version
18(none)
19*/
20
21#ifndef __MMC_PROTOCOL__
22#define __MMC_PROTOCOL__
23
24/* Standard MMC/SD clock speeds */
25#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
26#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
27#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
28
29/* Extra MMC commands for state control */
30/* Use negative numbers to disambiguate */
31#define MMC_CIM_RESET -1
32
33/* Standard MMC commands (3.1) type argument response */
34   /* class 1 */
35#define MMC_GO_IDLE_STATE 0 /* bc */
36#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
37#define MMC_ALL_SEND_CID 2 /* bcr R2 */
38#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
39#define MMC_SET_DSR 4 /* bc [31:16] RCA */
40#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
41#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
42#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
43#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
44#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
45#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
46#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
47
48  /* class 2 */
49#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
50#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
51#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
52
53  /* class 3 */
54#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
55
56  /* class 4 */
57#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
58#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
59#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
60#define MMC_PROGRAM_CID 26 /* adtc R1 */
61#define MMC_PROGRAM_CSD 27 /* adtc R1 */
62
63  /* class 6 */
64#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
65#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
66#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
67
68  /* class 5 */
69#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
70#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
71#define MMC_ERASE 37 /* ac R1b */
72
73  /* class 9 */
74#define MMC_FAST_IO 39 /* ac <Complex> R4 */
75#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
76
77  /* class 7 */
78#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
79
80  /* class 8 */
81#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
82#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
83
84  /* SD class */
85#define SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */
86#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
87#define SEND_SCR 51 /* adtc [31:0] staff R1 */
88
89/* Don't change the order of these; they are used in dispatch tables */
90enum mmc_rsp_t {
91    RESPONSE_NONE = 0,
92    RESPONSE_R1 = 1,
93    RESPONSE_R1B = 2,
94    RESPONSE_R2_CID = 3,
95    RESPONSE_R2_CSD = 4,
96    RESPONSE_R3 = 5,
97    RESPONSE_R4 = 6,
98    RESPONSE_R5 = 7,
99        RESPONSE_R6 = 8,
100};
101
102
103/*
104  MMC status in R1
105  Type
106      e : error bit
107    s : status bit
108    r : detected and set for the actual command response
109    x : detected and set during command execution. the host must poll
110            the card by sending status command in order to read these bits.
111  Clear condition
112      a : according to the card state
113    b : always related to the previous command. Reception of
114            a valid command will clear it (with a delay of one command)
115    c : clear by read
116 */
117
118#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
119#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
120#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
121#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
122#define R1_ERASE_PARAM (1 << 27) /* ex, c */
123#define R1_WP_VIOLATION (1 << 26) /* erx, c */
124#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
125#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
126#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
127#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
128#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
129#define R1_CC_ERROR (1 << 20) /* erx, c */
130#define R1_ERROR (1 << 19) /* erx, c */
131#define R1_UNDERRUN (1 << 18) /* ex, c */
132#define R1_OVERRUN (1 << 17) /* ex, c */
133#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
134#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
135#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
136#define R1_ERASE_RESET (1 << 13) /* sr, c */
137#define R1_STATUS(x) (x & 0xFFFFE000)
138#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
139#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
140#define R1_APP_CMD (1 << 7) /* sr, c */
141
142enum card_state {
143    CARD_STATE_EMPTY = -1,
144    CARD_STATE_IDLE = 0,
145    CARD_STATE_READY = 1,
146    CARD_STATE_IDENT = 2,
147    CARD_STATE_STBY = 3,
148    CARD_STATE_TRAN = 4,
149    CARD_STATE_DATA = 5,
150    CARD_STATE_RCV = 6,
151    CARD_STATE_PRG = 7,
152    CARD_STATE_DIS = 8,
153};
154
155/* These are unpacked versions of the actual responses */
156
157 struct mmc_response_r1 {
158    u8 cmd;
159    u32 status;
160};
161
162typedef struct mmc_cid {
163    u8 mid;
164    u16 oid;
165    u8 pnm[7]; /* Product name (we null-terminate) */
166    u8 prv;
167    u32 psn;
168    u8 mdt;
169}mmc_cid_t;
170
171typedef struct mmc_csd {
172    u8 csd_structure;
173    u8 spec_vers;
174    u8 taac;
175    u8 nsac;
176    u8 tran_speed;
177    u16 ccc;
178    u8 read_bl_len;
179    u8 read_bl_partial;
180    u8 write_blk_misalign;
181    u8 read_blk_misalign;
182    u8 dsr_imp;
183    u16 c_size;
184    u8 vdd_r_curr_min;
185    u8 vdd_r_curr_max;
186    u8 vdd_w_curr_min;
187    u8 vdd_w_curr_max;
188    u8 c_size_mult;
189    union {
190        struct { /* MMC system specification version 3.1 */
191            u8 erase_grp_size;
192            u8 erase_grp_mult;
193        } v31;
194        struct { /* MMC system specification version 2.2 */
195            u8 sector_size;
196            u8 erase_grp_size;
197        } v22;
198    } erase;
199    u8 wp_grp_size;
200    u8 wp_grp_enable;
201    u8 default_ecc;
202    u8 r2w_factor;
203    u8 write_bl_len;
204    u8 write_bl_partial;
205    u8 file_format_grp;
206    u8 copy;
207    u8 perm_write_protect;
208    u8 tmp_write_protect;
209    u8 file_format;
210    u8 ecc;
211}mmc_csd_t;;
212
213struct mmc_response_r3 {
214    u32 ocr;
215};
216
217#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */
218#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */
219#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */
220#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */
221#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */
222#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */
223#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */
224#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */
225#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
226#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
227#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
228#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
229#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
230#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
231#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
232#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
233#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
234#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
235#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
236#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
237#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
238#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
239#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
240#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
241#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
242
243
244/* CSD field definitions */
245
246#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
247#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
248#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */
249
250#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
251#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
252#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
253#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */
254
255#if MMC_DEBUG_LEVEL
256
257#define DEBUG(n, args...) \
258    do { \
259    if (n <= MMC_DEBUG_LEVEL) { \
260        printf(args); \
261    } \
262    } while(0)
263#else
264#define DEBUG(n, args...)
265#endif /* MMC_DEBUG_EN */
266
267#endif /* __MMC_PROTOCOL__ */
package/boot/uboot-xburst/files/cpu/mips/nanonote_gpm940b0.c
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#include <config.h>
23#include <common.h>
24#include <lcd.h>
25
26#include <asm/io.h> /* virt_to_phys() */
27
28#include <asm/jz4740.h>
29#include "nanonote_gpm940b0.h"
30
31#define align2(n) (n)=((((n)+1)>>1)<<1)
32#define align4(n) (n)=((((n)+3)>>2)<<2)
33#define align8(n) (n)=((((n)+7)>>3)<<3)
34
35struct jzfb_info {
36    unsigned int cfg; /* panel mode and pin usage etc. */
37    unsigned int w;
38    unsigned int h;
39    unsigned int bpp; /* bit per pixel */
40    unsigned int fclk; /* frame clk */
41    unsigned int hsw; /* hsync width, in pclk */
42    unsigned int vsw; /* vsync width, in line count */
43    unsigned int elw; /* end of line, in pclk */
44    unsigned int blw; /* begin of line, in pclk */
45    unsigned int efw; /* end of frame, in line count */
46    unsigned int bfw; /* begin of frame, in line count */
47};
48
49static struct jzfb_info jzfb = {
50    MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
51    320, 240, 32, 70, 1, 1, 273, 140, 1, 20
52};
53
54vidinfo_t panel_info = {
55    320, 240, LCD_BPP,
56};
57
58int lcd_line_length;
59
60int lcd_color_fg;
61int lcd_color_bg;
62/*
63 * Frame buffer memory information
64 */
65void *lcd_base; /* Start of framebuffer memory */
66void *lcd_console_address; /* Start of console buffer */
67
68short console_col;
69short console_row;
70
71void lcd_ctrl_init (void *lcdbase);
72void lcd_enable (void);
73void lcd_disable (void);
74
75static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid);
76static void jz_lcd_desc_init(vidinfo_t *vid);
77static int jz_lcd_hw_init( vidinfo_t *vid );
78extern int flush_cache_all(void);
79
80void lcd_ctrl_init (void *lcdbase)
81{
82    __lcd_display_pin_init();
83
84    jz_lcd_init_mem(lcdbase, &panel_info);
85    jz_lcd_desc_init(&panel_info);
86    jz_lcd_hw_init(&panel_info);
87
88    __lcd_display_on() ;
89}
90
91/*
92 * Before enabled lcd controller, lcd registers should be configured correctly.
93 */
94
95void lcd_enable (void)
96{
97    REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
98    REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
99}
100
101void lcd_disable (void)
102{
103    REG_LCD_CTRL |= (1<<4); /* LCDCTRL.DIS, regular disable */
104    /* REG_LCD_CTRL |= (1<<3); */ /* LCDCTRL.DIS, quikly disable */
105}
106
107static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
108{
109    u_long palette_mem_size;
110    struct jz_fb_info *fbi = &vid->jz_fb;
111    int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
112
113    fbi->screen = (u_long)lcdbase;
114    fbi->palette_size = 256;
115    palette_mem_size = fbi->palette_size * sizeof(u16);
116
117    debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
118    /* locate palette and descs at end of page following fb */
119    fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
120
121    return 0;
122}
123
124static void jz_lcd_desc_init(vidinfo_t *vid)
125{
126    struct jz_fb_info * fbi;
127    fbi = &vid->jz_fb;
128    fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
129    fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
130    fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
131
132    #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
133
134    /* populate descriptors */
135    fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
136    fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
137    fbi->dmadesc_fblow->fidr = 0;
138    fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
139
140    fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
141
142    fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
143    fbi->dmadesc_fbhigh->fidr = 0;
144    fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
145
146    fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
147    fbi->dmadesc_palette->fidr = 0;
148    fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
149
150    if(NBITS(vid->vl_bpix) < 12)
151    {
152        /* assume any mode with <12 bpp is palette driven */
153        fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
154        fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
155        /* flips back and forth between pal and fbhigh */
156        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
157    } else {
158        /* palette shouldn't be loaded in true-color mode */
159        fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
160        fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
161    }
162
163    flush_cache_all();
164}
165
166static int jz_lcd_hw_init(vidinfo_t *vid)
167{
168    struct jz_fb_info *fbi = &vid->jz_fb;
169    unsigned int val = 0;
170    unsigned int pclk;
171    unsigned int stnH;
172    int pll_div;
173
174    /* Setting Control register */
175    switch (jzfb.bpp) {
176    case 1:
177        val |= LCD_CTRL_BPP_1;
178        break;
179    case 2:
180        val |= LCD_CTRL_BPP_2;
181        break;
182    case 4:
183        val |= LCD_CTRL_BPP_4;
184        break;
185    case 8:
186        val |= LCD_CTRL_BPP_8;
187        break;
188    case 15:
189        val |= LCD_CTRL_RGB555;
190    case 16:
191        val |= LCD_CTRL_BPP_16;
192        break;
193    case 17 ... 32:
194        val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
195        break;
196
197    default:
198        printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
199        val |= LCD_CTRL_BPP_16;
200        break;
201    }
202
203    switch (jzfb.cfg & MODE_MASK) {
204    case MODE_STN_MONO_DUAL:
205    case MODE_STN_COLOR_DUAL:
206    case MODE_STN_MONO_SINGLE:
207    case MODE_STN_COLOR_SINGLE:
208        switch (jzfb.bpp) {
209        case 1:
210            /* val |= LCD_CTRL_PEDN; */
211        case 2:
212            val |= LCD_CTRL_FRC_2;
213            break;
214        case 4:
215            val |= LCD_CTRL_FRC_4;
216            break;
217        case 8:
218        default:
219            val |= LCD_CTRL_FRC_16;
220            break;
221        }
222        break;
223    }
224
225    val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
226    val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
227
228    switch (jzfb.cfg & MODE_MASK) {
229    case MODE_STN_MONO_DUAL:
230    case MODE_STN_COLOR_DUAL:
231    case MODE_STN_MONO_SINGLE:
232    case MODE_STN_COLOR_SINGLE:
233        switch (jzfb.cfg & STN_DAT_PINMASK) {
234        case STN_DAT_PIN1:
235            /* Do not adjust the hori-param value. */
236            break;
237        case STN_DAT_PIN2:
238            align2(jzfb.hsw);
239            align2(jzfb.elw);
240            align2(jzfb.blw);
241            break;
242        case STN_DAT_PIN4:
243            align4(jzfb.hsw);
244            align4(jzfb.elw);
245            align4(jzfb.blw);
246            break;
247        case STN_DAT_PIN8:
248            align8(jzfb.hsw);
249            align8(jzfb.elw);
250            align8(jzfb.blw);
251            break;
252        }
253        break;
254    }
255
256    REG_LCD_CTRL = val;
257
258    switch (jzfb.cfg & MODE_MASK) {
259    case MODE_STN_MONO_DUAL:
260    case MODE_STN_COLOR_DUAL:
261    case MODE_STN_MONO_SINGLE:
262    case MODE_STN_COLOR_SINGLE:
263        if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
264            ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
265            stnH = jzfb.h >> 1;
266        else
267            stnH = jzfb.h;
268
269        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
270        REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
271
272        /* Screen setting */
273        REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
274        REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
275        REG_LCD_DAV = (0 << 16) | (stnH);
276
277        /* AC BIAs signal */
278        REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
279
280        break;
281
282    case MODE_TFT_GEN:
283    case MODE_TFT_SHARP:
284    case MODE_TFT_CASIO:
285    case MODE_TFT_SAMSUNG:
286    case MODE_8BIT_SERIAL_TFT:
287    case MODE_TFT_18BIT:
288        REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
289        REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
290        REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
291        REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
292        REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
293            | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
294        break;
295    }
296
297    switch (jzfb.cfg & MODE_MASK) {
298    case MODE_TFT_SAMSUNG:
299    {
300        unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
301        unsigned int rev_s, rev_e, inv_s, inv_e;
302
303        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
304            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
305
306        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
307        tp_s = jzfb.blw + jzfb.w + 1;
308        tp_e = tp_s + 1;
309        /* ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100); */
310        ckv_s = tp_s - pclk/(1000000000/4100);
311        ckv_e = tp_s + total;
312        rev_s = tp_s - 11; /* -11.5 clk */
313        rev_e = rev_s + total;
314        inv_s = tp_s;
315        inv_e = inv_s + total;
316        REG_LCD_CLS = (tp_s << 16) | tp_e;
317        REG_LCD_PS = (ckv_s << 16) | ckv_e;
318        REG_LCD_SPL = (rev_s << 16) | rev_e;
319        REG_LCD_REV = (inv_s << 16) | inv_e;
320        jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
321        break;
322    }
323    case MODE_TFT_SHARP:
324    {
325        unsigned int total, cls_s, cls_e, ps_s, ps_e;
326        unsigned int spl_s, spl_e, rev_s, rev_e;
327        total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
328        spl_s = 1;
329        spl_e = spl_s + 1;
330        cls_s = 0;
331        cls_e = total - 60; /* > 4us (pclk = 80ns) */
332        ps_s = cls_s;
333        ps_e = cls_e;
334        rev_s = total - 40; /* > 3us (pclk = 80ns) */
335        rev_e = rev_s + total;
336        jzfb.cfg |= STFT_PSHI;
337        REG_LCD_SPL = (spl_s << 16) | spl_e;
338        REG_LCD_CLS = (cls_s << 16) | cls_e;
339        REG_LCD_PS = (ps_s << 16) | ps_e;
340        REG_LCD_REV = (rev_s << 16) | rev_e;
341        break;
342    }
343    case MODE_TFT_CASIO:
344        break;
345    }
346
347    /* Configure the LCD panel */
348    REG_LCD_CFG = jzfb.cfg;
349
350    /* Timing setting */
351    __cpm_stop_lcd();
352
353    val = jzfb.fclk; /* frame clk */
354    if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
355        pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
356            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
357    } else {
358        /* serial mode: Hsync period = 3*Width_Pixel */
359        pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
360            (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
361    }
362
363    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
364        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
365        pclk = (pclk * 3);
366
367    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
368        ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
369        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
370        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
371        pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
372
373    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
374        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
375        pclk >>= 1;
376
377    pll_div = ( REG_CPM_CPCCR & CPM_CPCCR_PCS ); /* clock source,0:pllout/2 1: pllout */
378    pll_div = pll_div ? 1 : 2 ;
379    val = ( __cpm_get_pllout()/pll_div ) / pclk;
380    val--;
381    if ( val > 0x1ff ) {
382        printf("CPM_LPCDR too large, set it to 0x1ff\n");
383        val = 0x1ff;
384    }
385    __cpm_set_pixdiv(val);
386
387    val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
388    if ( val > 150000000 ) {
389        printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
390        printf("Change LCDClock to 150MHz\n");
391        val = 150000000;
392    }
393    val = ( __cpm_get_pllout()/pll_div ) / val;
394    val--;
395    if ( val > 0x1f ) {
396        printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
397        val = 0x1f;
398    }
399    __cpm_set_ldiv( val );
400    REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
401
402    __cpm_start_lcd();
403    udelay(1000);
404
405    REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
406
407    if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
408        ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
409        REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
410
411    return 0;
412}
413
414void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
415{
416}
417
418void lcd_initcolregs (void)
419{
420}
package/boot/uboot-xburst/files/cpu/mips/nanonote_gpm940b0.h
1/*
2 * JzRISC lcd controller
3 *
4 * xiangfu liu <xiangfu.z@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#ifndef __QI_LB60_GPM940B0_H__
23#define __QI_LB60_GPM940B0_H__
24
25#include <asm/io.h>
26
27#define mdelay(n) udelay((n)*1000)
28
29#define NR_PALETTE 256
30
31struct lcd_desc{
32    unsigned int next_desc; /* LCDDAx */
33    unsigned int databuf; /* LCDSAx */
34    unsigned int frame_id; /* LCDFIDx */
35    unsigned int cmd; /* LCDCMDx */
36};
37
38#define MODE_MASK 0x0f
39#define MODE_TFT_GEN 0x00
40#define MODE_TFT_SHARP 0x01
41#define MODE_TFT_CASIO 0x02
42#define MODE_TFT_SAMSUNG 0x03
43#define MODE_CCIR656_NONINT 0x04
44#define MODE_CCIR656_INT 0x05
45#define MODE_STN_COLOR_SINGLE 0x08
46#define MODE_STN_MONO_SINGLE 0x09
47#define MODE_STN_COLOR_DUAL 0x0a
48#define MODE_STN_MONO_DUAL 0x0b
49#define MODE_8BIT_SERIAL_TFT 0x0c
50
51#define MODE_TFT_18BIT (1<<7)
52
53#define STN_DAT_PIN1 (0x00 << 4)
54#define STN_DAT_PIN2 (0x01 << 4)
55#define STN_DAT_PIN4 (0x02 << 4)
56#define STN_DAT_PIN8 (0x03 << 4)
57#define STN_DAT_PINMASK STN_DAT_PIN8
58
59#define STFT_PSHI (1 << 15)
60#define STFT_CLSHI (1 << 14)
61#define STFT_SPLHI (1 << 13)
62#define STFT_REVHI (1 << 12)
63
64#define SYNC_MASTER (0 << 16)
65#define SYNC_SLAVE (1 << 16)
66
67#define DE_P (0 << 9)
68#define DE_N (1 << 9)
69
70#define PCLK_P (0 << 10)
71#define PCLK_N (1 << 10)
72
73#define HSYNC_P (0 << 11)
74#define HSYNC_N (1 << 11)
75
76#define VSYNC_P (0 << 8)
77#define VSYNC_N (1 << 8)
78
79#define DATA_NORMAL (0 << 17)
80#define DATA_INVERSE (1 << 17)
81
82
83/* Jz LCDFB supported I/O controls. */
84#define FBIOSETBACKLIGHT 0x4688
85#define FBIODISPON 0x4689
86#define FBIODISPOFF 0x468a
87#define FBIORESET 0x468b
88#define FBIOPRINT_REG 0x468c
89
90/*
91 * LCD panel specific definition
92 */
93#define MODE 0xc9 /* 8bit serial RGB */
94#define SPEN (32*2+21) /*LCD_SPL */
95#define SPCK (32*2+23) /*LCD_CLS */
96#define SPDA (32*2+22) /*LCD_D12 */
97#define LCD_RET (32*3+27)
98
99#define __spi_write_reg1(reg, val) \
100do { \
101    unsigned char no;\
102    unsigned short value;\
103    unsigned char a=0;\
104    unsigned char b=0;\
105    a=reg;\
106    b=val;\
107    __gpio_set_pin(SPEN);\
108    __gpio_set_pin(SPCK);\
109    __gpio_clear_pin(SPDA);\
110    __gpio_clear_pin(SPEN);\
111    udelay(25);\
112    value=((a<<8)|(b&0xFF));\
113    for(no=0;no<16;no++)\
114    {\
115        __gpio_clear_pin(SPCK);\
116        if((value&0x8000)==0x8000)\
117        __gpio_set_pin(SPDA);\
118        else\
119        __gpio_clear_pin(SPDA);\
120        udelay(25);\
121        __gpio_set_pin(SPCK);\
122        value=(value<<1); \
123        udelay(25);\
124     }\
125    __gpio_set_pin(SPEN);\
126    udelay(100);\
127} while (0)
128
129#define __spi_write_reg(reg, val) \
130do {\
131    __spi_write_reg1((reg<<2|2), val);\
132    udelay(100); \
133}while(0)
134
135#define __lcd_special_pin_init() \
136do { \
137    __gpio_as_output(SPEN); /* use SPDA */\
138    __gpio_as_output(SPCK); /* use SPCK */\
139    __gpio_as_output(SPDA); /* use SPDA */\
140    __gpio_as_output(LCD_RET);\
141} while (0)
142
143#define __lcd_special_on() \
144do { \
145    __spi_write_reg1(0x05, 0x1e); \
146    udelay(50);\
147    __spi_write_reg1(0x05, 0x5d); \
148    __spi_write_reg1(0x0B, 0x81); \
149    __spi_write_reg1(0x01, 0x95); \
150    __spi_write_reg1(0x00, 0x07); \
151    __spi_write_reg1(0x06, 0x15); \
152    __spi_write_reg1(0x07, 0x8d); \
153    __spi_write_reg1(0x04, 0x0f); \
154    __spi_write_reg1(0x0d, 0x3d); \
155    __spi_write_reg1(0x10, 0x42); \
156    __spi_write_reg1(0x11, 0x3a); \
157    __spi_write_reg1(0x05, 0x5f); \
158} while (0)
159
160#define __lcd_special_off() \
161do { \
162    __spi_write_reg1(0x05, 0x5e); \
163} while (0)
164
165#define __lcd_display_pin_init() \
166do { \
167    __lcd_special_pin_init();\
168    __gpio_as_pwm();\
169    __lcd_set_backlight_level(8);\
170} while (0)
171
172#define __lcd_display_on() \
173do { \
174    __lcd_set_backlight_level(8); \
175    __lcd_special_on();\
176} while (0)
177
178#define __lcd_display_off() \
179do { \
180    __lcd_set_backlight_level(0); \
181    __lcd_special_off();\
182} while (0)
183
184#define __lcd_set_backlight_level(n)\
185do { \
186    __gpio_as_output(LCD_RET); \
187    __gpio_set_pin(LCD_RET); \
188} while (0)
189
190#if defined(CONFIG_SAKC)
191#define __lcd_close_backlight() \
192do { \
193    __gpio_as_output(GPIO_PWM); \
194    __gpio_clear_pin(GPIO_PWM); \
195} while (0)
196#endif
197
198#if defined(CONFIG_SAKC)
199#define __lcd_display_pin_init() \
200do { \
201    __cpm_start_tcu(); \
202    __lcd_special_pin_init(); \
203} while (0)
204
205#define __lcd_display_on() \
206do { \
207    __lcd_special_on(); \
208} while (0)
209
210#define __lcd_display_off() \
211do { \
212    __lcd_special_off(); \
213} while (0)
214#else
215#define __lcd_display_pin_init() \
216do { \
217    __cpm_start_tcu(); \
218    __lcd_special_pin_init(); \
219} while (0)
220
221#define __lcd_display_on() \
222do { \
223    __gpio_set_pin(GPIO_DISP_OFF_N); \
224    __lcd_special_on(); \
225} while (0)
226
227#define __lcd_display_off() \
228do { \
229    __lcd_special_off(); \
230    __gpio_clear_pin(GPIO_DISP_OFF_N); \
231} while (0)
232#endif
233
234#endif /* __QI_LB60_GPM940B0_H__ */
package/boot/uboot-xburst/files/cpu/mips/usb_boot.S
1/*
2 * for jz4740 usb boot
3 *
4 * Copyright (c) 2009 Xiangfu Liu <xiangfu.z@gmail.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24    .set noreorder
25    .globl usb_boot
26    .text
27
28//----------------------------------------------------------------------
29// Both NAND and USB boot load data to D-Cache first, then transfer
30// data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
31// So init caches first and then dispatch to a proper boot routine.
32//----------------------------------------------------------------------
33
34.macro load_addr reg addr
35    li \reg, 0x80000000
36    addiu \reg, \reg, \addr
37    la $2, usbboot_begin
38    subu \reg, \reg, $2
39.endm
40
41usb_boot:
42    //--------------------------------------------------------------
43    // Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz.
44    //--------------------------------------------------------------
45    la $9, 0xB0000000 // CPCCR: Clock Control Register
46    la $8, 0x42041110 // I:S:M:P=1:2:2:2
47    sw $8, 0($9)
48
49    la $9, 0xB0000010 // CPPCR: PLL Control Register
50    la $8, 0x06000120 // M=12 N=0 D=0 CLK=12*(M+2)/(N+2)
51    sw $8, 0($9)
52
53    mtc0 $0, $26 // CP0_ERRCTL, restore WST reset state
54    nop
55
56    mtc0 $0, $16 // CP0_CONFIG
57    nop
58
59    // Relocate code to beginning of the ram
60
61    la $2, usbboot_begin
62    la $3, usbboot_end
63    li $4, 0x80000000
64
651:
66    lw $5, 0($2)
67    sw $5, 0($4)
68    addiu $2, $2, 4
69    bne $2, $3, 1b
70    addiu $4, $4, 4
71
72    li $2, 0x80000000
73    ori $3, $2, 0
74    addiu $3, $3, usbboot_end
75    la $4, usbboot_begin
76    subu $3, $3, $4
77
78
792:
80    cache 0x0, 0($2) // Index_Invalidate_I
81    cache 0x1, 0($2) // Index_Writeback_Inv_D
82    addiu $2, $2, 32
83    subu $4, $3, $2
84    bgtz $4, 2b
85    nop
86
87    load_addr $3, usb_boot_return
88
89    jr $3
90
91usbboot_begin:
92
93init_caches:
94    li $2, 3 // cacheable for kseg0 access
95    mtc0 $2, $16 // CP0_CONFIG
96    nop
97
98    li $2, 0x20000000 // enable idx-store-data cache insn
99    mtc0 $2, $26 // CP0_ERRCTL
100
101    ori $2, $28, 0 // start address
102    ori $3, $2, 0x3fe0 // end address, total 16KB
103    mtc0 $0, $28, 0 // CP0_TAGLO
104    mtc0 $0, $28, 1 // CP0_DATALO
105cache_clear_a_line:
106    cache 0x8, 0($2) // Index_Store_Tag_I
107    cache 0x9, 0($2) // Index_Store_Tag_D
108    bne $2, $3, cache_clear_a_line
109    addiu $2, $2, 32 // increment CACHE_LINE_SIZE
110
111    ori $2, $28, 0 // start address
112    ori $3, $2, 0x3fe0 // end address, total 16KB
113    la $4, 0x1ffff000 // physical address and 4KB page mask
114cache_alloc_a_line:
115    and $5, $2, $4
116    ori $5, $5, 1 // V bit of the physical tag
117    mtc0 $5, $28, 0 // CP0_TAGLO
118    cache 0x8, 0($2) // Index_Store_Tag_I
119    cache 0x9, 0($2) // Index_Store_Tag_D
120    bne $2, $3, cache_alloc_a_line
121    addiu $2, $2, 32 // increment CACHE_LINE_SIZE
122
123    nop
124    nop
125    nop
126    //--------------------------------------------------------------
127    // Transfer data from dcache to icache, then jump to icache.
128    //
129    // Input parameters:
130    //
131    // $19: data length in bytes
132    // $20: jump target address
133    //--------------------------------------------------------------
134xfer_d2i:
135
136    ori $8, $20, 0
137    addu $9, $8, $19 // total 16KB
138
1391:
140    cache 0x0, 0($8) // Index_Invalidate_I
141    cache 0x1, 0($8) // Index_Writeback_Inv_D
142    bne $8, $9, 1b
143    addiu $8, $8, 32
144
145    // flush write-buffer
146    sync
147
148    // Invalidate BTB
149    mfc0 $8, $16, 7 // CP0_CONFIG
150    nop
151    ori $8, 2
152    mtc0 $8, $16, 7
153    nop
154
155    // Overwrite config to disable ram initalisation
156    li $2, 0xff
157    sb $2, 20($20)
158
159    jalr $20
160    nop
161
162icache_return:
163    //--------------------------------------------------------------
164    // User code can return to here after executing itself in
165    // icache, by jumping to $31.
166    //--------------------------------------------------------------
167    b usb_boot_return
168    nop
169
170
171usb_boot_return:
172    //--------------------------------------------------------------
173    // Enable the USB PHY
174    //--------------------------------------------------------------
175    la $9, 0xB0000024 // CPM_SCR
176    lw $8, 0($9)
177    ori $8, 0x40 // USBPHY_ENABLE
178    sw $8, 0($9)
179
180    //--------------------------------------------------------------
181    // Initialize USB registers
182    //--------------------------------------------------------------
183    la $27, 0xb3040000 // USB registers base address
184
185    sb $0, 0x0b($27) // INTRUSBE: disable common USB interrupts
186    sh $0, 0x06($27) // INTRINE: disable EPIN interrutps
187    sh $0, 0x08($27) // INTROUTE: disable EPOUT interrutps
188
189    li $9, 0x61
190    sb $9, 0x01($27) // POWER: HSENAB | SUSPENDM | SOFTCONN
191
192    //--------------------------------------------------------------
193    // Initialize USB states
194    //--------------------------------------------------------------
195    li $22, 0 // set EP0 to IDLE state
196    li $23, 1 // no data stage
197
198    //--------------------------------------------------------------
199    // Main loop of polling the usb commands
200    //--------------------------------------------------------------
201usb_command_loop:
202    lbu $9, 0x0a($27) // read INTRUSB
203    andi $9, 0x04 // check USB_INTR_RESET
204    beqz $9, check_intr_ep0in
205    nop
206
207    //--------------------------------------------------------------
208     // 1. Handle USB reset interrupt
209    //--------------------------------------------------------------
210handle_reset_intr:
211    lbu $9, 0x01($27) // read POWER
212    andi $9, 0x10 // test HS_MODE
213    bnez $9, _usb_set_maxpktsize
214    li $9, 512 // max packet size of HS mode
215    li $9, 64 // max packet size of FS mode
216
217_usb_set_maxpktsize:
218    li $8, 1
219    sb $8, 0x0e($27) // set INDEX 1
220
221    sh $9, 0x10($27) // INMAXP
222    sb $0, 0x13($27) // INCSRH
223    sh $9, 0x14($27) // OUTMAXP
224    sb $0, 0x17($27) // OUTCSRH
225
226_usb_flush_fifo:
227    li $8, 0x48 // INCSR_CDT && INCSR_FF
228    sb $8, 0x12($27) // INCSR
229    li $8, 0x90 // OUTCSR_CDT && OUTCSR_FF
230    sb $8, 0x16($27) // OUTCSR
231
232    li $22, 0 // set EP0 to IDLE state
233    li $23, 1 // no data stage
234
235    //--------------------------------------------------------------
236    // 2. Check and handle EP0 interrupt
237    //--------------------------------------------------------------
238check_intr_ep0in:
239    lhu $10, 0x02($27) // read INTRIN
240    andi $9, $10, 0x1 // check EP0 interrupt
241    beqz $9, check_intr_ep1in
242    nop
243
244handle_ep0_intr:
245    sb $0, 0x0e($27) // set INDEX 0
246    lbu $11, 0x12($27) // read CSR0
247
248    andi $9, $11, 0x04 // check SENTSTALL
249    beqz $9, _ep0_setupend
250    nop
251
252_ep0_sentstall:
253    andi $9, $11, 0xdb
254    sb $9, 0x12($27) // clear SENDSTALL and SENTSTALL
255    li $22, 0 // set EP0 to IDLE state
256
257_ep0_setupend:
258    andi $9, $11, 0x10 // check SETUPEND
259    beqz $9, ep0_idle_state
260    nop
261
262    ori $9, $11, 0x80
263    sb $9, 0x12($27) // set SVDSETUPEND
264    li $22, 0 // set EP0 to IDLE state
265
266ep0_idle_state:
267    bnez $22, ep0_tx_state
268    nop
269
270    //--------------------------------------------------------------
271    // 2.1 Handle EP0 IDLE state interrupt
272    //--------------------------------------------------------------
273    andi $9, $11, 0x01 // check OUTPKTRDY
274    beqz $9, check_intr_ep1in
275    nop
276
277    //--------------------------------------------------------------
278    // Read 8-bytes setup packet from the FIFO
279    //--------------------------------------------------------------
280    lw $25, 0x20($27) // first word of setup packet
281    lw $26, 0x20($27) // second word of setup packet
282
283    andi $9, $25, 0x60 // bRequestType & USB_TYPE_MASK
284    beqz $9, _ep0_std_req
285    nop
286
287    //--------------------------------------------------------------
288    // 2.1.1 Vendor-specific setup request
289    //--------------------------------------------------------------
290_ep0_vend_req:
291    li $22, 0 // set EP0 to IDLE state
292    li $23, 1 // NoData = 1
293
294    andi $9, $25, 0xff00 // check bRequest
295    srl $9, $9, 8
296    beqz $9, __ep0_get_cpu_info
297    sub $8, $9, 0x1
298    beqz $8, __ep0_set_data_address
299    sub $8, $9, 0x2
300    beqz $8, __ep0_set_data_length
301    sub $8, $9, 0x3
302    beqz $8, __ep0_flush_caches
303    sub $8, $9, 0x4
304    beqz $8, __ep0_prog_start1
305    sub $8, $9, 0x5
306    beqz $8, __ep0_prog_start2
307    nop
308    b _ep0_idle_state_fini // invalid request
309    nop
310
311__ep0_get_cpu_info:
312    load_addr $20, cpu_info_data // data pointer to transfer
313    li $21, 8 // bytes left to transfer
314    li $22, 1 // set EP0 to TX state
315    li $23, 0 // NoData = 0
316
317    b _ep0_idle_state_fini
318    nop
319
320__ep0_set_data_address:
321    li $9, 0xffff0000
322    and $9, $25, $9
323    andi $8, $26, 0xffff
324    or $20, $9, $8 // data address of next transfer
325
326    b _ep0_idle_state_fini
327    nop
328
329__ep0_set_data_length:
330    li $9, 0xffff0000
331    and $9, $25, $9
332    andi $8, $26, 0xffff
333    or $21, $9, $8 // data length of next transfer
334
335    li $9, 0x48 // SVDOUTPKTRDY and DATAEND
336    sb $9, 0x12($27) // CSR0
337
338    // We must write packet to FIFO before EP1-IN interrupt here.
339    b handle_epin1_intr
340    nop
341
342__ep0_flush_caches:
343    // Flush dcache and invalidate icache.
344    li $8, 0x80000000
345    addi $9, $8, 0x3fe0 // total 16KB
346
3471:
348    cache 0x0, 0($8) // Index_Invalidate_I
349    cache 0x1, 0($8) // Index_Writeback_Inv_D
350    bne $8, $9, 1b
351    addiu $8, $8, 32
352
353    // flush write-buffer
354    sync
355
356    // Invalidate BTB
357    mfc0 $8, $16, 7 // CP0_CONFIG
358    nop
359    ori $8, 2
360    mtc0 $8, $16, 7
361    nop
362
363    b _ep0_idle_state_fini
364    nop
365
366__ep0_prog_start1:
367    li $9, 0x48 // SVDOUTPKTRDY and DATAEND
368    sb $9, 0x12($27) // CSR0
369
370    li $9, 0xffff0000
371    and $9, $25, $9
372    andi $8, $26, 0xffff
373    or $20, $9, $8 // target address
374
375    b xfer_d2i
376    li $19, 0x2000 // 16KB data length
377
378__ep0_prog_start2:
379    li $9, 0x48 // SVDOUTPKTRDY and DATAEND
380    sb $9, 0x12($27) // CSR0
381
382    li $9, 0xffff0000
383    and $9, $25, $9
384    andi $8, $26, 0xffff
385    or $20, $9, $8 // target address
386
387    jalr $20 // jump, and place the return address in $31
388    nop
389
390__ep0_prog_start2_return:
391    // User code can return to here after executing itself, by jumping to $31.
392    b usb_boot_return
393    nop
394
395    //--------------------------------------------------------------
396    // 2.1.2 Standard setup request
397    //--------------------------------------------------------------
398_ep0_std_req:
399    andi $12, $25, 0xff00 // check bRequest
400    srl $12, $12, 8
401    sub $9, $12, 0x05 // check USB_REQ_SET_ADDRESS
402    bnez $9, __ep0_req_set_config
403    nop
404
405    //--------------------------------------------------------------
406    // Handle USB_REQ_SET_ADDRESS
407    //--------------------------------------------------------------
408__ep0_req_set_addr:
409    srl $9, $25, 16 // get wValue
410    sb $9, 0x0($27) // set FADDR
411    li $23, 1 // NoData = 1
412    b _ep0_idle_state_fini
413    nop
414
415__ep0_req_set_config:
416    sub $9, $12, 0x09 // check USB_REQ_SET_CONFIGURATION
417    bnez $9, __ep0_req_get_desc
418    nop
419
420    //--------------------------------------------------------------
421    // Handle USB_REQ_SET_CONFIGURATION
422    //--------------------------------------------------------------
423    li $23, 1 // NoData = 1
424    b _ep0_idle_state_fini
425    nop
426
427__ep0_req_get_desc:
428    sub $9, $12, 0x06 // check USB_REQ_GET_DESCRIPTOR
429    bnez $9, _ep0_idle_state_fini
430    li $23, 1 // NoData = 1
431
432    //--------------------------------------------------------------
433    // Handle USB_REQ_GET_DESCRIPTOR
434    //--------------------------------------------------------------
435    li $23, 0 // NoData = 0
436
437    srl $9, $25, 24 // wValue >> 8
438    sub $8, $9, 0x01 // check USB_DT_DEVICE
439    beqz $8, ___ep0_get_dev_desc
440    srl $21, $26, 16 // get wLength
441    sub $8, $9, 0x02 // check USB_DT_CONFIG
442    beqz $8, ___ep0_get_conf_desc
443    sub $8, $9, 0x03 // check USB_DT_STRING
444    beqz $8, ___ep0_get_string_desc
445    sub $8, $9, 0x06 // check USB_DT_DEVICE_QUALIFIER
446    beqz $8, ___ep0_get_dev_qualifier
447    nop
448    b _ep0_idle_state_fini
449    nop
450
451___ep0_get_dev_desc:
452    load_addr $20, device_desc // data pointer
453    li $22, 1 // set EP0 to TX state
454    sub $8, $21, 18
455    blez $8, _ep0_idle_state_fini // wLength <= 18
456    nop
457    li $21, 18 // max length of device_desc
458    b _ep0_idle_state_fini
459    nop
460
461___ep0_get_dev_qualifier:
462    load_addr $20, dev_qualifier // data pointer
463    li $22, 1 // set EP0 to TX state
464    sub $8, $21, 10
465    blez $8, _ep0_idle_state_fini // wLength <= 10
466    nop
467    li $21, 10 // max length of dev_qualifier
468    b _ep0_idle_state_fini
469    nop
470
471___ep0_get_conf_desc:
472    load_addr $20, config_desc_fs // data pointer of FS mode
473    lbu $8, 0x01($27) // read POWER
474    andi $8, 0x10 // test HS_MODE
475    beqz $8, ___ep0_get_conf_desc2
476    nop
477    load_addr $20, config_desc_hs // data pointer of HS mode
478
479___ep0_get_conf_desc2:
480    li $22, 1 // set EP0 to TX state
481    sub $8, $21, 32
482    blez $8, _ep0_idle_state_fini // wLength <= 32
483    nop
484    li $21, 32 // max length of config_desc
485    b _ep0_idle_state_fini
486    nop
487
488___ep0_get_string_desc:
489    li $22, 1 // set EP0 to TX state
490
491    srl $9, $25, 16 // wValue & 0xff
492    andi $9, 0xff
493
494    sub $8, $9, 1
495    beqz $8, ___ep0_get_string_manufacture
496    sub $8, $9, 2
497    beqz $8, ___ep0_get_string_product
498    nop
499
500___ep0_get_string_lang_ids:
501    load_addr $20, string_lang_ids // data pointer
502    b _ep0_idle_state_fini
503    li $21, 4 // data length
504
505___ep0_get_string_manufacture:
506    load_addr $20, string_manufacture // data pointer
507    b _ep0_idle_state_fini
508    li $21, 16 // data length
509
510___ep0_get_string_product:
511    load_addr $20, string_product // data pointer
512    b _ep0_idle_state_fini
513    li $21, 46 // data length
514
515_ep0_idle_state_fini:
516    li $9, 0x40 // SVDOUTPKTRDY
517    beqz $23, _ep0_idle_state_fini2
518    nop
519    ori $9, $9, 0x08 // DATAEND
520_ep0_idle_state_fini2:
521    sb $9, 0x12($27) // CSR0
522    beqz $22, check_intr_ep1in
523    nop
524
525    //--------------------------------------------------------------
526    // 2.2 Handle EP0 TX state interrupt
527    //--------------------------------------------------------------
528ep0_tx_state:
529    sub $9, $22, 1
530    bnez $9, check_intr_ep1in
531    nop
532
533    sub $9, $21, 64 // max packetsize
534    blez $9, _ep0_tx_state2 // data count <= 64
535    ori $19, $21, 0
536    li $19, 64
537
538_ep0_tx_state2:
539    beqz $19, _ep0_tx_state3 // send ZLP
540    ori $18, $19, 0 // record bytes to be transferred
541    sub $21, $21, $19 // decrement data count
542
543_ep0_fifo_write_loop:
544    lbu $9, 0($20) // read data
545    sb $9, 0x20($27) // load FIFO
546    sub $19, $19, 1 // decrement counter
547    bnez $19, _ep0_fifo_write_loop
548    addi $20, $20, 1 // increment data pointer
549
550    sub $9, $18, 64 // max packetsize
551    beqz $9, _ep0_tx_state4
552    nop
553
554_ep0_tx_state3:
555    // transferred bytes < max packetsize
556    li $9, 0x0a // set INPKTRDY and DATAEND
557    sb $9, 0x12($27) // CSR0
558    li $22, 0 // set EP0 to IDLE state
559    b check_intr_ep1in
560    nop
561
562_ep0_tx_state4:
563    // transferred bytes == max packetsize
564    li $9, 0x02 // set INPKTRDY
565    sb $9, 0x12($27) // CSR0
566    b check_intr_ep1in
567    nop
568
569    //--------------------------------------------------------------
570    // 3. Check and handle EP1 BULK-IN interrupt
571    //--------------------------------------------------------------
572check_intr_ep1in:
573    andi $9, $10, 0x2 // check EP1 IN interrupt
574    beqz $9, check_intr_ep1out
575    nop
576
577handle_epin1_intr:
578    li $9, 1
579    sb $9, 0x0e($27) // set INDEX 1
580    lbu $9, 0x12($27) // read INCSR
581
582    andi $8, $9, 0x2 // check INCSR_FFNOTEMPT
583    bnez $8, _epin1_tx_state4
584    nop
585
586_epin1_write_fifo:
587    lhu $9, 0x10($27) // get INMAXP
588    sub $8, $21, $9
589    blez $8, _epin1_tx_state1 // bytes left <= INMAXP
590    ori $19, $21, 0
591    ori $19, $9, 0
592
593_epin1_tx_state1:
594    beqz $19, _epin1_tx_state4 // No data
595    nop
596
597    sub $21, $21, $19 // decrement data count
598
599    srl $5, $19, 2 // # of word
600    andi $6, $19, 0x3 // # of byte
601    beqz $5, _epin1_tx_state2
602    nop
603
604_epin1_fifo_write_word:
605    lw $9, 0($20) // read data from source address
606    sw $9, 0x24($27) // write FIFO
607    sub $5, $5, 1 // decrement counter
608    bnez $5, _epin1_fifo_write_word
609    addiu $20, $20, 4 // increment dest address
610
611_epin1_tx_state2:
612    beqz $6, _epin1_tx_state3
613    nop
614
615_epin1_fifo_write_byte:
616    lbu $9, 0($20) // read data from source address
617    sb $9, 0x24($27) // write FIFO
618    sub $6, $6, 1 // decrement counter
619    bnez $6, _epin1_fifo_write_byte
620    addiu $20, $20, 1 // increment dest address
621
622_epin1_tx_state3:
623    li $9, 0x1
624    sb $9, 0x12($27) // INCSR, set INPKTRDY
625
626_epin1_tx_state4:
627    // nop
628
629    //--------------------------------------------------------------
630    // 4. Check and handle EP1 BULK-OUT interrupt
631    //--------------------------------------------------------------
632check_intr_ep1out:
633    lhu $9, 0x04($27) // read INTROUT
634    andi $9, 0x2
635    beqz $9, check_status_next
636    nop
637
638handle_epout1_intr:
639    li $9, 1
640    sb $9, 0x0e($27) // set INDEX 1
641
642    lbu $9, 0x16($27) // read OUTCSR
643    andi $9, 0x1 // check OUTPKTRDY
644    beqz $9, check_status_next
645    nop
646
647_epout1_read_fifo:
648    lhu $19, 0x18($27) // read OUTCOUNT
649    srl $5, $19, 2 // # of word
650    andi $6, $19, 0x3 // # of byte
651    beqz $5, _epout1_rx_state1
652    nop
653
654_epout1_fifo_read_word:
655    lw $9, 0x24($27) // read FIFO
656    sw $9, 0($20) // store to dest address
657    sub $5, $5, 1 // decrement counter
658    bnez $5, _epout1_fifo_read_word
659    addiu $20, $20, 4 // increment dest address
660
661_epout1_rx_state1:
662    beqz $6, _epout1_rx_state2
663    nop
664
665_epout1_fifo_read_byte:
666    lbu $9, 0x24($27) // read FIFO
667    sb $9, 0($20) // store to dest address
668    sub $6, $6, 1 // decrement counter
669    bnez $6, _epout1_fifo_read_byte
670    addiu $20, $20, 1 // increment dest address
671
672_epout1_rx_state2:
673    sb $0, 0x16($27) // clear OUTPKTRDY
674
675check_status_next:
676    b usb_command_loop
677    nop
678
679//--------------------------------------------------------------
680// Device/Configuration/Interface/Endpoint/String Descriptors
681//--------------------------------------------------------------
682
683    .align 2
684device_desc:
685    .byte 0x12 // bLength
686    .byte 0x01 // bDescriptorType
687    .byte 0x00 // bcdUSB
688    .byte 0x02 // bcdUSB
689    .byte 0x00 // bDeviceClass
690    .byte 0x00 // bDeviceSubClass
691    .byte 0x00 // bDeviceProtocol
692    .byte 0x40 // bMaxPacketSize0
693    .byte 0x1a // idVendor
694    .byte 0x60 // idVendor
695    .byte 0x40 // idProduct
696    .byte 0x47 // idProduct
697    .byte 0x00 // bcdDevice
698    .byte 0x01 // bcdDevice
699    .byte 0x01 // iManufacturer
700    .byte 0x02 // iProduct
701    .byte 0x00 // iSerialNumber
702    .byte 0x01 // bNumConfigurations
703
704    .align 2
705dev_qualifier:
706    .byte 0x0a // bLength
707    .byte 0x06 // bDescriptorType
708    .byte 0x00 // bcdUSB
709    .byte 0x02 // bcdUSB
710    .byte 0x00 // bDeviceClass
711    .byte 0x00 // bDeviceSubClass
712    .byte 0x00 // bDeviceProtocol
713    .byte 0x40 // bMaxPacketSize0
714    .byte 0x01 // bNumConfigurations
715    .byte 0x00 // bRESERVED
716
717    .align 2
718config_desc_hs:
719    .byte 0x09 // bLength
720    .byte 0x02 // bDescriptorType
721    .byte 0x20 // wTotalLength
722    .byte 0x00 // wTotalLength
723    .byte 0x01 // bNumInterfaces
724    .byte 0x01 // bConfigurationValue
725    .byte 0x00 // iConfiguration
726    .byte 0xc0 // bmAttributes
727    .byte 0x01 // MaxPower
728intf_desc_hs:
729    .byte 0x09 // bLength
730    .byte 0x04 // bDescriptorType
731    .byte 0x00 // bInterfaceNumber
732    .byte 0x00 // bAlternateSetting
733    .byte 0x02 // bNumEndpoints
734    .byte 0xff // bInterfaceClass
735    .byte 0x00 // bInterfaceSubClass
736    .byte 0x50 // bInterfaceProtocol
737    .byte 0x00 // iInterface
738ep1_desc_hs:
739    .byte 0x07 // bLength
740    .byte 0x05 // bDescriptorType
741    .byte 0x01 // bEndpointAddress
742    .byte 0x02 // bmAttributes
743    .byte 0x00 // wMaxPacketSize
744    .byte 0x02 // wMaxPacketSize
745    .byte 0x00 // bInterval
746ep2_desc_hs:
747    .byte 0x07 // bLength
748    .byte 0x05 // bDescriptorType
749    .byte 0x81 // bEndpointAddress
750    .byte 0x02 // bmAttributes
751    .byte 0x00 // wMaxPacketSize
752    .byte 0x02 // wMaxPacketSize
753    .byte 0x00 // bInterval
754
755    .align 2
756config_desc_fs:
757    .byte 0x09 // bLength
758    .byte 0x02 // bDescriptorType
759    .byte 0x20 // wTotalLength
760    .byte 0x00 // wTotalLength
761    .byte 0x01 // bNumInterfaces
762    .byte 0x01 // bConfigurationValue
763    .byte 0x00 // iConfiguration
764    .byte 0xc0 // bmAttributes
765    .byte 0x01 // MaxPower
766intf_desc_fs:
767    .byte 0x09 // bLength
768    .byte 0x04 // bDescriptorType
769    .byte 0x00 // bInterfaceNumber
770    .byte 0x00 // bAlternateSetting
771    .byte 0x02 // bNumEndpoints
772    .byte 0xff // bInterfaceClass
773    .byte 0x00 // bInterfaceSubClass
774    .byte 0x50 // bInterfaceProtocol
775    .byte 0x00 // iInterface
776ep1_desc_fs:
777    .byte 0x07 // bLength
778    .byte 0x05 // bDescriptorType
779    .byte 0x01 // bEndpointAddress
780    .byte 0x02 // bmAttributes
781    .byte 0x40 // wMaxPacketSize
782    .byte 0x00 // wMaxPacketSize
783    .byte 0x00 // bInterval
784ep2_desc_fs:
785    .byte 0x07 // bLength
786    .byte 0x05 // bDescriptorType
787    .byte 0x81 // bEndpointAddress
788    .byte 0x02 // bmAttributes
789    .byte 0x40 // wMaxPacketSize
790    .byte 0x00 // wMaxPacketSize
791    .byte 0x00 // bInterval
792
793    .align 2
794string_lang_ids:
795    .byte 0x04
796    .byte 0x03
797    .byte 0x09
798    .byte 0x04
799
800    .align 2
801string_manufacture:
802    .byte 0x10
803    .byte 0x03
804    .byte 0x49
805    .byte 0x00
806    .byte 0x6e
807    .byte 0x00
808    .byte 0x67
809    .byte 0x00
810    .byte 0x65
811    .byte 0x00
812    .byte 0x6e
813    .byte 0x00
814    .byte 0x69
815    .byte 0x00
816    .byte 0x63
817    .byte 0x00
818
819    .align 2
820string_product:
821    .byte 0x2e
822    .byte 0x03
823    .byte 0x4a
824    .byte 0x00
825    .byte 0x5a
826    .byte 0x00
827    .byte 0x34
828    .byte 0x00
829    .byte 0x37
830    .byte 0x00
831    .byte 0x34
832    .byte 0x00
833    .byte 0x30
834    .byte 0x00
835    .byte 0x20
836    .byte 0x00
837    .byte 0x55
838    .byte 0x00
839    .byte 0x53
840    .byte 0x00
841    .byte 0x42
842    .byte 0x00
843    .byte 0x20
844    .byte 0x00
845    .byte 0x42
846    .byte 0x00
847    .byte 0x6f
848    .byte 0x00
849    .byte 0x6f
850    .byte 0x00
851    .byte 0x74
852    .byte 0x00
853    .byte 0x20
854    .byte 0x00
855    .byte 0x44
856    .byte 0x00
857    .byte 0x65
858    .byte 0x00
859    .byte 0x76
860    .byte 0x00
861    .byte 0x69
862    .byte 0x00
863    .byte 0x63
864    .byte 0x00
865    .byte 0x65
866    .byte 0x00
867
868    .align 2
869cpu_info_data:
870    .byte 0x4a
871    .byte 0x5a
872    .byte 0x34
873    .byte 0x37
874    .byte 0x34
875    .byte 0x30
876    .byte 0x56
877    .byte 0x31
878usbboot_end:
879
880    .set reorder
package/boot/uboot-xburst/files/include/asm-mips/jz4740.h
1/*
2 * Include file for Ingenic Semiconductor's JZ4740 CPU.
3 */
4#ifndef __JZ4740_H__
5#define __JZ4740_H__
6
7#ifndef __ASSEMBLY__
8#define UCOS_CSP 0
9
10#if UCOS_CSP
11#define __KERNEL__
12#include <bsp.h>
13#include <types.h>
14
15#include <sysdefs.h>
16#include <cacheops.h>
17#define KSEG0 KSEG0BASE
18#else
19#include <asm/addrspace.h>
20#include <asm/cacheops.h>
21#endif
22
23#define cache_unroll(base,op) \
24    __asm__ __volatile__(" \
25        .set noreorder; \
26        .set mips3; \
27        cache %1, (%0); \
28        .set mips0; \
29        .set reorder" \
30        : \
31        : "r" (base), \
32          "i" (op));
33
34static inline void jz_flush_dcache(void)
35{
36    unsigned long start;
37    unsigned long end;
38
39    start = KSEG0;
40    end = start + CONFIG_SYS_DCACHE_SIZE;
41    while (start < end) {
42        cache_unroll(start,Index_Writeback_Inv_D);
43        start += CONFIG_SYS_CACHELINE_SIZE;
44    }
45}
46
47static inline void jz_flush_icache(void)
48{
49    unsigned long start;
50    unsigned long end;
51
52    start = KSEG0;
53    end = start + CONFIG_SYS_ICACHE_SIZE;
54    while(start < end) {
55        cache_unroll(start,Index_Invalidate_I);
56        start += CONFIG_SYS_CACHELINE_SIZE;
57    }
58}
59
60/* cpu pipeline flush */
61static inline void jz_sync(void)
62{
63    __asm__ volatile ("sync");
64}
65
66static inline void jz_writeb(u32 address, u8 value)
67{
68    *((volatile u8 *)address) = value;
69}
70
71static inline void jz_writew(u32 address, u16 value)
72{
73    *((volatile u16 *)address) = value;
74}
75
76static inline void jz_writel(u32 address, u32 value)
77{
78    *((volatile u32 *)address) = value;
79}
80
81static inline u8 jz_readb(u32 address)
82{
83    return *((volatile u8 *)address);
84}
85
86static inline u16 jz_readw(u32 address)
87{
88    return *((volatile u16 *)address);
89}
90
91static inline u32 jz_readl(u32 address)
92{
93    return *((volatile u32 *)address);
94}
95
96#define REG8(addr) *((volatile u8 *)(addr))
97#define REG16(addr) *((volatile u16 *)(addr))
98#define REG32(addr) *((volatile u32 *)(addr))
99
100#else
101
102#define REG8(addr) (addr)
103#define REG16(addr) (addr)
104#define REG32(addr) (addr)
105
106#endif /* !ASSEMBLY */
107
108/* Boot ROM Specification */
109/* NOR Boot config */
110#define JZ4740_NORBOOT_8BIT 0x00000000 /* 8-bit data bus flash */
111#define JZ4740_NORBOOT_16BIT 0x10101010 /* 16-bit data bus flash */
112#define JZ4740_NORBOOT_32BIT 0x20202020 /* 32-bit data bus flash */
113
114/* NAND Boot config */
115#define JZ4740_NANDBOOT_B8R3 0xffffffff /* 8-bit bus & 3 row cycles */
116#define JZ4740_NANDBOOT_B8R2 0xf0f0f0f0 /* 8-bit bus & 2 row cycles */
117#define JZ4740_NANDBOOT_B16R3 0x0f0f0f0f /* 16-bit bus & 3 row cycles */
118#define JZ4740_NANDBOOT_B16R2 0x00000000 /* 16-bit bus & 2 row cycles */
119
120
121/* Register Definitions */
122#define CPM_BASE 0xB0000000
123#define INTC_BASE 0xB0001000
124#define TCU_BASE 0xB0002000
125#define WDT_BASE 0xB0002000
126#define RTC_BASE 0xB0003000
127#define GPIO_BASE 0xB0010000
128#define AIC_BASE 0xB0020000
129#define ICDC_BASE 0xB0020000
130#define MSC_BASE 0xB0021000
131#define UART0_BASE 0xB0030000
132#define I2C_BASE 0xB0042000
133#define SSI_BASE 0xB0043000
134#define SADC_BASE 0xB0070000
135#define EMC_BASE 0xB3010000
136#define DMAC_BASE 0xB3020000
137#define UHC_BASE 0xB3030000
138#define UDC_BASE 0xB3040000
139#define LCD_BASE 0xB3050000
140#define SLCD_BASE 0xB3050000
141#define CIM_BASE 0xB3060000
142#define ETH_BASE 0xB3100000
143
144
145/*
146 * INTC (Interrupt Controller)
147 */
148#define INTC_ISR (INTC_BASE + 0x00)
149#define INTC_IMR (INTC_BASE + 0x04)
150#define INTC_IMSR (INTC_BASE + 0x08)
151#define INTC_IMCR (INTC_BASE + 0x0c)
152#define INTC_IPR (INTC_BASE + 0x10)
153
154#define REG_INTC_ISR REG32(INTC_ISR)
155#define REG_INTC_IMR REG32(INTC_IMR)
156#define REG_INTC_IMSR REG32(INTC_IMSR)
157#define REG_INTC_IMCR REG32(INTC_IMCR)
158#define REG_INTC_IPR REG32(INTC_IPR)
159
160/* 1st-level interrupts */
161#define IRQ_I2C 1
162#define IRQ_UHC 3
163#define IRQ_UART0 9
164#define IRQ_SADC 12
165#define IRQ_MSC 14
166#define IRQ_RTC 15
167#define IRQ_SSI 16
168#define IRQ_CIM 17
169#define IRQ_AIC 18
170#define IRQ_ETH 19
171#define IRQ_DMAC 20
172#define IRQ_TCU2 21
173#define IRQ_TCU1 22
174#define IRQ_TCU0 23
175#define IRQ_UDC 24
176#define IRQ_GPIO3 25
177#define IRQ_GPIO2 26
178#define IRQ_GPIO1 27
179#define IRQ_GPIO0 28
180#define IRQ_IPU 29
181#define IRQ_LCD 30
182
183/* 2nd-level interrupts */
184#define IRQ_DMA_0 32 /* 32 to 37 for DMAC channel 0 to 5 */
185#define IRQ_GPIO_0 48 /* 48 to 175 for GPIO pin 0 to 127 */
186
187
188/*
189 * RTC
190 */
191#define RTC_RCR (RTC_BASE + 0x00) /* RTC Control Register */
192#define RTC_RSR (RTC_BASE + 0x04) /* RTC Second Register */
193#define RTC_RSAR (RTC_BASE + 0x08) /* RTC Second Alarm Register */
194#define RTC_RGR (RTC_BASE + 0x0c) /* RTC Regulator Register */
195
196#define RTC_HCR (RTC_BASE + 0x20) /* Hibernate Control Register */
197#define RTC_HWFCR (RTC_BASE + 0x24) /* Hibernate Wakeup Filter Counter Reg */
198#define RTC_HRCR (RTC_BASE + 0x28) /* Hibernate Reset Counter Register */
199#define RTC_HWCR (RTC_BASE + 0x2c) /* Hibernate Wakeup Control Register */
200#define RTC_HWRSR (RTC_BASE + 0x30) /* Hibernate Wakeup Status Register */
201#define RTC_HSPR (RTC_BASE + 0x34) /* Hibernate Scratch Pattern Register */
202
203#define REG_RTC_RCR REG32(RTC_RCR)
204#define REG_RTC_RSR REG32(RTC_RSR)
205#define REG_RTC_RSAR REG32(RTC_RSAR)
206#define REG_RTC_RGR REG32(RTC_RGR)
207#define REG_RTC_HCR REG32(RTC_HCR)
208#define REG_RTC_HWFCR REG32(RTC_HWFCR)
209#define REG_RTC_HRCR REG32(RTC_HRCR)
210#define REG_RTC_HWCR REG32(RTC_HWCR)
211#define REG_RTC_HWRSR REG32(RTC_HWRSR)
212#define REG_RTC_HSPR REG32(RTC_HSPR)
213
214/* RTC Control Register */
215#define RTC_RCR_WRDY (1 << 7) /* Write Ready Flag */
216#define RTC_RCR_HZ (1 << 6) /* 1Hz Flag */
217#define RTC_RCR_HZIE (1 << 5) /* 1Hz Interrupt Enable */
218#define RTC_RCR_AF (1 << 4) /* Alarm Flag */
219#define RTC_RCR_AIE (1 << 3) /* Alarm Interrupt Enable */
220#define RTC_RCR_AE (1 << 2) /* Alarm Enable */
221#define RTC_RCR_RTCE (1 << 0) /* RTC Enable */
222
223/* RTC Regulator Register */
224#define RTC_RGR_LOCK (1 << 31) /* Lock Bit */
225#define RTC_RGR_ADJC_BIT 16
226#define RTC_RGR_ADJC_MASK (0x3ff << RTC_RGR_ADJC_BIT)
227#define RTC_RGR_NC1HZ_BIT 0
228#define RTC_RGR_NC1HZ_MASK (0xffff << RTC_RGR_NC1HZ_BIT)
229
230/* Hibernate Control Register */
231#define RTC_HCR_PD (1 << 0) /* Power Down */
232
233/* Hibernate Wakeup Filter Counter Register */
234#define RTC_HWFCR_BIT 5
235#define RTC_HWFCR_MASK (0x7ff << RTC_HWFCR_BIT)
236
237/* Hibernate Reset Counter Register */
238#define RTC_HRCR_BIT 5
239#define RTC_HRCR_MASK (0x7f << RTC_HRCR_BIT)
240
241/* Hibernate Wakeup Control Register */
242#define RTC_HWCR_EALM (1 << 0) /* RTC alarm wakeup enable */
243
244/* Hibernate Wakeup Status Register */
245#define RTC_HWRSR_HR (1 << 5) /* Hibernate reset */
246#define RTC_HWRSR_PPR (1 << 4) /* PPR reset */
247#define RTC_HWRSR_PIN (1 << 1) /* Wakeup pin status bit */
248#define RTC_HWRSR_ALM (1 << 0) /* RTC alarm status bit */
249
250
251/*************************************************************************
252 * CPM (Clock reset and Power control Management)
253 *************************************************************************/
254#define CPM_CPCCR (CPM_BASE+0x00)
255#define CPM_CPPCR (CPM_BASE+0x10)
256#define CPM_I2SCDR (CPM_BASE+0x60)
257#define CPM_LPCDR (CPM_BASE+0x64)
258#define CPM_MSCCDR (CPM_BASE+0x68)
259#define CPM_UHCCDR (CPM_BASE+0x6C)
260
261#define CPM_LCR (CPM_BASE+0x04)
262#define CPM_CLKGR (CPM_BASE+0x20)
263#define CPM_SCR (CPM_BASE+0x24)
264
265#define CPM_HCR (CPM_BASE+0x30)
266#define CPM_HWFCR (CPM_BASE+0x34)
267#define CPM_HRCR (CPM_BASE+0x38)
268#define CPM_HWCR (CPM_BASE+0x3c)
269#define CPM_HWSR (CPM_BASE+0x40)
270#define CPM_HSPR (CPM_BASE+0x44)
271
272#define CPM_RSR (CPM_BASE+0x08)
273
274
275#define REG_CPM_CPCCR REG32(CPM_CPCCR)
276#define REG_CPM_CPPCR REG32(CPM_CPPCR)
277#define REG_CPM_I2SCDR REG32(CPM_I2SCDR)
278#define REG_CPM_LPCDR REG32(CPM_LPCDR)
279#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
280#define REG_CPM_UHCCDR REG32(CPM_UHCCDR)
281
282#define REG_CPM_LCR REG32(CPM_LCR)
283#define REG_CPM_CLKGR REG32(CPM_CLKGR)
284#define REG_CPM_SCR REG32(CPM_SCR)
285#define REG_CPM_HCR REG32(CPM_HCR)
286#define REG_CPM_HWFCR REG32(CPM_HWFCR)
287#define REG_CPM_HRCR REG32(CPM_HRCR)
288#define REG_CPM_HWCR REG32(CPM_HWCR)
289#define REG_CPM_HWSR REG32(CPM_HWSR)
290#define REG_CPM_HSPR REG32(CPM_HSPR)
291
292#define REG_CPM_RSR REG32(CPM_RSR)
293
294
295/* Clock Control Register */
296#define CPM_CPCCR_I2CS (1 << 31)
297#define CPM_CPCCR_CLKOEN (1 << 30)
298#define CPM_CPCCR_UCS (1 << 29)
299#define CPM_CPCCR_UDIV_BIT 23
300#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT)
301#define CPM_CPCCR_CE (1 << 22)
302#define CPM_CPCCR_PCS (1 << 21)
303#define CPM_CPCCR_LDIV_BIT 16
304#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT)
305#define CPM_CPCCR_MDIV_BIT 12
306#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT)
307#define CPM_CPCCR_PDIV_BIT 8
308#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT)
309#define CPM_CPCCR_HDIV_BIT 4
310#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT)
311#define CPM_CPCCR_CDIV_BIT 0
312#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT)
313
314/* I2S Clock Divider Register */
315#define CPM_I2SCDR_I2SDIV_BIT 0
316#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT)
317
318/* LCD Pixel Clock Divider Register */
319#define CPM_LPCDR_PIXDIV_BIT 0
320#define CPM_LPCDR_PIXDIV_MASK (0x1ff << CPM_LPCDR_PIXDIV_BIT)
321
322/* MSC Clock Divider Register */
323#define CPM_MSCCDR_MSCDIV_BIT 0
324#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT)
325
326/* PLL Control Register */
327#define CPM_CPPCR_PLLM_BIT 23
328#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT)
329#define CPM_CPPCR_PLLN_BIT 18
330#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT)
331#define CPM_CPPCR_PLLOD_BIT 16
332#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT)
333#define CPM_CPPCR_PLLS (1 << 10)
334#define CPM_CPPCR_PLLBP (1 << 9)
335#define CPM_CPPCR_PLLEN (1 << 8)
336#define CPM_CPPCR_PLLST_BIT 0
337#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT)
338
339/* Low Power Control Register */
340#define CPM_LCR_DOZE_DUTY_BIT 3
341#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT)
342#define CPM_LCR_DOZE_ON (1 << 2)
343#define CPM_LCR_LPM_BIT 0
344#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT)
345  #define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT)
346  #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT)
347
348/* Clock Gate Register */
349#define CPM_CLKGR_UART1 (1 << 15)
350#define CPM_CLKGR_UHC (1 << 14)
351#define CPM_CLKGR_IPU (1 << 13)
352#define CPM_CLKGR_DMAC (1 << 12)
353#define CPM_CLKGR_UDC (1 << 11)
354#define CPM_CLKGR_LCD (1 << 10)
355#define CPM_CLKGR_CIM (1 << 9)
356#define CPM_CLKGR_SADC (1 << 8)
357#define CPM_CLKGR_MSC (1 << 7)
358