From fca2f09cdad6a722bf032d1dbbbaa311486acb45 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E6=9E=97=E8=BE=89=E8=BE=89?= Date: Fri, 23 Apr 2010 03:25:06 +0000 Subject: [PATCH] add rk2818 serial and up iomap --- .config | 296 ++------ arch/arm/mach-rk2818/board-midsdk.c | 66 +- arch/arm/mach-rk2818/clock-rk2818.c | 2 +- arch/arm/mach-rk2818/devices.c | 64 +- arch/arm/mach-rk2818/include/mach/irqs.h | 16 +- .../mach-rk2818/include/mach/rk2818_iomap.h | 20 - arch/arm/mach-rk2818/timer.c | 19 +- drivers/serial/Kconfig | 12 + drivers/serial/Makefile | 2 + drivers/serial/rk2818_serial.c | 670 ++++++++++++++++++ drivers/serial/rk2818_serial.h | 122 ++++ include/linux/serial_core.h | 2 + 12 files changed, 968 insertions(+), 323 deletions(-) create mode 100644 drivers/serial/rk2818_serial.c create mode 100644 drivers/serial/rk2818_serial.h diff --git a/.config b/.config index 33d630c01c18..5c8597749bf2 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.32.9 -# Tue Apr 20 14:32:55 2010 +# Fri Apr 23 10:59:03 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -79,7 +79,6 @@ CONFIG_EMBEDDED=y CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -321,77 +320,13 @@ CONFIG_NET=y # # Networking options # -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE=y -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y -CONFIG_IPV6_SIT=y -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set +# CONFIG_PACKET is not set +# CONFIG_UNIX is not set +# CONFIG_NET_KEY is not set +# CONFIG_INET is not set CONFIG_ANDROID_PARANOID_NETWORK=y -CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_NET_DSA is not set @@ -402,63 +337,10 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_PHONET is not set # CONFIG_IEEE802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=y -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -CONFIG_NET_SCH_INGRESS=y - -# -# Classification -# -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_CGROUP is not set -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_NBYTE is not set -CONFIG_NET_EMATCH_U32=y -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_TEXT is not set -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -CONFIG_NET_ACT_GACT=y -# CONFIG_GACT_PROB is not set -CONFIG_NET_ACT_MIRRED=y -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_SCH_FIFO=y +# CONFIG_NET_SCHED is not set # CONFIG_DCB is not set # @@ -468,32 +350,11 @@ CONFIG_NET_SCH_FIFO=y # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -# CONFIG_BT_BNEP_MC_FILTER is not set -# CONFIG_BT_BNEP_PROTO_FILTER is not set -CONFIG_BT_HIDP=y - -# -# Bluetooth device drivers -# -# CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_BCSP is not set -CONFIG_BT_HCIUART_LL=y -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_MRVL is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y +# CONFIG_BT is not set CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set CONFIG_CFG80211_DEFAULT_PS_VALUE=0 -CONFIG_WIRELESS_OLD_REGULATORY=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y # CONFIG_LIB80211 is not set @@ -502,10 +363,7 @@ CONFIG_WIRELESS_EXT_SYSFS=y # CFG80211 needs to be enabled for MAC80211 # # CONFIG_WIMAX is not set -CONFIG_RFKILL=y -# CONFIG_RFKILL_PM is not set -CONFIG_RFKILL_LEDS=y -# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # @@ -522,8 +380,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set @@ -543,7 +399,6 @@ CONFIG_ANDROID_PMEM=y CONFIG_KERNEL_DEBUGGER_CORE=y # CONFIG_ISL29003 is not set CONFIG_UID_STAT=y -# CONFIG_WL127X_RFKILL is not set # CONFIG_APANIC is not set # CONFIG_C2PORT is not set @@ -577,33 +432,12 @@ CONFIG_DM_CRYPT=y # CONFIG_DM_DELAY is not set CONFIG_DM_UEVENT=y CONFIG_NETDEVICES=y -CONFIG_IFB=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -CONFIG_SMC91X=y -# CONFIG_DM9000 is not set -# CONFIG_ETHOC is not set -# CONFIG_SMC911X is not set -# CONFIG_SMSC911X is not set -# CONFIG_DNET is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_B44 is not set -# CONFIG_KS8842 is not set -# CONFIG_KS8851_MLL is not set +# CONFIG_NET_ETHERNET is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y CONFIG_WLAN=y @@ -614,20 +448,8 @@ CONFIG_WLAN=y # Enable WiMAX (Networking options) to see the WiMAX drivers # # CONFIG_WAN is not set -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_MPPE=y -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y +# CONFIG_PPP is not set # CONFIG_SLIP is not set -CONFIG_SLHC=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -696,8 +518,12 @@ CONFIG_INPUT_GPIO=y # # Character devices # -# CONFIG_VT is not set -# CONFIG_DEVMEM is not set +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVMEM=y # CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -709,11 +535,16 @@ CONFIG_INPUT_GPIO=y # # Non-8250 serial port support # -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_RK2818=y +CONFIG_SERIAL_RK2818_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set @@ -828,7 +659,6 @@ CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_COMMON=y # CONFIG_VIDEO_ALLOW_V4L1 is not set CONFIG_VIDEO_V4L1_COMPAT=y -# CONFIG_DVB_CORE is not set CONFIG_VIDEO_MEDIA=y # @@ -908,6 +738,13 @@ CONFIG_FB=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set # CONFIG_LOGO is not set # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y @@ -918,8 +755,6 @@ CONFIG_HID=y # # Special HID drivers # -# CONFIG_HID_APPLE is not set -# CONFIG_HID_WACOM is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -934,7 +769,6 @@ CONFIG_USB_ARCH_HAS_HCD=y # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=500 @@ -945,13 +779,13 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set # CONFIG_USB_GADGET_PXA25X is not set -CONFIG_USB_GADGET_R8A66597=y -CONFIG_USB_R8A66597=y +# CONFIG_USB_GADGET_R8A66597 is not set # CONFIG_USB_GADGET_PXA27X is not set # CONFIG_USB_GADGET_S3C_HSOTG is not set # CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_M66592 is not set +CONFIG_USB_GADGET_M66592=y +CONFIG_USB_M66592=y # CONFIG_USB_GADGET_AMD5536UDC is not set # CONFIG_USB_GADGET_FSL_QE is not set # CONFIG_USB_GADGET_CI13XXX is not set @@ -1214,13 +1048,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set # # Partition Types @@ -1267,7 +1094,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set # # Kernel hacking @@ -1281,48 +1107,11 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set -# CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y @@ -1341,13 +1130,8 @@ CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set # # Security options diff --git a/arch/arm/mach-rk2818/board-midsdk.c b/arch/arm/mach-rk2818/board-midsdk.c index cf8d509b848c..09bcd9b8b9ee 100644 --- a/arch/arm/mach-rk2818/board-midsdk.c +++ b/arch/arm/mach-rk2818/board-midsdk.c @@ -38,37 +38,58 @@ static struct map_desc rk2818_io_desc[] __initdata = { { - .virtual = RK2818_AHB_BASE, //ÐéÄâµØÖ· - .pfn = __phys_to_pfn(RK2818_AHB_PHYS), //ÎïÀíµØÖ·£¬ÐëÓëÒ³±í¶ÔÆë - .length = RK2818_AHB_SIZE, //³¤¶È + .virtual = RK2818_MCDMA_BASE, //ÐéÄâµØÖ· + .pfn = __phys_to_pfn(RK2818_MCDMA_PHYS), //ÎïÀíµØÖ·£¬ÐëÓëÒ³±í¶ÔÆë + .length = RK2818_MCDMA_SIZE, //³¤¶È .type = MT_DEVICE //Ó³É䷽ʽ }, { - .virtual = RK2818_APB_BASE, - .pfn = __phys_to_pfn(RK2818_APB_PHYS), - .length = RK2818_APB_SIZE, - .type = MT_DEVICE + .virtual = RK2818_DWDMA_BASE, + .pfn = __phys_to_pfn(RK2818_DWDMA_PHYS), + .length = RK2818_DWDMA_SIZE, + .type = MT_DEVICE }, - - { - .virtual = RK2818_DSP_BASE, - .pfn = __phys_to_pfn(RK2818_DSP_PHYS), - .length = RK2818_DSP_SIZE, - .type = MT_DEVICE + + { + .virtual = RK2818_INTC_BASE, + .pfn = __phys_to_pfn(RK2818_INTC_PHYS), + .length = RK2818_INTC_SIZE, + .type = MT_DEVICE }, - { - .virtual = 0xff400000, /* for itcm , vir = phy , for reboot */ - .pfn = __phys_to_pfn(0xff400000), - .length = SZ_16K, - .type = MT_DEVICE + { + .virtual = RK2818_ARMDARBITER_BASE, + .pfn = __phys_to_pfn(RK2818_ARMDARBITER_PHYS), + .length = RK2818_ARMDARBITER_SIZE, + .type = MT_DEVICE + }, + + { + .virtual = RK2818_APB_BASE, + .pfn = __phys_to_pfn(RK2818_APB_PHYS), + .length = 0xa0000, + .type = MT_DEVICE + }, + + { + .virtual = RK2818_WDT_BASE, + .pfn = __phys_to_pfn(RK2818_WDT_PHYS), + .length = 0xa0000, ///apb bus i2s i2c spi no map in this + .type = MT_DEVICE + }, + + { + .virtual = 0xff400000, /* for itcm , vir = phy , for reboot */ + .pfn = __phys_to_pfn(0xff400000), + .length = SZ_16K, + .type = MT_DEVICE } }; static struct platform_device *devices[] __initdata = { - //&rk2818_add_device_serial, + &rk2818_device_uart1, }; extern struct sys_timer rk2818_timer; @@ -80,6 +101,7 @@ static void __init machine_rk2818_init_irq(void) static void __init machine_rk2818_board_init(void) { + printk("%s [%d]\n",__FUNCTION__,__LINE__); platform_add_devices(devices, ARRAY_SIZE(devices)); } @@ -87,10 +109,8 @@ static void __init machine_rk2818_mapio(void) { iotable_init(rk2818_io_desc, ARRAY_SIZE(rk2818_io_desc)); rk2818_clock_init(); - //rk2818_iomux_init(); - -/* Setup the serial ports and console*/ - // rk2818_init_serial(&rk2818_uart_config); + printk("%s [%d]\n",__FUNCTION__,__LINE__); + //rk2818_iomux_init(); } MACHINE_START(RK2818, "rk2818midsdk") diff --git a/arch/arm/mach-rk2818/clock-rk2818.c b/arch/arm/mach-rk2818/clock-rk2818.c index 5010e0693c08..c4a66260ad2a 100644 --- a/arch/arm/mach-rk2818/clock-rk2818.c +++ b/arch/arm/mach-rk2818/clock-rk2818.c @@ -99,7 +99,7 @@ struct clk rk2818_clocks[] = { CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0), CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0), - ///CLOCK("uart_clk", UART1_CLK, &rk2818_device_uart1.dev, OFF), + CLOCK("uart_clk", UART1_CLK, &rk2818_device_uart1.dev, OFF), CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF), CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0), CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0), diff --git a/arch/arm/mach-rk2818/devices.c b/arch/arm/mach-rk2818/devices.c index 44e57d826170..95359a4e70c1 100644 --- a/arch/arm/mach-rk2818/devices.c +++ b/arch/arm/mach-rk2818/devices.c @@ -24,10 +24,24 @@ #include #include + + +static struct resource resources_uart0[] = { + { + .start = IRQ_NR_UART0, + .end = IRQ_NR_UART0, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2818_UART0_PHYS, + .end = RK2818_UART0_PHYS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, +}; static struct resource resources_uart1[] = { { - .start = IRQ_NR_UART1,//INT_UART1, - .end = IRQ_NR_UART1,//INT_UART1, + .start = IRQ_NR_UART1, + .end = IRQ_NR_UART1, .flags = IORESOURCE_IRQ, }, { @@ -36,13 +50,53 @@ static struct resource resources_uart1[] = { .flags = IORESOURCE_MEM, }, }; +static struct resource resources_uart2[] = { + { + .start = IRQ_NR_UART2, + .end = IRQ_NR_UART2, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2818_UART2_PHYS, + .end = RK2818_UART2_PHYS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, +}; +static struct resource resources_uart3[] = { + { + .start = IRQ_NR_UART3, + .end = IRQ_NR_UART3, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2818_UART3_PHYS, + .end = RK2818_UART3_PHYS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, +}; - -struct platform_device msm_device_uart1 = { +struct platform_device rk2818_device_uart0 = { .name = "rk2818_serial", .id = 0, + .num_resources = ARRAY_SIZE(resources_uart0), + .resource = resources_uart0, +}; +struct platform_device rk2818_device_uart1 = { + .name = "rk2818_serial", + .id = 1, .num_resources = ARRAY_SIZE(resources_uart1), .resource = resources_uart1, }; - +struct platform_device rk2818_device_uart2 = { + .name = "rk2818_serial", + .id = 2, + .num_resources = ARRAY_SIZE(resources_uart2), + .resource = resources_uart2, +}; +struct platform_device rk2818_device_uart3 = { + .name = "rk2818_serial", + .id = 3, + .num_resources = ARRAY_SIZE(resources_uart3), + .resource = resources_uart3, +}; diff --git a/arch/arm/mach-rk2818/include/mach/irqs.h b/arch/arm/mach-rk2818/include/mach/irqs.h index 52cdef1b0fc8..d6b94df7bcd1 100644 --- a/arch/arm/mach-rk2818/include/mach/irqs.h +++ b/arch/arm/mach-rk2818/include/mach/irqs.h @@ -86,14 +86,14 @@ #define IRQ_NR_SWI 37// -- Software Interrupt #define IRQ_NR_DSPMEI 38// -- DSP master interface error interrupt #define IRQ_NR_DSPSAEI 39// -- DSP system access error interrupt -#define IRQ_GPU_M55_INT 40 -#define IRQ_GPU_MMU_INT 41 -#define IRQ_DDRII_MOBILE_CTR_INIT 42 -#define IRQ_MC_DMA_INT 43 -#define IRQ_NAND_FLASH_RDY_INT 44 -#define IRQ_APB_UART2 45 -#define IRQ_APB_UART3 46 -#define IRQ_USB_HOST 47 +#define IRQ_NR_GPU_M55 40 +#define IRQ_NR_GPU_MMU 41 +#define IRQ_NR_DDRII_MOBILE_CTR 42 +#define IRQ_NR_MC_DMA 43 +#define IRQ_NR_NAND_FLASH_RDY 44 +#define IRQ_NR_UART2 45 +#define IRQ_NR_UART3 46 +#define IRQ_NR_USB_HOST 47 #endif diff --git a/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h b/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h index 15df1c5a539a..95f4b0fc101e 100644 --- a/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h +++ b/arch/arm/mach-rk2818/include/mach/rk2818_iomap.h @@ -43,7 +43,6 @@ #define RK2818_SDRAM_SIZE (0x00100000*64) #endif -#define RK2818_AHB_BASE 0xFF000000 #define RK2818_AHB_PHYS 0x10000000 //AHB ×ÜÏßÉ豸»ùÎïÀíµØÖ· #define RK2818_AHB_SIZE 0x00100000 // size:1M @@ -51,15 +50,12 @@ #define RK2818_APB_PHYS 0x18000000 // APB×ÜÏßÉ豸»ùÎïÀíµØÖ· #define RK2818_APB_SIZE 0x00100000 // size:1M -#define RK2818_BOOTROM_BASE 0xFF000000 #define RK2818_BOOTROM_PHYS 0x10000000 #define RK2818_BOOTROM_SIZE SZ_8K -#define RK2818_SRAM_BASE 0xFF002000 #define RK2818_SRAM_PHYS 0x10002000 #define RK2818_SRAM_SIZE SZ_8K -#define RK2818_USBOTG_BASE 0xFF040000 #define RK2818_USBOTG_PHYS 0x10040000 #define RK2818_USBOTG_SIZE SZ_256K @@ -67,7 +63,6 @@ #define RK2818_MCDMA_PHYS 0x10080000 #define RK2818_MCDMA_SIZE SZ_8K -#define RK2818_SHAREMEM_BASE 0xFF090000 #define RK2818_SHAREMEM_PHYS 0x10090000 #define RK2818_SHAREMEM_SIZE SZ_64K @@ -75,19 +70,15 @@ #define RK2818_DWDMA_PHYS 0x100A0000 #define RK2818_DWDMA_SIZE SZ_8K -#define RK2818_HOSTIF_BASE 0xFF0A2000 #define RK2818_HOSTIF_PHYS 0x100A2000 #define RK2818_HOSTIF_SIZE SZ_8K -#define RK2818_LCDC_BASE 0xFF0A4000 #define RK2818_LCDC_PHYS 0x100A4000 #define RK2818_LCDC_SIZE SZ_8K -#define RK2818_VIP_BASE 0xFF0A6000 #define RK2818_VIP_PHYS 0x100A6000 #define RK2818_VIP_SIZE SZ_8K -#define RK2818_SDMMC1_BASE 0xFF0A8000 #define RK2818_SDMMC1_PHYS 0x100A8000 #define RK2818_SDMMC1_SIZE SZ_8K @@ -95,15 +86,12 @@ #define RK2818_INTC_PHYS 0x100AA000 #define RK2818_INTC_SIZE SZ_8K -#define RK2818_SDMMC0_BASE 0xFF0AC000 #define RK2818_SDMMC0_PHYS 0x100AC000 #define RK2818_SDMMC0_SIZE SZ_8K -#define RK2818_NANDC_BASE 0xFF0AE000 #define RK2818_NANDC_PHYS 0x100AE000 #define RK2818_NANDC_SIZE SZ_16K -#define RK2818_SDRAMC_BASE 0xFF0B0000 #define RK2818_SDRAMC_PHYS 0x100B0000 #define RK2818_SDRAMC_SIZE SZ_8K @@ -111,15 +99,12 @@ #define RK2818_ARMDARBITER_PHYS 0x100B4000 #define RK2818_ARMDARBITER_SIZE SZ_8K -#define RK2818_VIDEOCOP_BASE 0xFF0B8000 #define RK2818_VIDEOCOP_PHYS 0x100B8000 #define RK2818_VIDEOCOP_SIZE SZ_8K -#define RK2818_ESRAM_BASE 0xFF0BA000 #define RK2818_ESRAM_PHYS 0x100BA000 #define RK2818_ESRAM_SIZE SZ_8K -#define RK2818_USBHOST_BASE 0xFF10000 #define RK2818_USBHOST_PHYS 0x1010000 #define RK2818_USBHOST_SIZE SZ_256K @@ -155,19 +140,15 @@ #define RK2818_GPIO1_PHYS 0x18009000 #define RK2818_GPIO1_SIZE SZ_8K -#define RK2818_I2S_BASE 0xFF10A000 #define RK2818_I2S_PHYS 0x1800A000 #define RK2818_I2S_SIZE SZ_8K -#define RK2818_I2C0_BASE 0xFF10C000 #define RK2818_I2C0_PHYS 0x1800C000 #define RK2818_I2C0_SIZE SZ_4K -#define RK2818_I2C1_BASE 0xFF10D000 #define RK2818_I2C1_PHYS 0x1800D000 #define RK2818_I2C1_SIZE SZ_4K -#define RK2818_SPIMASTER_BASE 0xFF10E000 #define RK2818_SPIMASTER_PHYS 0x1800E000 #define RK2818_SPIMASTER_SIZE SZ_4K @@ -199,7 +180,6 @@ #define RK2818_REGFILE_PHYS 0x18019000 #define RK2818_REGFILE_SIZE SZ_4K -#define RK2818_DSP_BASE 0xE0000000 #define RK2818_DSP_PHYS 0x80000000 #define RK2818_DSP_SIZE 0x00600000 diff --git a/arch/arm/mach-rk2818/timer.c b/arch/arm/mach-rk2818/timer.c index 9de5b9e19e17..1a9ad50a2e6b 100644 --- a/arch/arm/mach-rk2818/timer.c +++ b/arch/arm/mach-rk2818/timer.c @@ -68,7 +68,7 @@ static irqreturn_t rk2818_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static cycle_t rk2818_timer_read(void) +static cycle_t rk2818_timer_read(struct clocksource *cs) { unsigned int elapsed; @@ -117,7 +117,7 @@ static void rk2818_timer_set_mode(enum clock_event_mode mode, } } -static struct rk2818_clock rk2818_clocks[] = { +static struct rk2818_clock rk2818_system_clocks[] = { { .clockevent = { .name = "timer", @@ -139,26 +139,25 @@ static struct rk2818_clock rk2818_clocks[] = { .name = "timer", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING, .handler = rk2818_timer_interrupt, - .dev_id = &rk2818_clocks[0].clockevent, + .dev_id = &rk2818_system_clocks[0].clockevent, .irq = IRQ_NR_TIMER3 }, .regbase = RK2818_TIMER3_BASE, .freq = TIMER_HZ - } + }, }; static void __init rk2818_timer_init(void) { int i; int res; - printk("%s [%d]\n",__FUNCTION__,__LINE__); - //rk2818_clock_init(); - for (i = 0; i < ARRAY_SIZE(rk2818_clocks); i++) { - printk("%s::Enter %d\n",__FUNCTION__,i+1); - struct rk2818_clock *clock = &rk2818_clocks[i]; + + for (i = 0; i < ARRAY_SIZE(rk2818_system_clocks); i++) { + struct rk2818_clock *clock = &rk2818_system_clocks[i]; struct clock_event_device *ce = &clock->clockevent; struct clocksource *cs = &clock->clocksource; - + + printk("%s::Enter %d\n",__FUNCTION__,i+1); writel((TIMER_HZ+ HZ/2) / HZ,clock->regbase+TIMER_LOAD_COUNT); writel(0x04, clock->regbase + TIMER_CONTROL_REG); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e52257257279..bfa326c0686c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1477,4 +1477,16 @@ config SERIAL_BCM63XX_CONSOLE If you have enabled the serial port on the bcm63xx CPU you can make it the console by answering Y to this option. +config SERIAL_RK2818 + bool "RockChip rk2818 serial port support" + depends on ARM && ARCH_RK2818 + select SERIAL_CORE + + +config SERIAL_RK2818_CONSOLE + bool "Rockchip rk2818 serial console support" + depends on SERIAL_RK2818=y + select SERIAL_CORE_CONSOLE + + endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d21d5dd5d048..10e42a48d962 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -80,4 +80,6 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_QE) += ucc_uart.o +obj-$(CONFIG_SERIAL_RK2818) += rk2818_serial.o + obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o diff --git a/drivers/serial/rk2818_serial.c b/drivers/serial/rk2818_serial.c new file mode 100644 index 000000000000..7560660c50b5 --- /dev/null +++ b/drivers/serial/rk2818_serial.c @@ -0,0 +1,670 @@ +/* + * drivers/serial/rk2818_serial.c - driver for rk2818 RK2818 serial device and console + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rk2818_serial.h" + +/* + * We wrap our port structure around the generic uart_port. + */ +struct rk2818_port { + struct uart_port uart; + char name[16]; + struct clk *clk; + unsigned int imr; +}; + +#if defined(CONFIG_SERIAL_RK2818_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#define UART_TO_RK2818(uart_port) ((struct rk2818_port *) uart_port) +#define RK2818_SERIAL_MAJOR TTY_MAJOR +#define RK2818_SERIAL_MINOR 64 + + +static inline void rk2818_uart_write(struct uart_port *port, unsigned int val, + unsigned int off) +{ + __raw_writel(val, port->membase + off); +} + +static inline unsigned int rk2818_uart_read(struct uart_port *port, unsigned int off) +{ + return __raw_readl(port->membase + off); +} + +static int rk2818_set_baud_rate(struct uart_port *port, unsigned int baud) +{ + unsigned int uartTemp; + + rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) | LCR_DLA_EN,UART_LCR); + uartTemp = port->uartclk / (16 * baud); + rk2818_uart_write(port,uartTemp & 0xff,UART_DLL); + rk2818_uart_write(port,(uartTemp>>8) & 0xff,UART_DLH); + rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) & (~LCR_DLA_EN),UART_LCR); + return baud; +} + +/* + * ÅжϷ¢ËÍ»º³åÇøÊÇ·ñΪ¿Õ + *ÏÈÒÔFIFO´ò¿ª×ö£¬ºóÃæ¿ÉÒÔ×ö³ÉFIFO¹Ø»òFIFO¿ª¡£ + */ +static u_int rk2818_serial_tx_empty(struct uart_port *port) +{ + while(!(rk2818_uart_read(port,UART_USR)&UART_TRANSMIT_FIFO_EMPTY)) + cpu_relax(); + if(rk2818_uart_read(port,UART_USR)&UART_TRANSMIT_FIFO_EMPTY) + { + return (1);///1£º¿Õ + }else{ + return (0);///0:·Ç¿Õ + } +} + +/* + * Power / Clock management. + */ +static void rk2818_serial_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct rk2818_port *rk2818_port = UART_TO_RK2818(port); + + switch (state) { + case 0: + /* + * Enable the peripheral clock for this serial port. + * This is called on uart_open() or a resume event. + */ + clk_enable(rk2818_port->clk); + break; + case 3: + /* + * Disable the peripheral clock for this serial port. + * This is called on uart_close() or a suspend event. + */ + clk_disable(rk2818_port->clk); + break; + default: + printk(KERN_ERR "rk2818_serial: unknown pm %d\n", state); + } +} + +/* + * Return string describing the specified port + */ +static const char *rk2818_serial_type(struct uart_port *port) +{ + return (port->type == PORT_RK2818) ? "RK2818_SERIAL" : NULL; +} + +static void rk2818_serial_enable_ms(struct uart_port *port) +{ + #ifdef DEBUG_LHH + printk("Enter::%s\n",__FUNCTION__); + #endif +} + +/* no modem control lines */ +static unsigned int rk2818_serial_get_mctrl(struct uart_port *port) +{ + unsigned int result = 0; + unsigned int status; + + status = rk2818_uart_read(port,UART_MSR); + if (status & UART_MSR_URCTS) + { + result = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; + printk("UART_GET_MSR:0x%x\n",result); + }else{ + result = TIOCM_CAR | TIOCM_DSR; + printk("UART_GET_MSR:0x%x\n",result); + } + return result; +} + +static void rk2818_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + #ifdef DEBUG_LHH + printk("Enter::%s\n",__FUNCTION__); + #endif +} + +/* + * Stop transmitting. + */ +static void rk2818_serial_stop_tx(struct uart_port *port) +{ + #ifdef DEBUG_LHH + printk("Enter::%s\n",__FUNCTION__); + #endif +} + +/* + * Start transmitting. + */ +static void rk2818_serial_start_tx(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + while(!(uart_circ_empty(xmit))) + { + while (!(rk2818_uart_read(port,UART_USR) & UART_TRANSMIT_FIFO_NOT_FULL)){ + rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE|UART_IER_SEND_EMPTY_INT_ENABLE,UART_IER); + return; + } + rk2818_uart_write(port,xmit->buf[xmit->tail],UART_THR); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + } + if((uart_circ_empty(xmit))) + rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE,UART_IER); + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); +} + +/* + * Stop receiving - port is in process of being closed. + */ +static void rk2818_serial_stop_rx(struct uart_port *port) +{ + #ifdef DEBUG_LHH + printk("Enter::%s\n",__FUNCTION__); + #endif +} + +/* + * Control the transmission of a break signal + */ +static void rk2818_serial_break_ctl(struct uart_port *port, int break_state) +{ + unsigned int temp; + temp = rk2818_uart_read(port,UART_LCR); + if (break_state != 0) + temp = temp & (~BREAK_CONTROL_BIT);/* start break */ + else + temp = temp | BREAK_CONTROL_BIT; /* stop break */ + rk2818_uart_write(port,temp,UART_LCR); +} + + +/* + * Characters received (called from interrupt handler) + */ +static void rk2818_rx_chars(struct uart_port *port) +{ + unsigned int ch, flag; + while((rk2818_uart_read(port,UART_USR) & UART_RECEIVE_FIFO_NOT_EMPTY) == UART_RECEIVE_FIFO_NOT_EMPTY) + { + ch = rk2818_uart_read(port,UART_RBR); + flag = TTY_NORMAL; + port->icount.rx++; + if (uart_handle_sysrq_char(port, ch)) + { + continue; + } + uart_insert_char(port, 0, 0, ch, flag); + } + spin_unlock(&port->lock); + tty_flip_buffer_push(port->state->port.tty); + spin_lock(&port->lock); + +} + +/* + * Interrupt handler + */ +static irqreturn_t rk2818_uart_interrupt(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + unsigned int status, pending; + + status = rk2818_uart_read(port,UART_IIR); + pending = status & 0x0f; + if((pending == UART_IIR_RECV_AVAILABLE) || (pending == UART_IIR_CHAR_TIMEOUT)) + rk2818_rx_chars(port); + if(pending == UART_IIR_THR_EMPTY) + rk2818_serial_start_tx(port); + return IRQ_HANDLED; +} + +/* + * Disable the port + */ +static void rk2818_serial_shutdown(struct uart_port *port) +{ + struct rk2818_port *rk2818_port = UART_TO_RK2818(port); + rk2818_uart_write(port,0x00,UART_IER); + clk_disable(rk2818_port->clk); + free_irq(port->irq, port); +} +/* + * Perform initialization and enable port for reception + */ +static int rk2818_serial_startup(struct uart_port *port) +{ + struct tty_struct *tty = port->state->port.tty; + int retval; + + retval = request_irq(port->irq,rk2818_uart_interrupt,IRQF_SHARED, + tty ? tty->name : "rk2818_serial",port); + if(retval) + { + printk("\nrk2818_serial_startup err \n"); + rk2818_serial_shutdown(port); + return retval; + } + rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE,UART_IER); //enable uart recevice IRQ + return 0; +} + +/* + * Change the port parameters + */ +static void rk2818_serial_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) +{ + unsigned long flags; + unsigned int mode, baud; + unsigned int umcon,fcr; + /* Get current mode register */ + mode = rk2818_uart_read(port,UART_LCR) & (BREAK_CONTROL_BIT | EVEN_PARITY_SELECT | PARITY_ENABLED + | ONE_HALF_OR_TWO_BIT | UART_DATABIT_MASK); + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + /* byte size */ + switch (termios->c_cflag & CSIZE) { + case CS5: + mode |= LCR_WLS_5; + break; + case CS6: + mode |= LCR_WLS_6; + break; + case CS7: + mode |= LCR_WLS_7; + break; + default: + mode |= LCR_WLS_8; + break; + } + + /* stop bits */ + if (termios->c_cflag & CSTOPB) + mode |= ONE_STOP_BIT; + + /* parity */ + if (termios->c_cflag & PARENB) + { + mode |= PARITY_ENABLED; + if (termios->c_cflag & PARODD) + mode |= ODD_PARITY; + else + mode |= EVEN_PARITY; + } + spin_lock_irqsave(&port->lock, flags); + if(termios->c_cflag & CRTSCTS) + { + /*¿ªÆôuart0Ó²¼þÁ÷¿Ø*/ + //rk2818_mux_api_set(GPIOB2_U0CTSN_SEL_NAME, IOMUXB_UART0_CTS_N); + //rk2818_mux_api_set(GPIOB3_U0RTSN_SEL_NAME, IOMUXB_UART0_RTS_N); + printk("start CRTSCTS control and baudrate is %d\n",baud); + umcon=rk2818_uart_read(port,UART_MCR); + printk("UART_GET_MCR umcon=0x%x\n",umcon); + umcon |= UART_MCR_AFCEN; + umcon |= UART_MCR_URRTS; + umcon &=~UART_SIR_ENABLE; + rk2818_uart_write(port,umcon,UART_MCR); + printk("UART_GET_MCR umcon=0x%x\n",umcon); + fcr=rk2818_uart_read(port,UART_FCR); + printk("UART_GET_MCR fcr=0x%x\n",fcr); + fcr |= UART_FCR_FIFO_ENABLE; + rk2818_uart_write(port,fcr,UART_FCR); + printk("UART_GET_MCR fcr=0x%x\n",fcr); + } + mode = mode | LCR_DLA_EN; + while(rk2818_uart_read(port,UART_USR)&UART_USR_BUSY) + cpu_relax(); + rk2818_uart_write(port,mode,UART_LCR); + baud = rk2818_set_baud_rate(port, baud); + uart_update_timeout(port, termios->c_cflag, baud); + spin_unlock_irqrestore(&port->lock, flags); +} + + +static void rk2818_serial_release_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *resource; + resource_size_t size; + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) + return; + size = resource->end - resource->start + 1; + + release_mem_region(port->mapbase, size); + iounmap(port->membase); + port->membase = NULL; +} + +static int rk2818_serial_request_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *resource; + resource_size_t size; + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) + return -ENXIO; + size = resource->end - resource->start + 1; + + if (unlikely(!request_mem_region(port->mapbase, size, "rk2818_serial"))) + return -EBUSY; + + port->membase = ioremap(port->mapbase, size); + if (!port->membase) { + release_mem_region(port->mapbase, size); + return -EBUSY; + } + + return 0; +} + +/* + * Configure/autoconfigure the port. + */ +static void rk2818_serial_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_RK2818; + rk2818_serial_request_port(port); + } +} + +/* + * Verify the new serial_struct (for TIOCSSERIAL). + */ +static int rk2818_serial_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + int ret = 0; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_RK2818) + ret = -EINVAL; + if (port->irq != ser->irq) + ret = -EINVAL; + if (ser->io_type != SERIAL_IO_MEM) + ret = -EINVAL; + if (port->uartclk / 16 != ser->baud_base) + ret = -EINVAL; + if ((void *)port->mapbase != ser->iomem_base) + ret = -EINVAL; + if (port->iobase != ser->port) + ret = -EINVAL; + if (ser->hub6 != 0) + ret = -EINVAL; + return ret; +} + + +static struct uart_ops rk2818_uart_pops = { + .tx_empty = rk2818_serial_tx_empty, + .set_mctrl = rk2818_serial_set_mctrl, + .get_mctrl = rk2818_serial_get_mctrl, + .stop_tx = rk2818_serial_stop_tx, + .start_tx = rk2818_serial_start_tx, + .stop_rx = rk2818_serial_stop_rx, + .enable_ms = rk2818_serial_enable_ms, + .break_ctl = rk2818_serial_break_ctl, + .startup = rk2818_serial_startup, + .shutdown = rk2818_serial_shutdown, + .set_termios = rk2818_serial_set_termios, + .type = rk2818_serial_type, + .release_port = rk2818_serial_release_port, + .request_port = rk2818_serial_request_port, + .config_port = rk2818_serial_config_port, + .verify_port = rk2818_serial_verify_port, + .pm = rk2818_serial_pm, +}; + + +static struct rk2818_port rk2818_uart_ports[] = { + { + .uart = { + .iotype = UPIO_MEM, + .ops = &rk2818_uart_pops, + .flags = UPF_BOOT_AUTOCONF, + .fifosize = 32, + .line = 0, + }, + }, + { + .uart = { + .iotype = UPIO_MEM, + .ops = &rk2818_uart_pops, + .flags = UPF_BOOT_AUTOCONF, + .fifosize = 32, + .line = 1, + }, + }, + { + .uart = { + .iotype = UPIO_MEM, + .ops = &rk2818_uart_pops, + .flags = UPF_BOOT_AUTOCONF, + .fifosize = 32, + .line = 2, + }, + }, + { + .uart = { + .iotype = UPIO_MEM, + .ops = &rk2818_uart_pops, + .flags = UPF_BOOT_AUTOCONF, + .fifosize = 32, + .line = 3, + }, + }, +}; + +#define UART_NR ARRAY_SIZE(rk2818_uart_ports) + +static inline struct uart_port *get_port_from_line(unsigned int line) +{ + return &rk2818_uart_ports[line].uart; +} + +#ifdef CONFIG_SERIAL_RK2818_CONSOLE +static void rk2818_console_putchar(struct uart_port *port, int ch) +{ + while (!(rk2818_uart_read(port,UART_USR) & UART_TRANSMIT_FIFO_NOT_FULL)) + cpu_relax(); + rk2818_uart_write(port,ch,UART_THR); +} + +/* + * Interrupts are disabled on entering + */ +static void rk2818_console_write(struct console *co, const char *s, u_int count) +{ + struct uart_port *port; + struct rk2818_port *rk2818_port; + + BUG_ON(co->index < 0 || co->index >= UART_NR); + + port = get_port_from_line(co->index); + rk2818_port = UART_TO_RK2818(port); + + spin_lock(&port->lock); + uart_console_write(port, s, count, rk2818_console_putchar); + spin_unlock(&port->lock); +} + +static int __init rk2818_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud, flow, bits, parity; + + if (unlikely(co->index >= UART_NR || co->index < 0)) + return -ENXIO; + + port = get_port_from_line(co->index); + + if (unlikely(!port->membase)) + return -ENXIO; + + port->cons = co; + + //rk2818_init_clock(port); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + bits = 8; + parity = 'n'; + flow = 'n'; + rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) | LCR_WLS_8 | PARITY_DISABLED | ONE_STOP_BIT,UART_LCR); /* 8N1 */ + if (baud < 300 || baud > 115200) + baud = 115200; + rk2818_set_baud_rate(port, baud); + + printk(KERN_INFO "rk2818_serial: console setup on port %d\n", port->line); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver rk2818_uart_driver; + +static struct console rk2818_console = { + .name = "ttyS", + .write = rk2818_console_write, + .device = uart_console_device, + .setup = rk2818_console_setup, + .flags = CON_PRINTBUFFER, + .index = 1, + .data = &rk2818_uart_driver, +}; + +#define RK2818_CONSOLE (&rk2818_console) + +#else +#define RK2818_CONSOLE NULL +#endif + +static struct uart_driver rk2818_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "rk2818_serial", + .dev_name = "ttyS", + .nr = UART_NR, + .cons = RK2818_CONSOLE, + .major = RK2818_SERIAL_MAJOR, + .minor = RK2818_SERIAL_MINOR, +}; + +static int __devinit rk2818_serial_probe(struct platform_device *pdev) +{ + struct rk2818_port *rk2818_port; + struct resource *resource; + struct uart_port *port; + + if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) + return -ENXIO; + + printk(KERN_INFO "rk2818_serial: detected port %d\n", pdev->id); + + port = get_port_from_line(pdev->id); + port->dev = &pdev->dev; + rk2818_port = UART_TO_RK2818(port); + + rk2818_port->clk = clk_get(&pdev->dev, "uart_clk"); + if (unlikely(IS_ERR(rk2818_port->clk))) + return PTR_ERR(rk2818_port->clk); + port->uartclk = 24000*1000; ///clk_get_rate(rk2818_port->clk); + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) + return -ENXIO; + port->mapbase = resource->start; + + port->irq = platform_get_irq(pdev, 0); + if (unlikely(port->irq < 0)) + return -ENXIO; + + platform_set_drvdata(pdev, port); + + return uart_add_one_port(&rk2818_uart_driver, port); +} + +static int __devexit rk2818_serial_remove(struct platform_device *pdev) +{ + struct rk2818_port *rk2818_port = platform_get_drvdata(pdev); + + clk_put(rk2818_port->clk); + + return 0; +} + +static struct platform_driver rk2818_platform_driver = { + .remove = rk2818_serial_remove, + .driver = { + .name = "rk2818_serial", + .owner = THIS_MODULE, + }, +}; + +static int __init rk2818_serial_init(void) +{ + int ret; + ret = uart_register_driver(&rk2818_uart_driver); + if (unlikely(ret)) + return ret; + + ret = platform_driver_probe(&rk2818_platform_driver, rk2818_serial_probe); + if (unlikely(ret)) + uart_unregister_driver(&rk2818_uart_driver); + + printk(KERN_INFO "rk2818_serial: driver initialized\n"); + + return ret; +} + +static void __exit rk2818_serial_exit(void) +{ + #ifdef CONFIG_SERIAL_RK2818_CONSOLE + unregister_console(&rk2818_console); + #endif + platform_driver_unregister(&rk2818_platform_driver); + uart_unregister_driver(&rk2818_uart_driver); +} + + +module_init(rk2818_serial_init); +module_exit(rk2818_serial_exit); + +MODULE_AUTHOR("lhh lhh@rock-chips.com"); +MODULE_DESCRIPTION("Rockchip RK2818 Serial port driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/rk2818_serial.h b/drivers/serial/rk2818_serial.h new file mode 100644 index 000000000000..627cf2baa9e9 --- /dev/null +++ b/drivers/serial/rk2818_serial.h @@ -0,0 +1,122 @@ +/* + * drivers/serial/rk2818_serial.h + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DRIVERS_SERIAL_RK2818_SERIAL_H +#define __DRIVERS_SERIAL_RK2818_SERIAL_H + +#define UART_RBR 0x0000 /* Receive Buffer Register */ +#define UART_THR 0x0000 /* Transmit Holding Register */ +#define UART_DLL 0x0000 /* Divisor Latch (Low) */ +#define UART_DLH 0x0004 /* Divisor Latch (High) */ +#define UART_IER 0x0004 /* Interrupt Enable Register */ +#define UART_IIR 0x0008 /* Interrupt Identification Register */ +#define UART_FCR 0x0008 /* FIFO Control Register */ +#define UART_LCR 0x000C /* Line Control Register */ +#define UART_MCR 0x0010 /* Modem Control Register */ +#define UART_LSR 0x0014 /* [0x0000_0060] Line Status Register */ +#define UART_MSR 0x0018 /* Modem Status Register */ +#define UART_SCR 0x001c /* Scratchpad Register */ +#define UART_SRBR(n) (0x0030+((n) * 4)) /* Shadow Receive Buffer Register */ +#define UART_STHR(n) (0x0030+((n) * 4)) /* Shadow Transmit Holding Register */ +#define UART_FAR 0x0070 /* FIFO Access Register */ +#define UART_TFR 0x0074 /* Transmit FIFO Read */ +#define UART_RFW 0x0078 /* Receive FIFO Write */ +#define UART_USR 0x007C /* UART Status Register */ +#define UART_TFL 0x0080 /* Transmit FIFO Level */ +#define UART_RFL 0x0084 /* Receive FIFO Level */ +#define UART_SRR 0x0088 /* Software Reset Register */ +#define UART_SRTS 0x008C /* Shadow Request to Send */ +#define UART_SBCR 0x0090 /* Shadow Break Control Register */ +#define UART_SDMAM 0x0094 /* Shadow DMA Mode */ +#define UART_SFE 0x0098 /* Shadow FIFO Enable */ +#define UART_SRT 0x009C /* Shadow RCVR Trigger */ +#define UART_STET 0x00A0 /* Shadow TX Empty Trigger */ +#define UART_HTX 0x00A4 /* Halt TX */ +#define UART_DMASA 0x00A8 /* DMA Software Acknowledge */ +#define UART_CPR 0x00F4 /* Component Parameter Register */ +#define UART_UCV 0x00F8 /* [0x3330_372a] UART Component Version */ +#define UART_CTR 0x00FC /* [0x4457_0110] Component Type Register */ + +#define UART_FCR_FIFO_ENABLE (1<<0) + +//#define UART_LCR 0x0c +#define LCR_DLA_EN (1<<7) +#define BREAK_CONTROL_BIT (1<<6) +#define EVEN_PARITY_SELECT (1<<4) +#define EVEN_PARITY (1<<4) +#define ODD_PARITY (0) +#define PARITY_DISABLED (0) +#define PARITY_ENABLED (1<<3) +#define ONE_STOP_BIT (0) +#define ONE_HALF_OR_TWO_BIT (1<<2) +#define LCR_WLS_5 (0x00) +#define LCR_WLS_6 (0x01) +#define LCR_WLS_7 (0x02) +#define LCR_WLS_8 (0x03) +#define UART_DATABIT_MASK (0x03) + +/* Detail UART_IER Register Description */ +#define UART_IER_THRE_MODE_INT_ENABLE 1<<7 +#define UART_IER_MODEM_STATUS_INT_ENABLE 1<<3 +#define UART_IER_RECV_LINE_STATUS_INT_ENABLE 1<<2 +#define UART_IER_SEND_EMPTY_INT_ENABLE 1<<1 +#define UART_IER_RECV_DATA_AVAIL_INT_ENABLE 1<<0 + + +/* Detail UART_IIR Register Description */ +#define UART_IIR_FIFO_DISABLE 0x00 +#define UART_IIR_FIFO_ENABLE 0x03 +#define UART_IIR_INT_ID_MASK 0x0F +#define UART_IIR_MODEM_STATUS 0x00 +#define UART_IIR_NO_INTERRUPT_PENDING 0x01 +#define UART_IIR_THR_EMPTY 0x02 +#define UART_IIR_RECV_AVAILABLE 0x04 +#define UART_IIR_RECV_LINE_STATUS 0x06 +#define UART_IIR_BUSY_DETECT 0x07 +#define UART_IIR_CHAR_TIMEOUT 0x0C + +//#define UART_MCR 0x10 +/* Modem Control Register */ +#define UART_SIR_ENABLE (1 << 6) +#define UART_MCR_AFCEN (1 << 5) /* Auto Flow Control Mode enabled */ +#define UART_MCR_URLB (1 << 4) /* Loop-back mode */ +#define UART_MCR_UROUT2 (1 << 3) /* OUT2 signal */ +#define UART_MCR_UROUT1 (1 << 2) /* OUT1 signal */ +#define UART_MCR_URRTS (1 << 1) /* Request to Send */ +#define UART_MCR_URDTR (1 << 0) /* Data Terminal Ready */ + +//#define UART_MSR 0x18 +/* Modem Status Register */ +#define UART_MSR_URDCD (1 << 7) /* Data Carrier Detect */ +#define UART_MSR_URRI (1 << 6) /* Ring Indicator */ +#define UART_MSR_URDSR (1 << 5) /* Data Set Ready */ +#define UART_MSR_URCTS (1 << 4) /* Clear to Send */ +#define UART_MSR_URDDCD (1 << 3) /* Delta Data Carrier Detect */ +#define UART_MSR_URTERI (1 << 2) /* Trailing Edge Ring Indicator */ +#define UART_MSR_URDDST (1 << 1) /* Delta Data Set Ready */ +#define UART_MSR_URDCTS (1 << 0) /* Delta Clear to Send */ + +/* Detail UART_USR Register Description */ +#define UART_RECEIVE_FIFO_FULL (1<<4) +#define UART_RECEIVE_FIFO_NOT_FULL (0) +#define UART_RECEIVE_FIFO_EMPTY (0) +#define UART_RECEIVE_FIFO_NOT_EMPTY (1<<3) +#define UART_TRANSMIT_FIFO_NOT_EMPTY (0) +#define UART_TRANSMIT_FIFO_EMPTY (1<<2) +#define UART_TRANSMIT_FIFO_FULL (0) +#define UART_TRANSMIT_FIFO_NOT_FULL (1<<1) +#define UART_USR_BUSY (1) + +#endif /* __DRIVERS_SERIAL_RK2818_SERIAL_H */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 743f48ac71dc..1f9fa0e1561b 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -179,6 +179,8 @@ /* BCM63xx family SoCs */ #define PORT_BCM63XX 89 +#define PORT_RK2818 90 + #ifdef __KERNEL__ #include -- 2.34.1