diff --git a/Documentation/boards.dox b/Documentation/boards.dox index 6bcc14f..f0fc2f1 100644 --- a/Documentation/boards.dox +++ b/Documentation/boards.dox @@ -58,7 +58,8 @@ @li @subpage dlink_dir_320 @li @subpage loongson_ls1b @li @subpage qemu_malta -@li @subpage rzx50 +@li @subpage ritmix-rzx50 +@li @subpage tplink-mr3020 */ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b819b49..9a240b7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -54,6 +54,19 @@ select DRIVER_SERIAL_NS16550 select HAS_DEBUG_LL +config MACH_MIPS_ATH79 + bool "Atheros AR71XX/AR724X/AR913X/AR933X based boards" + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select CSRC_R4K_LIB + select HAS_DEBUG_LL + select HAVE_CLK + select COMMON_CLK + select COMMON_CLK_OF_PROVIDER + select CLKDEV_LOOKUP + select OFTREE + config MACH_MIPS_BCM47XX bool "Broadcom BCM47xx-based boards" select CSRC_R4K_LIB @@ -80,6 +93,7 @@ source arch/mips/mach-malta/Kconfig source arch/mips/mach-ar231x/Kconfig +source arch/mips/mach-ath79/Kconfig source arch/mips/mach-bcm47xx/Kconfig source arch/mips/mach-loongson/Kconfig source arch/mips/mach-xburst/Kconfig diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8986fcf..b3bacf3 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -78,6 +78,9 @@ machine-$(CONFIG_MACH_MIPS_AR231X) := ar231x board-$(CONFIG_BOARD_NETGEAR_WG102) := netgear-wg102 +machine-$(CONFIG_MACH_MIPS_ATH79) := ath79 +board-$(CONFIG_BOARD_TPLINK_MR3020) := tplink-mr3020 + machine-$(CONFIG_MACH_MIPS_BCM47XX) := bcm47xx board-$(CONFIG_BOARD_DLINK_DIR320) := dlink-dir-320 @@ -85,7 +88,7 @@ board-$(CONFIG_BOARD_LOONGSON_TECH_LS1B) := loongson-ls1b machine-$(CONFIG_MACH_MIPS_XBURST) := xburst -board-$(CONFIG_BOARD_RZX50) := rzx50 +board-$(CONFIG_BOARD_RZX50) := ritmix-rzx50 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y)) diff --git a/arch/mips/boards/ritmix-rzx50/Makefile b/arch/mips/boards/ritmix-rzx50/Makefile new file mode 100644 index 0000000..31c0629 --- /dev/null +++ b/arch/mips/boards/ritmix-rzx50/Makefile @@ -0,0 +1 @@ +obj-y += serial.o diff --git a/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h b/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h new file mode 100644 index 0000000..fb914d9 --- /dev/null +++ b/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h @@ -0,0 +1,43 @@ +/* + * Startup Code for Ritmix RZX-50 board + * + * Copyright (C) 2013 Antony Pavlov + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 + + .macro board_pbl_start + .set push + .set noreorder + + mips_disable_interrupts + + /* CPU/SoC specific setup ... */ + /* ... absent */ + + debug_ll_ns16550_init + + debug_ll_ns16550_outc '.' + debug_ll_ns16550_outnl + + mips_nmon + + copy_to_link_location pbl_start + + .set pop + .endm diff --git a/arch/mips/boards/ritmix-rzx50/include/board/debug_ll.h b/arch/mips/boards/ritmix-rzx50/include/board/debug_ll.h new file mode 100644 index 0000000..7ae0e2a --- /dev/null +++ b/arch/mips/boards/ritmix-rzx50/include/board/debug_ll.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012 Antony Pavlov + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ +#define __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ + +#include + +#endif /* __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ */ diff --git a/arch/mips/boards/ritmix-rzx50/ritmix-rzx50.dox b/arch/mips/boards/ritmix-rzx50/ritmix-rzx50.dox new file mode 100644 index 0000000..5ec8194 --- /dev/null +++ b/arch/mips/boards/ritmix-rzx50/ritmix-rzx50.dox @@ -0,0 +1,46 @@ +/** @page ritmix-rzx50 Ritmix RZX-50 game console + +Ritmix RZX-50 is a portable game console for the Russian market. + +The portable game console has +@li Ingenic JZ4755 SoC; +@li 64 MiB SDRAM; +@li 4 GiB microSDHC card / 4 GiB NAND type Flash Memory; +@li RS232 serial interface (LV-TTL levels on the board!); +@li LCD display (480x272); +@li Video out interface; +@li 1xUSB interface; +@li buttons. + +The game console uses U-Boot 1.1.6 as bootloader. + +barebox-rzx50 mini-howto: + +1. Connect to the game console's UART (see. http://a320.emulate.su/2012/01/19/uart-na-ritmix-rzx-50/); + +2. Unblock U-Boot console (see. http://a320.emulate.su/2012/01/25/rzx-50-dostup-k-konsoli-u-boot/); Please note that U-Boot's Zmodem support does not work; + +3. Boot Ritmix linux and login; + +4. Upload barebox.bin via Zmodem +@verbatim + # cd /tmp + # rz +@endverbatim + +5. Write barebox to onboard flash +@verbatim + # dd if=barebox.bin of=/dev/mmcblk0 seek=1048576 bs=1 count=262144 +@endverbatim + +6. Reboot RZX-50, next in U-Boot console start barebox: +@verbatim + CETUS # msc read 0xa0800000 0x100000 0x40000; g a0800000 +@endverbatim + +Ritmix RZX-50 links: +@li http://www.ritmixrussia.ru/products/252/entertainment/game/rzx-50 +@li ftp://ftp.ingenic.cn/2soc/4755/JZ4755_ds.pdf +@li ftp://ftp.ingenic.cn/3sw/01linux/01loader/u-boot/u-boot-1.1.6-jz-20110719-r1728-add-jz4770.patch.bz2 + +*/ diff --git a/arch/mips/boards/ritmix-rzx50/serial.c b/arch/mips/boards/ritmix-rzx50/serial.c new file mode 100644 index 0000000..f1e8da0 --- /dev/null +++ b/arch/mips/boards/ritmix-rzx50/serial.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Antony Pavlov + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 + +static int rzx50_hostname_init(void) +{ + barebox_set_hostname("rzx50"); + + return 0; +} +console_initcall(rzx50_hostname_init); diff --git a/arch/mips/boards/rzx50/Makefile b/arch/mips/boards/rzx50/Makefile deleted file mode 100644 index ff1a655..0000000 --- a/arch/mips/boards/rzx50/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o diff --git a/arch/mips/boards/rzx50/include/board/board_pbl_start.h b/arch/mips/boards/rzx50/include/board/board_pbl_start.h deleted file mode 100644 index fb914d9..0000000 --- a/arch/mips/boards/rzx50/include/board/board_pbl_start.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Startup Code for Ritmix RZX-50 board - * - * Copyright (C) 2013 Antony Pavlov - * - * This file is part of barebox. - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * 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 - - .macro board_pbl_start - .set push - .set noreorder - - mips_disable_interrupts - - /* CPU/SoC specific setup ... */ - /* ... absent */ - - debug_ll_ns16550_init - - debug_ll_ns16550_outc '.' - debug_ll_ns16550_outnl - - mips_nmon - - copy_to_link_location pbl_start - - .set pop - .endm diff --git a/arch/mips/boards/rzx50/include/board/debug_ll.h b/arch/mips/boards/rzx50/include/board/debug_ll.h deleted file mode 100644 index 7ae0e2a..0000000 --- a/arch/mips/boards/rzx50/include/board/debug_ll.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2012 Antony Pavlov - * - * This file is part of barebox. - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * 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 __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ -#define __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ - -#include - -#endif /* __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ */ diff --git a/arch/mips/boards/rzx50/rzx50.dox b/arch/mips/boards/rzx50/rzx50.dox deleted file mode 100644 index 963473c..0000000 --- a/arch/mips/boards/rzx50/rzx50.dox +++ /dev/null @@ -1,46 +0,0 @@ -/** @page rzx50 Ritmix RZX-50 game console - -Ritmix RZX-50 is a portable game console for the Russian market. - -The portable game console has -@li Ingenic JZ4755 SoC; -@li 64 MiB SDRAM; -@li 4 GiB microSDHC card / 4 GiB NAND type Flash Memory; -@li RS232 serial interface (LV-TTL levels on the board!); -@li LCD display (480x272); -@li Video out interface; -@li 1xUSB interface; -@li buttons. - -The game console uses U-Boot 1.1.6 as bootloader. - -barebox-rzx50 mini-howto: - -1. Connect to the game console's UART (see. http://a320.emulate.su/2012/01/19/uart-na-ritmix-rzx-50/); - -2. Unblock U-Boot console (see. http://a320.emulate.su/2012/01/25/rzx-50-dostup-k-konsoli-u-boot/); Please note that U-Boot's Zmodem support does not work; - -3. Boot Ritmix linux and login; - -4. Upload barebox.bin via Zmodem -@verbatim - # cd /tmp - # rz -@endverbatim - -5. Write barebox to onboard flash -@verbatim - # dd if=barebox.bin of=/dev/mmcblk0 seek=1048576 bs=1 count=262144 -@endverbatim - -6. Reboot RZX-50, next in U-Boot console start barebox: -@verbatim - CETUS # msc read 0xa0800000 0x100000 0x40000; g a0800000 -@endverbatim - -Ritmix RZX-50 links: -@li http://www.ritmixrussia.ru/products/252/entertainment/game/rzx-50 -@li ftp://ftp.ingenic.cn/2soc/4755/JZ4755_ds.pdf -@li ftp://ftp.ingenic.cn/3sw/01linux/01loader/u-boot/u-boot-1.1.6-jz-20110719-r1728-add-jz4770.patch.bz2 - -*/ diff --git a/arch/mips/boards/rzx50/serial.c b/arch/mips/boards/rzx50/serial.c deleted file mode 100644 index 566356a..0000000 --- a/arch/mips/boards/rzx50/serial.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2012 Antony Pavlov - * - * This file is part of barebox. - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * 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 - -static int rzx50_console_init(void) -{ - barebox_set_hostname("rzx50"); - - /* Register the serial port */ - jz_add_uart(DEVICE_ID_DYNAMIC, UART1_BASE, 12000000); - - return 0; -} -console_initcall(rzx50_console_init); diff --git a/arch/mips/boards/tplink-mr3020/Makefile b/arch/mips/boards/tplink-mr3020/Makefile new file mode 100644 index 0000000..dcfc293 --- /dev/null +++ b/arch/mips/boards/tplink-mr3020/Makefile @@ -0,0 +1 @@ +obj-y += board.o diff --git a/arch/mips/boards/tplink-mr3020/board.c b/arch/mips/boards/tplink-mr3020/board.c new file mode 100644 index 0000000..318998c --- /dev/null +++ b/arch/mips/boards/tplink-mr3020/board.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Antony Pavlov + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 + +static int model_hostname_init(void) +{ + barebox_set_hostname("mr3020"); + + return 0; +} +postcore_initcall(model_hostname_init); diff --git a/arch/mips/boards/tplink-mr3020/tplink-mr3020.dox b/arch/mips/boards/tplink-mr3020/tplink-mr3020.dox new file mode 100644 index 0000000..16fe465 --- /dev/null +++ b/arch/mips/boards/tplink-mr3020/tplink-mr3020.dox @@ -0,0 +1,64 @@ +/** @page tplink-mr3020 TP-LINK MR3020 wireless router + +The router has +@li Atheros ar9331 SoC; +@li 32 MiB SDRAM; +@li 4 MiB NOR type SPI Flash Memory; +@li RS232 serial interface (LV-TTL levels on board!); +@li 1 USB interface; +@li 1 Ethernet interfaces; +@li 802.11b/g/n (WiFi) interface; +@li LEDs & buttons. + +The router uses U-Boot 1.1.4 as firmware. + +Barebox can be started from U-Boot using tftp. +But you have to encode barebox image in a very special way. + +First obtain 'lzma' and 'mktplinkfw' utilities. + +The 'lzma' utility can be obtained in Debian/Ubuntu +distro by installing lzma package. + +The 'mktplinkfw' utility can be obtained from openwrt, e.g.: + +@verbatim +$ OWRTPREF=https://raw.githubusercontent.com/mirrors/openwrt/master +$ curl -OL $OWRTPREF/tools/firmware-utils/src/mktplinkfw.c \ + -OL $OWRTPREF/tools/firmware-utils/src/md5.c \ + -OL $OWRTPREF/tools/firmware-utils/src/md5.h +$ cc -o mktplinkfw mktplinkfw.c md5.c +@endverbatim + +To convert your barebox.bin to U-Boot-loadable image (6F01A8C0.img) +use this command sequence: + +@verbatim +$ lzma -c -k barebox.bin > barebox.lzma +$ ./FW/mktplinkfw -c -H 0x07200103 -W 1 -N TL-WR720N-v3 \ + -s -F 4Mlzma -k barebox.lzma -o 6F01A8C0.img +@endverbatim + +You must setup tftp-server on host 192.168.0.1. +Put your 6F01A8C0.img to tftp-server directory +(usual /tftpboot or /srv/tftp). +Connect your board to your tftp-server network via Ethernet. + +Next, setup network on MR3020 and run 6F01A8C0.img, e.g.: +@verbatim +hornet> set ipaddr 192.168.0.2 +hornet> set serverip 192.168.0.1 +hornet> tftpboot 0x81000000 6F01A8C0.img +hornet> bootm 0x81000000 +@endverbatim + +TP-LINK MR3020 links: +@li http://www.tp-link.com/en/products/details/?model=TL-MR3020 +@li http://wiki.openwrt.org/toh/tp-link/tl-mr3020 +@li https://wikidevi.com/wiki/TP-LINK_TL-MR3020 + +See also: +@li http://www.eeboard.com/wp-content/uploads/downloads/2013/08/AR9331.pdf +@li http://squonk42.github.io/TL-WR703N/ + +*/ diff --git a/arch/mips/configs/ritmix-rzx50_defconfig b/arch/mips/configs/ritmix-rzx50_defconfig new file mode 100644 index 0000000..7691bae --- /dev/null +++ b/arch/mips/configs/ritmix-rzx50_defconfig @@ -0,0 +1,39 @@ +CONFIG_BUILTIN_DTB=y +CONFIG_BUILTIN_DTB_NAME="rzx50" +CONFIG_MACH_MIPS_XBURST=y +CONFIG_JZ4750D_DEBUG_LL_UART1=y +CONFIG_PBL_IMAGE=y +CONFIG_BAUDRATE=57600 +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_HUSH_GETOPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +# CONFIG_DEFAULT_ENVIRONMENT is not set +CONFIG_DEBUG_LL=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_LOADS=y +CONFIG_CMD_SAVES=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTM_OFTREE=y +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_RESET=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_NODE=y +CONFIG_OFDEVICE=y +# CONFIG_SPI is not set +CONFIG_SHA1=y +CONFIG_SHA224=y +CONFIG_SHA256=y diff --git a/arch/mips/configs/rzx50_defconfig b/arch/mips/configs/rzx50_defconfig deleted file mode 100644 index 7691bae..0000000 --- a/arch/mips/configs/rzx50_defconfig +++ /dev/null @@ -1,39 +0,0 @@ -CONFIG_BUILTIN_DTB=y -CONFIG_BUILTIN_DTB_NAME="rzx50" -CONFIG_MACH_MIPS_XBURST=y -CONFIG_JZ4750D_DEBUG_LL_UART1=y -CONFIG_PBL_IMAGE=y -CONFIG_BAUDRATE=57600 -CONFIG_GLOB=y -CONFIG_HUSH_FANCY_PROMPT=y -CONFIG_HUSH_GETOPT=y -CONFIG_CMDLINE_EDITING=y -CONFIG_AUTO_COMPLETE=y -# CONFIG_DEFAULT_ENVIRONMENT is not set -CONFIG_DEBUG_LL=y -CONFIG_CMD_EDIT=y -CONFIG_CMD_SLEEP=y -CONFIG_CMD_LOADB=y -CONFIG_CMD_LOADY=y -CONFIG_CMD_LOADS=y -CONFIG_CMD_SAVES=y -CONFIG_CMD_MEMINFO=y -CONFIG_CMD_IOMEM=y -CONFIG_CMD_MD5SUM=y -CONFIG_CMD_BOOTM_SHOW_TYPE=y -CONFIG_CMD_BOOTM_VERBOSE=y -CONFIG_CMD_BOOTM_INITRD=y -CONFIG_CMD_BOOTM_OFTREE=y -CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y -CONFIG_CMD_UIMAGE=y -CONFIG_CMD_RESET=y -CONFIG_CMD_POWEROFF=y -CONFIG_CMD_GO=y -CONFIG_CMD_OFTREE=y -CONFIG_CMD_OF_PROPERTY=y -CONFIG_CMD_OF_NODE=y -CONFIG_OFDEVICE=y -# CONFIG_SPI is not set -CONFIG_SHA1=y -CONFIG_SHA224=y -CONFIG_SHA256=y diff --git a/arch/mips/configs/tplink-mr3020_defconfig b/arch/mips/configs/tplink-mr3020_defconfig new file mode 100644 index 0000000..2e925d9 --- /dev/null +++ b/arch/mips/configs/tplink-mr3020_defconfig @@ -0,0 +1,29 @@ +CONFIG_BUILTIN_DTB=y +CONFIG_BUILTIN_DTB_NAME="tplink-mr3020" +CONFIG_MACH_MIPS_ATH79=y +CONFIG_LONGHELP=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_LET=y +CONFIG_CMD_GLOBAL=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MM=y +CONFIG_CMD_SHA1SUM=y +# CONFIG_CMD_BOOTM is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_CLK=y +CONFIG_OFDEVICE=y +CONFIG_DRIVER_SERIAL_AR933X=y +# CONFIG_SPI is not set +CONFIG_MD5=y +CONFIG_SHA224=y +CONFIG_SHA256=y diff --git a/arch/mips/dts/ar9331.dtsi b/arch/mips/dts/ar9331.dtsi new file mode 100644 index 0000000..890fda8 --- /dev/null +++ b/arch/mips/dts/ar9331.dtsi @@ -0,0 +1,26 @@ +#include + +#include "skeleton.dtsi" + +/ { + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + device_type = "soc"; + ranges; + + serial0: serial@b8020000 { + compatible = "qca,ar9330-uart"; + reg = <0xb8020000 0x14>; + clocks = <&ar9331_clk AR933X_CLK_UART>; + status = "disabled"; + }; + + ar9331_clk: clock { + compatible = "qca,ar933x-clk"; + reg = <0xb8050000 0x48>; + #clock-cells = <1>; + }; + }; +}; diff --git a/arch/mips/dts/include/dt-bindings b/arch/mips/dts/include/dt-bindings new file mode 120000 index 0000000..0cecb3d --- /dev/null +++ b/arch/mips/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../include/dt-bindings \ No newline at end of file diff --git a/arch/mips/dts/jz4755.dtsi b/arch/mips/dts/jz4755.dtsi new file mode 100644 index 0000000..44ff912 --- /dev/null +++ b/arch/mips/dts/jz4755.dtsi @@ -0,0 +1,35 @@ +#include "skeleton.dtsi" + +/ { + soc { + compatible = "simple-bus"; + model = "Ingenic JZ4755"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + serial0: serial@b0030000 { + compatible = "ingenic,jz4740-uart"; + reg = <0xb0030000 0x20>; + reg-shift = <2>; + clock-frequency = <12000000>; + status = "disabled"; + }; + + serial1: serial@b0031000 { + compatible = "ingenic,jz4740-uart"; + reg = <0xb0031000 0x20>; + reg-shift = <2>; + clock-frequency = <12000000>; + status = "disabled"; + }; + + serial2: serial@b0032000 { + compatible = "ingenic,jz4740-uart"; + reg = <0xb0032000 0x20>; + reg-shift = <2>; + clock-frequency = <12000000>; + status = "disabled"; + }; + }; +}; diff --git a/arch/mips/dts/qemu-malta.dts b/arch/mips/dts/qemu-malta.dts index b6b69c4..67fe591 100644 --- a/arch/mips/dts/qemu-malta.dts +++ b/arch/mips/dts/qemu-malta.dts @@ -25,6 +25,14 @@ clock-frequency = <1843200>; }; + uart2: serial@bf000900 { + compatible = "ns16550a"; + reg = <0xbf000900 0x40>; + reg-shift = <3>; + /* no matter for emulated port */ + clock-frequency = <1843200>; + }; + nor0: flash@be000000 { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/dts/rzx50.dts b/arch/mips/dts/rzx50.dts index 69320dd..360c1bf 100644 --- a/arch/mips/dts/rzx50.dts +++ b/arch/mips/dts/rzx50.dts @@ -1,6 +1,6 @@ /dts-v1/; -/include/ "skeleton.dtsi" +#include "jz4755.dtsi" / { model = "Ritmix RZX-50"; @@ -10,3 +10,7 @@ reg = <0x00000000 0x4000000>; }; }; + +&serial1 { + status = "okay"; +}; diff --git a/arch/mips/dts/tplink-mr3020.dts b/arch/mips/dts/tplink-mr3020.dts new file mode 100644 index 0000000..5d613d8 --- /dev/null +++ b/arch/mips/dts/tplink-mr3020.dts @@ -0,0 +1,16 @@ +/dts-v1/; + +#include + +/ { + model = "TP-LINK MR3020"; + compatible = "tplink,mr3020"; + + memory { + reg = <0x00000000 0x2000000>; + }; +}; + +&serial0 { + status = "okay"; +}; diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S index bc78d2b..4ee4252 100644 --- a/arch/mips/lib/barebox.lds.S +++ b/arch/mips/lib/barebox.lds.S @@ -69,6 +69,8 @@ __usymtab : { BAREBOX_SYMS } __usymtab_end = .; + .oftables : { BAREBOX_CLK_TABLE() } + .dtb : { BAREBOX_DTB() } _edata = .; diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig new file mode 100644 index 0000000..96fffd3 --- /dev/null +++ b/arch/mips/mach-ath79/Kconfig @@ -0,0 +1,15 @@ +if MACH_MIPS_ATH79 + +config ARCH_TEXT_BASE + hex + default 0xa0800000 + +choice + prompt "Board type" + +config BOARD_TPLINK_MR3020 + bool "TP-LINK MR3020" + +endchoice + +endif diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile new file mode 100644 index 0000000..f3cc668 --- /dev/null +++ b/arch/mips/mach-ath79/Makefile @@ -0,0 +1 @@ +obj-y += reset.o diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h new file mode 100644 index 0000000..0c6ddd6 --- /dev/null +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h @@ -0,0 +1,64 @@ +/* + * Atheros AR71XX/AR724X/AR913X SoC register definitions + * + * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_MACH_AR71XX_REGS_H +#define __ASM_MACH_AR71XX_REGS_H + +#include + +#define AR71XX_APB_BASE 0x18000000 + +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) +#define AR71XX_PLL_SIZE 0x100 +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) +#define AR71XX_RESET_SIZE 0x100 + +#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) +#define AR933X_UART_SIZE 0x14 + +/* + * PLL block + */ +#define AR933X_PLL_CPU_CONFIG_REG 0x00 +#define AR933X_PLL_CPU_CONFIG2_REG 0x04 +#define AR933X_PLL_CLOCK_CTRL_REG 0x08 +#define AR933X_PLL_DITHER_FRAC_REG 0x10 +#define AR933X_PLL_DITHER_REG 0x14 + +#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 +#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f +#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 +#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f +#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 +#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 + +#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 + +/* + * RESET block + */ +#define AR933X_RESET_REG_RESET_MODULE 0x1c +#define AR933X_RESET_REG_BOOTSTRAP 0xac + +#define AR71XX_RESET_FULL_CHIP BIT(24) + +#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + +#endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h new file mode 100644 index 0000000..ff53406 --- /dev/null +++ b/arch/mips/mach-ath79/include/mach/ath79.h @@ -0,0 +1,33 @@ +/* + * Atheros AR71XX/AR724X/AR913X common definitions + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_MACH_ATH79_H +#define __ASM_MACH_ATH79_H + +#include +#include +#include + +#include + +static inline void ath79_reset_wr(unsigned reg, u32 val) +{ + __raw_writel(val, (char *)KSEG1ADDR(AR71XX_RESET_BASE + reg)); +} + +static inline u32 ath79_reset_rr(unsigned reg) +{ + return __raw_readl((char *)KSEG1ADDR(AR71XX_RESET_BASE + reg)); +} + +#endif /* __ASM_MACH_ATH79_H */ diff --git a/arch/mips/mach-ath79/include/mach/debug_ll.h b/arch/mips/mach-ath79/include/mach/debug_ll.h new file mode 100644 index 0000000..de4c00d --- /dev/null +++ b/arch/mips/mach-ath79/include/mach/debug_ll.h @@ -0,0 +1,56 @@ +/* + * based on linux.git/drivers/tty/serial/ar933x_uart.c + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 __AR933X_DEBUG_LL__ +#define __AR933X_DEBUG_LL__ + +#include +#include +#include + +#include + +#define AR933X_UART_DATA_REG 0x00 +#define AR933X_UART_DATA_TX_RX_MASK 0xff +#define AR933X_UART_DATA_TX_CSR BIT(9) + +#define DEBUG_LL_UART_ADDR KSEG1ADDR(AR933X_UART_BASE) + +static inline void ar933x_debug_ll_writel(u32 b, int offset) +{ + cpu_writel(b, (u8 *)DEBUG_LL_UART_ADDR + offset); +} + +static inline u32 ar933x_debug_ll_readl(int offset) +{ + return cpu_readl((u8 *)DEBUG_LL_UART_ADDR + offset); +} + +static inline void PUTC_LL(int ch) +{ + u32 data; + + /* wait transmitter ready */ + data = ar933x_debug_ll_readl(AR933X_UART_DATA_REG); + while (!(data & AR933X_UART_DATA_TX_CSR)) + data = ar933x_debug_ll_readl(AR933X_UART_DATA_REG); + + data = (ch & AR933X_UART_DATA_TX_RX_MASK) | AR933X_UART_DATA_TX_CSR; + ar933x_debug_ll_writel(data, AR933X_UART_DATA_REG); +} + +#endif /* __AR933X_DEBUG_LL__ */ diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c new file mode 100644 index 0000000..a0e9b34 --- /dev/null +++ b/arch/mips/mach-ath79/reset.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Du Huanpeng + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 + +void __noreturn reset_cpu(ulong addr) +{ + ath79_reset_wr(AR933X_RESET_REG_RESET_MODULE, AR71XX_RESET_FULL_CHIP); + /* + * Used to command a full chip reset. This is the software equivalent of + * pulling the reset pin. The system will reboot with PLL disabled. + * Always zero when read. + */ + unreachable(); + /*NOTREACHED*/ +} +EXPORT_SYMBOL(reset_cpu); diff --git a/arch/mips/mach-malta/include/mach/hardware.h b/arch/mips/mach-malta/include/mach/hardware.h index 9345a67..ba28cb8 100644 --- a/arch/mips/mach-malta/include/mach/hardware.h +++ b/arch/mips/mach-malta/include/mach/hardware.h @@ -20,6 +20,9 @@ #define MALTA_PIIX4_UART0 0xb80003f8 +#define MALTA_CBUS_UART 0xbf000900 +#define MALTA_CBUS_UART_SHIFT 3 + /* * Reset register. */ diff --git a/arch/mips/mach-xburst/Makefile b/arch/mips/mach-xburst/Makefile index 3e0cd73..e5634ba 100644 --- a/arch/mips/mach-xburst/Makefile +++ b/arch/mips/mach-xburst/Makefile @@ -1,2 +1 @@ -obj-y += serial.o obj-$(CONFIG_CPU_JZ4755) += csrc-jz4750.o reset-jz4750.o diff --git a/arch/mips/mach-xburst/mach-xburst.dox b/arch/mips/mach-xburst/mach-xburst.dox index a5e524d..052c05e 100644 --- a/arch/mips/mach-xburst/mach-xburst.dox +++ b/arch/mips/mach-xburst/mach-xburst.dox @@ -2,6 +2,6 @@ @section xburst_boards XBurst-based boards -@li @subpage rzx50 +@li @subpage ritmix-rzx50 */ diff --git a/arch/mips/mach-xburst/serial.c b/arch/mips/mach-xburst/serial.c deleted file mode 100644 index acf5648..0000000 --- a/arch/mips/mach-xburst/serial.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2013 Antony Pavlov - * - * Based on the linux kernel JZ4740 serial support: - * Copyright (C) 2010, Lars-Peter Clausen - * - * This file is part of barebox. - * See file CREDITS for list of people who contributed to this project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * 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 - -#define JZ_UART_SHIFT 2 - -#define ier (1 << JZ_UART_SHIFT) -#define fcr (2 << JZ_UART_SHIFT) - -static void jz_serial_reg_write(unsigned int val, unsigned long base, - unsigned char reg_offset) -{ - switch (reg_offset) { - case fcr: - val |= 0x10; /* Enable uart module */ - break; - case ier: - val |= (val & 0x4) << 2; - break; - default: - break; - } - - writeb(val & 0xff, (void *)(base + reg_offset)); -} - -struct device_d *jz_add_uart(int id, unsigned long base, unsigned int clock) -{ - struct NS16550_plat *serial_plat; - - serial_plat = xzalloc(sizeof(*serial_plat)); - - serial_plat->shift = JZ_UART_SHIFT; - serial_plat->reg_write = &jz_serial_reg_write; - serial_plat->clock = clock; - - return add_ns16550_device(id, base, 8 << JZ_UART_SHIFT, - IORESOURCE_MEM_8BIT, serial_plat); -} diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 7506f87..0687b3c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_CLK_SOCFPGA) += socfpga.o +obj-$(CONFIG_MACH_MIPS_ATH79) += clk-ar933x.o diff --git a/drivers/clk/clk-ar933x.c b/drivers/clk/clk-ar933x.c new file mode 100644 index 0000000..d983387 --- /dev/null +++ b/drivers/clk/clk-ar933x.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2013 Lucas Stach + * + * Based on the Linux Tegra clock code + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct clk *clks[AR933X_CLK_END]; +static struct clk_onecell_data clk_data; + +struct clk_ar933x { + struct clk clk; + void __iomem *base; + u32 div_shift; + u32 div_mask; + const char *parent; +}; + +static unsigned long clk_ar933x_recalc_rate(struct clk *clk, + unsigned long parent_rate) +{ + struct clk_ar933x *f = container_of(clk, struct clk_ar933x, clk); + unsigned long rate; + unsigned long freq; + u32 clock_ctrl; + u32 cpu_config; + u32 t; + + clock_ctrl = __raw_readl(f->base + AR933X_PLL_CLOCK_CTRL_REG); + + if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { + rate = parent_rate; + } else { + cpu_config = __raw_readl(f->base + AR933X_PLL_CPU_CONFIG_REG); + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & + AR933X_PLL_CPU_CONFIG_REFDIV_MASK; + freq = parent_rate / t; + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & + AR933X_PLL_CPU_CONFIG_NINT_MASK; + freq *= t; + + t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & + AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; + if (t == 0) + t = 1; + + freq >>= t; + + t = ((clock_ctrl >> f->div_shift) & f->div_mask) + 1; + rate = freq / t; + } + + return rate; +} + +struct clk_ops clk_ar933x_ops = { + .recalc_rate = clk_ar933x_recalc_rate, +}; + +static struct clk *clk_ar933x(const char *name, const char *parent, + void __iomem *base, u32 div_shift, u32 div_mask) +{ + struct clk_ar933x *f = xzalloc(sizeof(*f)); + + f->parent = parent; + f->base = base; + f->div_shift = div_shift; + f->div_mask = div_mask; + + f->clk.ops = &clk_ar933x_ops; + f->clk.name = name; + f->clk.parent_names = &f->parent; + f->clk.num_parents = 1; + + clk_register(&f->clk); + + return &f->clk; +} + +static void ar933x_ref_clk_init(void __iomem *base) +{ + u32 t; + unsigned long ref_rate; + + t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); + if (t & AR933X_BOOTSTRAP_REF_CLK_40) + ref_rate = (40 * 1000 * 1000); + else + ref_rate = (25 * 1000 * 1000); + + clks[AR933X_CLK_REF] = clk_fixed("ref", ref_rate); +} + +static void ar933x_pll_init(void __iomem *base) +{ + clks[AR933X_CLK_UART] = clk_fixed_factor("uart", "ref", 1, 1, + CLK_SET_RATE_PARENT); + + clks[AR933X_CLK_CPU] = clk_ar933x("cpu", "ref", base, + AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT, + AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK); + + clks[AR933X_CLK_DDR] = clk_ar933x("ddr", "ref", base, + AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT, + AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK); + + clks[AR933X_CLK_AHB] = clk_ar933x("ahb", "ref", base, + AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT, + AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK); + + clks[AR933X_CLK_WDT] = clk_fixed_factor("wdt", "ahb", 1, 1, + CLK_SET_RATE_PARENT); +} + +static int ar933x_clk_probe(struct device_d *dev) +{ + void __iomem *base; + + base = dev_request_mem_region(dev, 0); + if (!base) + return -EBUSY; + + ar933x_ref_clk_init(base); + ar933x_pll_init(base); + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, + &clk_data); + + return 0; +} + +static __maybe_unused struct of_device_id ar933x_clk_dt_ids[] = { + { + .compatible = "qca,ar933x-clk", + }, { + /* sentinel */ + } +}; + +static struct driver_d ar933x_clk_driver = { + .probe = ar933x_clk_probe, + .name = "ar933x_clk", + .of_compatible = DRV_OF_COMPAT(ar933x_clk_dt_ids), +}; + +static int ar933x_clk_init(void) +{ + return platform_driver_register(&ar933x_clk_driver); +} +postcore_initcall(ar933x_clk_init); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 11fc155..f51c6e6 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -14,6 +14,13 @@ If unsure, say N. +config DRIVER_SERIAL_AR933X + bool "AR933X serial driver" + depends on MACH_MIPS_ATH79 + help + If you have an Atheros AR933X SOC based board and want to use the + built-in UART of the SoC, say Y to this option. + config DRIVER_SERIAL_IMX depends on ARCH_IMX default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 93790b5..e1865f7 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o +obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c new file mode 100644 index 0000000..27cccba --- /dev/null +++ b/drivers/serial/serial_ar933x.c @@ -0,0 +1,204 @@ +/* + * based on linux.git/drivers/tty/serial/serial_ar933x.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serial_ar933x.h" + +#define AR933X_UART_MAX_SCALE 0xff +#define AR933X_UART_MAX_STEP 0xffff + +struct ar933x_uart_priv { + void __iomem *base; + struct clk *clk; +}; + +static inline void ar933x_serial_writel(struct console_device *cdev, + u32 b, int offset) +{ + struct ar933x_uart_priv *priv = cdev->dev->priv; + + cpu_writel(b, priv->base + offset); +} + +static inline u32 ar933x_serial_readl(struct console_device *cdev, + int offset) +{ + struct ar933x_uart_priv *priv = cdev->dev->priv; + + return cpu_readl(priv->base + offset); +} + +/* + * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17)) + * take from linux. + */ +static unsigned long ar933x_uart_get_baud(unsigned int clk, + unsigned int scale, + unsigned int step) +{ + u64 t; + u32 div; + + div = (2 << 16) * (scale + 1); + t = clk; + t *= step; + t += (div / 2); + do_div(t, div); + + return t; +} + +static void ar933x_uart_get_scale_step(unsigned int clk, + unsigned int baud, + unsigned int *scale, + unsigned int *step) +{ + unsigned int tscale; + long min_diff; + + *scale = 0; + *step = 0; + + min_diff = baud; + for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) { + u64 tstep; + int diff; + + tstep = baud * (tscale + 1); + tstep *= (2 << 16); + do_div(tstep, clk); + + if (tstep > AR933X_UART_MAX_STEP) + break; + + diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud); + if (diff < min_diff) { + min_diff = diff; + *scale = tscale; + *step = tstep; + } + } +} + +static int ar933x_serial_setbaudrate(struct console_device *cdev, int baudrate) +{ + struct ar933x_uart_priv *priv = cdev->dev->priv; + unsigned int scale, step; + + ar933x_uart_get_scale_step(clk_get_rate(priv->clk), baudrate, &scale, + &step); + ar933x_serial_writel(cdev, (scale << AR933X_UART_CLOCK_SCALE_S) | step, + AR933X_UART_CLOCK_REG); + + return 0; +} + +static void ar933x_serial_putc(struct console_device *cdev, char ch) +{ + u32 data; + + /* wait transmitter ready */ + data = ar933x_serial_readl(cdev, AR933X_UART_DATA_REG); + while (!(data & AR933X_UART_DATA_TX_CSR)) + data = ar933x_serial_readl(cdev, AR933X_UART_DATA_REG); + + data = (ch & AR933X_UART_DATA_TX_RX_MASK) | AR933X_UART_DATA_TX_CSR; + ar933x_serial_writel(cdev, data, AR933X_UART_DATA_REG); +} + +static int ar933x_serial_tstc(struct console_device *cdev) +{ + u32 rdata; + + rdata = ar933x_serial_readl(cdev, AR933X_UART_DATA_REG); + + return rdata & AR933X_UART_DATA_RX_CSR; +} + +static int ar933x_serial_getc(struct console_device *cdev) +{ + u32 rdata; + + while (!ar933x_serial_tstc(cdev)) + ; + + rdata = ar933x_serial_readl(cdev, AR933X_UART_DATA_REG); + + /* remove the character from the FIFO */ + ar933x_serial_writel(cdev, AR933X_UART_DATA_RX_CSR, + AR933X_UART_DATA_REG); + + return rdata & AR933X_UART_DATA_TX_RX_MASK; +} + +static int ar933x_serial_probe(struct device_d *dev) +{ + struct console_device *cdev; + struct ar933x_uart_priv *priv; + u32 uart_cs; + + cdev = xzalloc(sizeof(struct console_device)); + priv = xzalloc(sizeof(struct ar933x_uart_priv)); + priv->base = dev_request_mem_region(dev, 0); + dev->priv = priv; + + cdev->dev = dev; + cdev->tstc = ar933x_serial_tstc; + cdev->putc = ar933x_serial_putc; + cdev->getc = ar933x_serial_getc; + cdev->setbrg = ar933x_serial_setbaudrate; + + priv->clk = clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(dev, "unable to get UART clock\n"); + return PTR_ERR(priv->clk); + } + + uart_cs = (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) + | AR933X_UART_CS_TX_READY_ORIDE + | AR933X_UART_CS_RX_READY_ORIDE; + ar933x_serial_writel(cdev, uart_cs, AR933X_UART_CS_REG); + /* FIXME: need ar933x_serial_init_port(cdev); */ + + console_register(cdev); + + return 0; +} + +static struct of_device_id ar933x_serial_dt_ids[] = { + { + .compatible = "qca,ar9330-uart", + }, { + /* sentinel */ + }, +}; + +static struct driver_d ar933x_serial_driver = { + .name = "ar933x_serial", + .probe = ar933x_serial_probe, + .of_compatible = DRV_OF_COMPAT(ar933x_serial_dt_ids), +}; +console_platform_driver(ar933x_serial_driver); diff --git a/drivers/serial/serial_ar933x.h b/drivers/serial/serial_ar933x.h new file mode 100644 index 0000000..f55f0fa --- /dev/null +++ b/drivers/serial/serial_ar933x.h @@ -0,0 +1,69 @@ +/* + * Atheros AR933X UART defines + * + * Copyright (C) 2011 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __AR933X_UART_H +#define __AR933X_UART_H + +#include + +#define AR933X_UART_REGS_SIZE 20 +#define AR933X_UART_FIFO_SIZE 16 + +#define AR933X_UART_DATA_REG 0x00 +#define AR933X_UART_CS_REG 0x04 +#define AR933X_UART_CLOCK_REG 0x08 +#define AR933X_UART_INT_REG 0x0c +#define AR933X_UART_INT_EN_REG 0x10 + +#define AR933X_UART_DATA_TX_RX_MASK 0xff +#define AR933X_UART_DATA_RX_CSR BIT(8) +#define AR933X_UART_DATA_TX_CSR BIT(9) + +#define AR933X_UART_CS_PARITY_S 0 +#define AR933X_UART_CS_PARITY_M 0x3 +#define AR933X_UART_CS_PARITY_NONE 0 +#define AR933X_UART_CS_PARITY_ODD 1 +#define AR933X_UART_CS_PARITY_EVEN 2 +#define AR933X_UART_CS_IF_MODE_S 2 +#define AR933X_UART_CS_IF_MODE_M 0x3 +#define AR933X_UART_CS_IF_MODE_NONE 0 +#define AR933X_UART_CS_IF_MODE_DTE 1 +#define AR933X_UART_CS_IF_MODE_DCE 2 +#define AR933X_UART_CS_FLOW_CTRL_S 4 +#define AR933X_UART_CS_FLOW_CTRL_M 0x3 +#define AR933X_UART_CS_DMA_EN BIT(6) +#define AR933X_UART_CS_TX_READY_ORIDE BIT(7) +#define AR933X_UART_CS_RX_READY_ORIDE BIT(8) +#define AR933X_UART_CS_TX_READY BIT(9) +#define AR933X_UART_CS_RX_BREAK BIT(10) +#define AR933X_UART_CS_TX_BREAK BIT(11) +#define AR933X_UART_CS_HOST_INT BIT(12) +#define AR933X_UART_CS_HOST_INT_EN BIT(13) +#define AR933X_UART_CS_TX_BUSY BIT(14) +#define AR933X_UART_CS_RX_BUSY BIT(15) + +#define AR933X_UART_CLOCK_STEP_M 0xffff +#define AR933X_UART_CLOCK_SCALE_M 0xfff +#define AR933X_UART_CLOCK_SCALE_S 16 +#define AR933X_UART_CLOCK_STEP_M 0xffff + +#define AR933X_UART_INT_RX_VALID BIT(0) +#define AR933X_UART_INT_TX_READY BIT(1) +#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2) +#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3) +#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4) +#define AR933X_UART_INT_RX_PARITY_ERR BIT(5) +#define AR933X_UART_INT_RX_BREAK_ON BIT(6) +#define AR933X_UART_INT_RX_BREAK_OFF BIT(7) +#define AR933X_UART_INT_RX_FULL BIT(8) +#define AR933X_UART_INT_TX_EMPTY BIT(9) +#define AR933X_UART_INT_ALLINTS 0x3ff + +#endif /* __AR933X_UART_H */ diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index f1da44b..0c00eb1 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -48,6 +48,7 @@ struct NS16550_plat plat; int access_width; struct clk *clk; + uint32_t fcrval; }; static inline struct ns16550_priv *to_ns16550_priv(struct console_device *cdev) @@ -157,18 +158,13 @@ { unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate); struct ns16550_priv *priv = to_ns16550_priv(cdev); - struct NS16550_plat *plat = &priv->plat; ns16550_write(cdev, LCR_BKSE, lcr); ns16550_write(cdev, baud_divisor & 0xff, dll); ns16550_write(cdev, (baud_divisor >> 8) & 0xff, dlm); ns16550_write(cdev, LCRVAL, lcr); ns16550_write(cdev, MCRVAL, mcr); - - if (plat->flags & NS16650_FLAG_DISABLE_FIFO) - ns16550_write(cdev, FCRVAL & ~FCR_FIFO_EN, fcr); - else - ns16550_write(cdev, FCRVAL, fcr); + ns16550_write(cdev, priv->fcrval, fcr); return 0; } @@ -185,6 +181,15 @@ ns16550_write(cdev, 0x00, ier); } +static void ns16450_serial_init_port(struct console_device *cdev) +{ + struct ns16550_priv *priv = to_ns16550_priv(cdev); + + priv->fcrval &= ~FCR_FIFO_EN; + + ns16550_serial_init_port(cdev); +} + #define omap_mdr1 8 static void ns16550_omap_init_port(struct console_device *cdev) @@ -192,7 +197,17 @@ ns16550_serial_init_port(cdev); ns16550_write(cdev, 0x07, omap_mdr1); /* Disable */ - ns16550_write(cdev, 0x00, omap_mdr1); + ns16550_write(cdev, 0x00, omap_mdr1); +} + +#define JZ_FCR_UME 0x10 /* Uart Module Enable */ + +static void ns16550_jz_init_port(struct console_device *cdev) +{ + struct ns16550_priv *priv = to_ns16550_priv(cdev); + + priv->fcrval |= JZ_FCR_UME; + ns16550_serial_init_port(cdev); } /*********** Exposed Functions **********************************/ @@ -246,6 +261,10 @@ of_property_read_u32(np, "reg-shift", &priv->plat.shift); } +static struct ns16550_drvdata ns16450_drvdata = { + .init_port = ns16450_serial_init_port, +}; + static struct ns16550_drvdata ns16550_drvdata = { .init_port = ns16550_serial_init_port, }; @@ -255,6 +274,10 @@ .linux_console_name = "ttyO", }; +static __maybe_unused struct ns16550_drvdata jz_drvdata = { + .init_port = ns16550_jz_init_port, +}; + /** * @brief Probe entry point -called on the first match for device * @@ -316,6 +339,11 @@ cdev->setbrg = ns16550_setbaudrate; cdev->linux_console_name = devtype->linux_console_name; + if (plat && (plat->flags & NS16650_FLAG_DISABLE_FIFO)) + priv->fcrval = FCRVAL & ~FCR_FIFO_EN; + else + priv->fcrval = FCRVAL; + devtype->init_port(cdev); return console_register(cdev); @@ -328,6 +356,9 @@ static struct of_device_id ns16550_serial_dt_ids[] = { { + .compatible = "ns16450", + .data = (unsigned long)&ns16450_drvdata, + }, { .compatible = "ns16550a", .data = (unsigned long)&ns16550_drvdata, }, { @@ -346,6 +377,12 @@ .data = (unsigned long)&omap_drvdata, }, #endif +#if IS_ENABLED(CONFIG_MACH_MIPS_XBURST) + { + .compatible = "ingenic,jz4740-uart", + .data = (unsigned long)&jz_drvdata, + }, +#endif { /* sentinel */ }, diff --git a/include/dt-bindings/clock/ar933x-clk.h b/include/dt-bindings/clock/ar933x-clk.h new file mode 100644 index 0000000..f048930 --- /dev/null +++ b/include/dt-bindings/clock/ar933x-clk.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2014 Antony Pavlov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __DT_BINDINGS_AR933X_CLK_H +#define __DT_BINDINGS_AR933X_CLK_H + +#define AR933X_CLK_REF 0 +#define AR933X_CLK_UART 1 +#define AR933X_CLK_CPU 2 +#define AR933X_CLK_DDR 3 +#define AR933X_CLK_AHB 4 +#define AR933X_CLK_WDT 5 + +#define AR933X_CLK_END 6 + +#endif /* __DT_BINDINGS_AR933X_CLK_H */