9
0
Fork 0

Merge branch 'for-next/mips'

This commit is contained in:
Sascha Hauer 2014-04-04 09:58:17 +02:00
commit b587c87aac
39 changed files with 966 additions and 81 deletions

View File

@ -58,7 +58,8 @@ MIPS type:
@li @subpage dlink_dir_320
@li @subpage loongson_ls1b
@li @subpage qemu_malta
@li @subpage rzx50
@li @subpage ritmix-rzx50
@li @subpage tplink-mr3020
*/

View File

@ -54,6 +54,19 @@ config MACH_MIPS_AR231X
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 @@ endchoice
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

View File

@ -78,6 +78,9 @@ board-$(CONFIG_BOARD_QEMU_MALTA) := qemu-malta
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 @@ machine-$(CONFIG_MACH_MIPS_LOONGSON) := loongson
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))

View File

@ -0,0 +1 @@
obj-y += serial.o

View File

@ -1,4 +1,4 @@
/** @page rzx50 Ritmix RZX-50 game console
/** @page ritmix-rzx50 Ritmix RZX-50 game console
Ritmix RZX-50 is a portable game console for the Russian market.

View File

@ -17,16 +17,11 @@
#include <common.h>
#include <init.h>
#include <mach/devices.h>
#include <mach/jz4750d_regs.h>
static int rzx50_console_init(void)
static int rzx50_hostname_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);
console_initcall(rzx50_hostname_init);

View File

@ -1 +0,0 @@
obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o

View File

@ -0,0 +1 @@
obj-y += board.o

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* 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 <common.h>
#include <init.h>
static int model_hostname_init(void)
{
barebox_set_hostname("mr3020");
return 0;
}
postcore_initcall(model_hostname_init);

View File

@ -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/
*/

View File

@ -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

26
arch/mips/dts/ar9331.dtsi Normal file
View File

@ -0,0 +1,26 @@
#include <dt-bindings/clock/ar933x-clk.h>
#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>;
};
};
};

View File

@ -0,0 +1 @@
../../../../include/dt-bindings

35
arch/mips/dts/jz4755.dtsi Normal file
View File

@ -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";
};
};
};

View File

@ -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>;

View File

@ -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";
};

View File

@ -0,0 +1,16 @@
/dts-v1/;
#include <ar9331.dtsi>
/ {
model = "TP-LINK MR3020";
compatible = "tplink,mr3020";
memory {
reg = <0x00000000 0x2000000>;
};
};
&serial0 {
status = "okay";
};

View File

@ -69,6 +69,8 @@ SECTIONS
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
.oftables : { BAREBOX_CLK_TABLE() }
.dtb : { BAREBOX_DTB() }
_edata = .;

View File

@ -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

View File

@ -0,0 +1 @@
obj-y += reset.o

View File

@ -0,0 +1,64 @@
/*
* Atheros AR71XX/AR724X/AR913X SoC register definitions
*
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* 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 <linux/bitops.h>
#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 */

View File

@ -0,0 +1,33 @@
/*
* Atheros AR71XX/AR724X/AR913X common definitions
*
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* 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 <common.h>
#include <io.h>
#include <asm/memory.h>
#include <mach/ar71xx_regs.h>
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 */

View File

@ -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 <io.h>
#include <linux/bitops.h>
#include <asm/addrspace.h>
#include <mach/ar71xx_regs.h>
#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__ */

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2013 Du Huanpeng <u74147@gmail.com>
*
* 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 <common.h>
#include <mach/ath79.h>
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);

View File

@ -20,6 +20,9 @@
#define MALTA_PIIX4_UART0 0xb80003f8
#define MALTA_CBUS_UART 0xbf000900
#define MALTA_CBUS_UART_SHIFT 3
/*
* Reset register.
*/

View File

@ -1,2 +1 @@
obj-y += serial.o
obj-$(CONFIG_CPU_JZ4755) += csrc-jz4750.o reset-jz4750.o

View File

@ -2,6 +2,6 @@
@section xburst_boards XBurst-based boards
@li @subpage rzx50
@li @subpage ritmix-rzx50
*/

View File

@ -1,60 +0,0 @@
/*
* Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
*
* Based on the linux kernel JZ4740 serial support:
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
*
* 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 <common.h>
#include <ns16550.h>
#include <io.h>
#include <mach/devices.h>
#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);
}

View File

@ -6,3 +6,4 @@ obj-$(CONFIG_ARCH_MVEBU) += mvebu/
obj-$(CONFIG_ARCH_MXS) += mxs/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_CLK_SOCFPGA) += socfpga.o
obj-$(CONFIG_MACH_MIPS_ATH79) += clk-ar933x.o

175
drivers/clk/clk-ar933x.c Normal file
View File

@ -0,0 +1,175 @@
/*
* Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <common.h>
#include <init.h>
#include <io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/ath79.h>
#include <dt-bindings/clock/ar933x-clk.h>
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);

View File

@ -14,6 +14,13 @@ config SERIAL_AMBA_PL011
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

View File

@ -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

View File

@ -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 <common.h>
#include <driver.h>
#include <init.h>
#include <malloc.h>
#include <io.h>
#include <asm-generic/div64.h>
#include <linux/clk.h>
#include <linux/err.h>
#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);

View File

@ -0,0 +1,69 @@
/*
* Atheros AR933X UART defines
*
* Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
*
* 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 <linux/bitops.h>
#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 */

View File

@ -48,6 +48,7 @@ struct ns16550_priv {
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 @@ static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate)
{
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 @@ static void ns16550_serial_init_port(struct console_device *cdev)
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 @@ static void ns16550_omap_init_port(struct console_device *cdev)
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 @@ static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv)
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 @@ static __maybe_unused struct ns16550_drvdata omap_drvdata = {
.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 @@ static int ns16550_probe(struct device_d *dev)
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 @@ err:
static struct of_device_id ns16550_serial_dt_ids[] = {
{
.compatible = "ns16450",
.data = (unsigned long)&ns16450_drvdata,
}, {
.compatible = "ns16550a",
.data = (unsigned long)&ns16550_drvdata,
}, {
@ -345,6 +376,12 @@ static struct of_device_id ns16550_serial_dt_ids[] = {
.compatible = "ti,omap4-uart",
.data = (unsigned long)&omap_drvdata,
},
#endif
#if IS_ENABLED(CONFIG_MACH_MIPS_XBURST)
{
.compatible = "ingenic,jz4740-uart",
.data = (unsigned long)&jz_drvdata,
},
#endif
{
/* sentinel */

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* 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 */