- bmips: add BCRM NAND support for BCM6368, BCM6328, BCM6362 and BCM63268 SoCs

- bmips: various small fixes
 - mtmips: add new drivers for clock, reset-controller and pinctrl
 - mtmips: add support for high speed UART
 - mtmips: update/enhance drivers for SPI and ethernet
 - mtmips: add support for MMC
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEiQkHUH+J02LLC9InKPlOlyTyXBgFAl2zFisACgkQKPlOlyTy
 XBgf9RAAkNwLjqUcBz3Ob1briRG5HF4D6bZCpjtkTIO8a2fanUHbSehh30TX8x2X
 z0t/9Sd4OZwAeTxfQ/AlbbVdiB9IMgEb6lJ30Vr88MRNoPhABIQ8hw5xAzFi/6x9
 88YolS/HQo6iR9rzSlaKjdIHhPTH5oQzRJ3JLqSwZzfUNy+zqINEhs3SYCnD2lyV
 gTgiIT3Y5nKrhVHPUCy+jQG+wwWej2NFgwn71vR3/PSQJwxBuasg0qqOKD9hRtpC
 XL6VErE7bf00elO8xjEObYrmB2FpffXJdkazS2HtRYNyKx0quaRNXJt7wqxEVP9L
 M6SmL+S7zBFAetc/iyrlaakPvn7ImehSZkgLYaTPc3yzO+6bgq9tLfBERn/B/s5g
 YyIzPGF66L96nuu0eVGCgSoUBjzBE8l2QTI8dho5xJxjWAUJOWSB0egqfFZzYVFu
 4X37w6Z0j6uTK2oEl7KgJdc0JsZRsAJ8ZiqgOeNeMUTl2RnjGt0Oa7E24Va3n3hM
 5vuEba9nPUFmdC5vlSd2RUK/dB587uKV93r5j54U62clpbiK+VMaRuRVX64ytZvB
 B/0fKyCu+y7bxeZe4/X27jBUOk5yCuxbNI66m+cnnvfHqEmhz5PfDCEK1Dr29oqf
 sCJLgTr7ahyuW4kEoL7KCOBEugPI85fp8/OlqC63M6/Kft0w5sA=
 =6G/J
 -----END PGP SIGNATURE-----

Merge tag 'mips-pull-2019-10-25' of git://git.denx.de/u-boot-mips

- bmips: add BCRM NAND support for BCM6368, BCM6328, BCM6362 and BCM63268 SoCs
- bmips: various small fixes
- mtmips: add new drivers for clock, reset-controller and pinctrl
- mtmips: add support for high speed UART
- mtmips: update/enhance drivers for SPI and ethernet
- mtmips: add support for MMC
This commit is contained in:
Tom Rini 2019-10-25 20:07:24 -04:00
commit ffc379b42c
75 changed files with 2331 additions and 549 deletions

View File

@ -76,12 +76,18 @@ config ARCH_BMIPS
config ARCH_MTMIPS
bool "Support MediaTek MIPS platforms"
select CLK
imply CMD_DM
select DISPLAY_CPUINFO
select DM
imply DM_ETH
imply DM_GPIO
select DM_RESET
select DM_SERIAL
select PINCTRL
select PINMUX
select PINCONF
select RESET_MTMIPS
imply DM_SPI
imply DM_SPI_FLASH
select LAST_STAGE_INIT
@ -408,9 +414,17 @@ config SYS_ICACHE_LINE_SIZE
help
The size of L1 Icache lines, if known at compile time.
config SYS_SCACHE_LINE_SIZE
int
default 0
help
The size of L2 cache lines, if known at compile time.
config SYS_CACHE_SIZE_AUTO
def_bool y if SYS_DCACHE_SIZE = 0 && SYS_ICACHE_SIZE = 0 && \
SYS_DCACHE_LINE_SIZE = 0 && SYS_ICACHE_LINE_SIZE = 0
SYS_DCACHE_LINE_SIZE = 0 && SYS_ICACHE_LINE_SIZE = 0 && \
SYS_SCACHE_LINE_SIZE = 0
help
Select this (or let it be auto-selected by not defining any cache
sizes) in order to allow U-Boot to automatically detect the sizes

View File

@ -10,6 +10,7 @@ dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb
dtb-$(CONFIG_BOARD_BROADCOM_BCM968380GERG) += brcm,bcm968380gerg.dtb
dtb-$(CONFIG_BOARD_COMTREND_AR5315U) += comtrend,ar-5315u.dtb
dtb-$(CONFIG_BOARD_COMTREND_AR5387UN) += comtrend,ar-5387un.dtb
dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
@ -19,10 +20,9 @@ dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
dtb-$(CONFIG_BOARD_SFR_NB4_SER) += sfr,nb4-ser.dtb
dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
dtb-$(CONFIG_SOC_BMIPS_BCM6358) += sfr,nb4-ser.dtb
dtb-$(CONFIG_SOC_BMIPS_BCM6838) += brcm,bcm968380gerg.dtb
dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb
dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb
dtb-$(CONFIG_SOC_JR2) += jr2_pcb110.dtb jr2_pcb111.dtb serval2_pcb112.dtb

View File

@ -141,6 +141,24 @@
status = "disabled";
};
nand: nand-controller@10000200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,nand-bcm6368",
"brcm,brcmnand-v4.0",
"brcm,brcmnand";
reg-names = "nand",
"nand-cache",
"nand-int-base";
reg = <0x10000200 0x180>,
<0x10000600 0x200>,
<0x100000b0 0x10>;
clocks = <&periph_clk BCM63268_CLK_NAND>;
clock-names = "nand";
status = "disabled";
};
periph_pwr: power-controller@1000184c {
compatible = "brcm,bcm6328-power-domain";
reg = <0x1000184c 0x4>;

View File

@ -124,6 +124,22 @@
status = "disabled";
};
nand: nand-controller@10000200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,nand-bcm6368",
"brcm,brcmnand-v2.2",
"brcm,brcmnand";
reg-names = "nand",
"nand-cache",
"nand-int-base";
reg = <0x10000200 0x180>,
<0x10000400 0x200>,
<0x100000b0 0x10>;
status = "disabled";
};
leds: led-controller@10000800 {
compatible = "brcm,bcm6328-leds";
reg = <0x10000800 0x24>;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
#include <dt-bindings/clock/bcm6362-clock.h>
@ -135,6 +135,24 @@
status = "disabled";
};
nand: nand-controller@10000200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,nand-bcm6368",
"brcm,brcmnand-v2.2",
"brcm,brcmnand";
reg-names = "nand",
"nand-cache",
"nand-int-base";
reg = <0x10000200 0x180>,
<0x10000600 0x200>,
<0x100000b0 0x10>;
clocks = <&periph_clk BCM6362_CLK_NAND>;
clock-names = "nand";
status = "disabled";
};
lsspi: spi@10000800 {
compatible = "brcm,bcm6358-spi";
reg = <0x10000800 0x70c>;

View File

@ -146,6 +146,24 @@
status = "disabled";
};
nand: nand-controller@10000200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,nand-bcm6368",
"brcm,brcmnand-v2.1",
"brcm,brcmnand";
reg-names = "nand",
"nand-cache",
"nand-int-base";
reg = <0x10000200 0x180>,
<0x10000600 0x200>,
<0x100000b0 0x10>;
clocks = <&periph_clk BCM6368_CLK_NAND>;
clock-names = "nand";
status = "disabled";
};
spi: spi@10000800 {
compatible = "brcm,bcm6358-spi";
reg = <0x10000800 0x70c>;

View File

@ -99,6 +99,19 @@
};
};
&nand {
status = "okay";
nandcs@0 {
compatible = "brcm,nandcs";
reg = <0>;
nand-ecc-strength = <15>;
nand-ecc-step-size = <512>;
nand-on-flash-bbt;
brcm,nand-oob-sector-size = <64>;
};
};
&ohci {
status = "okay";
};

View File

@ -85,15 +85,26 @@
};
};
&pinctrl {
state_default: pin_state {
p0led {
groups = "p0led_a";
function = "led";
};
};
};
&uart0 {
status = "okay";
clock-frequency = <40000000>;
};
&spi0 {
status = "okay";
num-cs = <2>;
pinctrl-names = "default";
pinctrl-0 = <&spi_dual_pins>;
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
@ -110,3 +121,9 @@
reg = <1>;
};
};
&eth {
pinctrl-names = "default";
pinctrl-0 = <&ephy_iot_mode>;
mediatek,poll-link-phy = <0>;
};

View File

@ -26,9 +26,17 @@
};
};
&pinctrl {
state_default: pin_state {
p0led {
groups = "p0led_a";
function = "led";
};
};
};
&uart2 {
status = "okay";
clock-frequency = <40000000>;
};
&spi0 {
@ -43,3 +51,9 @@
reg = <0>;
};
};
&eth {
pinctrl-names = "default";
pinctrl-0 = <&ephy_iot_mode>;
mediatek,poll-link-phy = <0>;
};

View File

@ -1,4 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/clock/mt7628-clk.h>
#include <dt-bindings/reset/mt7628-reset.h>
/ {
#address-cells = <1>;
@ -16,11 +18,6 @@
};
};
resetc: reset-controller {
compatible = "ralink,rt2880-reset";
#reset-cells = <1>;
};
cpuintc: interrupt-controller {
#address-cells = <0>;
#interrupt-cells = <1>;
@ -28,6 +25,14 @@
compatible = "mti,cpu-interrupt-controller";
};
clk48m: clk48m@0 {
compatible = "fixed-clock";
clock-frequency = <48000000>;
#clock-cells = <0>;
};
palmbus@10000000 {
compatible = "palmbus", "simple-bus";
reg = <0x10000000 0x200000>;
@ -48,11 +53,175 @@
mask = <0x1>;
};
clkctrl: clkctrl@0x2c {
reg = <0x2c 0x8>, <0x10 0x4>;
reg-names = "syscfg0", "clkcfg";
compatible = "mediatek,mt7628-clk";
#clock-cells = <1>;
u-boot,dm-pre-reloc;
};
rstctrl: rstctrl@0x34 {
reg = <0x34 0x4>;
compatible = "mediatek,mtmips-reset";
#reset-cells = <1>;
};
pinctrl: pinctrl@60 {
compatible = "mediatek,mt7628-pinctrl";
reg = <0x3c 0x2c>, <0x1300 0x100>;
reg-names = "gpiomode", "padconf";
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
state_default: pin_state {
};
spi_single_pins: spi_single_pins {
groups = "spi";
function = "spi";
};
spi_dual_pins: spi_dual_pins {
spi_master_pins {
groups = "spi";
function = "spi";
};
spi_cs1_pin {
groups = "spi cs1";
function = "spi cs1";
};
};
uart0_pins: uart0_pins {
groups = "uart0";
function = "uart0";
};
uart1_pins: uart1_pins {
groups = "uart1";
function = "uart1";
};
uart2_pins: uart2_pins {
groups = "uart2";
function = "uart2";
};
i2c_pins: i2c_pins {
groups = "i2c";
function = "i2c";
};
ephy_iot_mode: ephy_iot_mode {
ephy4_1_dis {
groups = "ephy4_1_pad";
function = "digital";
};
ephy0_en {
groups = "ephy0";
function = "enable";
};
};
ephy_router_mode: ephy_router_mode {
ephy4_1_en {
groups = "ephy4_1_pad";
function = "analog";
};
ephy0_en {
groups = "ephy0";
function = "enable";
};
};
sd_iot_mode: sd_iot_mode {
ephy4_1_dis {
groups = "ephy4_1_pad";
function = "digital";
};
sdxc_en {
groups = "sdmode";
function = "sdxc";
};
sdxc_iot_mode {
groups = "sd router";
function = "iot";
};
sd_clk_pad {
pins = "sd_clk";
drive-strength-4g = <8>;
};
};
sd_router_mode: sd_router_mode {
sdxc_router_mode {
groups = "sd router";
function = "router";
};
sdxc_map_pins {
groups = "gpio0", "i2s", "sdmode", \
"i2c", "uart1";
function = "gpio";
};
sd_clk_pad {
pins = "gpio0";
drive-strength-28 = <8>;
};
};
emmc_iot_8bit_mode: emmc_iot_8bit_mode {
ephy4_1_dis {
groups = "ephy4_1_pad";
function = "digital";
};
emmc_en {
groups = "sdmode";
function = "sdxc";
};
emmc_iot_mode {
groups = "sd router";
function = "iot";
};
emmc_d4_d5 {
groups = "uart2";
function = "sdxc d5 d4";
};
emmc_d6 {
groups = "pwm1";
function = "sdxc d6";
};
emmc_d7 {
groups = "pwm0";
function = "sdxc d7";
};
sd_clk_pad {
pins = "sd_clk";
drive-strength-4g = <8>;
};
};
};
watchdog: watchdog@100 {
compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt";
reg = <0x100 0x30>;
resets = <&resetc 8>;
resets = <&rstctrl MT7628_TIMER_RST>;
reset-names = "wdt";
interrupt-parent = <&intc>;
@ -66,7 +235,7 @@
interrupt-controller;
#interrupt-cells = <1>;
resets = <&resetc 9>;
resets = <&rstctrl MT7628_INT_RST>;
reset-names = "intc";
interrupt-parent = <&cpuintc>;
@ -89,6 +258,9 @@
compatible = "mtk,mt7628-gpio", "mtk,mt7621-gpio";
reg = <0x600 0x100>;
resets = <&rstctrl MT7628_PIO_RST>;
reset-names = "pio";
interrupt-parent = <&intc>;
interrupts = <6>;
@ -117,17 +289,26 @@
spi0: spi@b00 {
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x40>;
resets = <&rstctrl MT7628_SPI_RST>;
reset-names = "spi";
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <200000000>;
clocks = <&clkctrl CLK_SPI>;
};
uart0: uartlite@c00 {
compatible = "ns16550a";
compatible = "mediatek,hsuart", "ns16550a";
reg = <0xc00 0x100>;
resets = <&resetc 12>;
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
clocks = <&clkctrl CLK_UART0>;
resets = <&rstctrl MT7628_UART0_RST>;
reset-names = "uart0";
interrupt-parent = <&intc>;
@ -137,10 +318,15 @@
};
uart1: uart1@d00 {
compatible = "ns16550a";
compatible = "mediatek,hsuart", "ns16550a";
reg = <0xd00 0x100>;
resets = <&resetc 19>;
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins>;
clocks = <&clkctrl CLK_UART1>;
resets = <&rstctrl MT7628_UART1_RST>;
reset-names = "uart1";
interrupt-parent = <&intc>;
@ -150,10 +336,15 @@
};
uart2: uart2@e00 {
compatible = "ns16550a";
compatible = "mediatek,hsuart", "ns16550a";
reg = <0xe00 0x100>;
resets = <&resetc 20>;
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
clocks = <&clkctrl CLK_UART2>;
resets = <&rstctrl MT7628_UART2_RST>;
reset-names = "uart2";
interrupt-parent = <&intc>;
@ -163,11 +354,14 @@
};
};
eth@10110000 {
eth: eth@10110000 {
compatible = "mediatek,mt7628-eth";
reg = <0x10100000 0x10000
0x10110000 0x8000>;
resets = <&rstctrl MT7628_EPHY_RST>;
reset-names = "ephy";
syscon = <&sysc>;
};
@ -178,8 +372,12 @@
#phy-cells = <0>;
ralink,sysctl = <&sysc>;
resets = <&resetc 22 &resetc 25>;
reset-names = "host", "device";
resets = <&rstctrl MT7628_UPHY_RST>;
reset-names = "phy";
clocks = <&clkctrl CLK_UPHY>;
clock-names = "cg";
};
ehci@101c0000 {
@ -192,4 +390,18 @@
interrupt-parent = <&intc>;
interrupts = <18>;
};
mmc: mmc@10130000 {
compatible = "mediatek,mt7620-mmc";
reg = <0x10130000 0x4000>;
builtin-cd = <1>;
r_smpl = <1>;
clocks = <&clk48m>, <&clkctrl CLK_SDXC>;
clock-names = "source", "hclk";
resets = <&rstctrl MT7628_SDXC_RST>;
status = "disabled";
};
};

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
/dts-v1/;

View File

@ -87,7 +87,7 @@ static inline unsigned long scache_line_size(void)
#ifdef CONFIG_MIPS_L2_CACHE
return gd->arch.l2_line_size;
#else
return 0;
return CONFIG_SYS_SCACHE_LINE_SIZE;
#endif
}

View File

@ -13,6 +13,8 @@ choice
config SOC_MT7628
bool "MT7628"
select MIPS_L1_CACHE_SHIFT_5
select PINCTRL_MT7628
select MTK_SERIAL
help
This supports MediaTek MT7628/MT7688.

View File

@ -1,5 +1,5 @@
NETGEAR DGND3700V2 BOARD
M: Álvaro Fernández Rojas <noltari@gmail.com>
M: Álvaro Fernández Rojas <noltari@gmail.com>
S: Maintained
F: board/netgear/dgnd3700v2/
F: include/configs/netgear_dgnd3700v2.h

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
#include <common.h>

View File

@ -25,6 +25,7 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_NAND=y
CONFIG_CMD_USB=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
@ -37,6 +38,10 @@ CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_MTD=y
CONFIG_NAND=y
CONFIG_NAND_BRCMNAND=y
CONFIG_NAND_BRCMNAND_6368=y
CONFIG_DM_ETH=y
CONFIG_BCM6368_ETH=y
CONFIG_PHY=y

View File

@ -45,7 +45,6 @@ CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_HAVE_BLOCK_DEVICE=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
@ -60,14 +59,8 @@ CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_XMC=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_MTD_UBI_BEB_LIMIT=22
CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y

View File

@ -48,7 +48,6 @@ CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_HAVE_BLOCK_DEVICE=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
@ -63,14 +62,8 @@ CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_XMC=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_MTD_UBI_BEB_LIMIT=22
CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y

View File

@ -35,7 +35,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
@ -46,15 +45,9 @@ CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
CONFIG_MT76X8_USB_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y

View File

@ -39,7 +39,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
@ -50,15 +49,9 @@ CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
CONFIG_MT76X8_USB_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y

View File

@ -16,6 +16,7 @@ obj-y += imx/
obj-y += tegra/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_MESON) += meson/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SOCFPGA) += altera/

View File

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SOC_MT7628) += clk-mt7628.o

View File

@ -0,0 +1,158 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-bindings/clock/mt7628-clk.h>
#include <linux/bitops.h>
#include <linux/io.h>
/* SYSCFG0 */
#define XTAL_40M_SEL BIT(6)
/* CLKCFG0 */
#define CLKCFG0_REG 0x0
#define PERI_CLK_FROM_XTAL_SEL BIT(4)
#define CPU_PLL_FROM_BBP BIT(1)
#define CPU_PLL_FROM_XTAL BIT(0)
/* CLKCFG1 */
#define CLKCFG1_REG 0x4
#define CLK_SRC_CPU -1
#define CLK_SRC_CPU_D2 -2
#define CLK_SRC_SYS -3
#define CLK_SRC_XTAL -4
#define CLK_SRC_PERI -5
struct mt7628_clk_priv {
void __iomem *base;
int cpu_clk;
int sys_clk;
int xtal_clk;
};
static const int mt7628_clks[] = {
[CLK_SYS] = CLK_SRC_SYS,
[CLK_CPU] = CLK_SRC_CPU,
[CLK_XTAL] = CLK_SRC_XTAL,
[CLK_PWM] = CLK_SRC_PERI,
[CLK_MIPS_CNT] = CLK_SRC_CPU_D2,
[CLK_UART2] = CLK_SRC_PERI,
[CLK_UART1] = CLK_SRC_PERI,
[CLK_UART0] = CLK_SRC_PERI,
[CLK_SPI] = CLK_SRC_SYS,
[CLK_I2C] = CLK_SRC_PERI,
};
static ulong mt7628_clk_get_rate(struct clk *clk)
{
struct mt7628_clk_priv *priv = dev_get_priv(clk->dev);
u32 val;
if (clk->id >= ARRAY_SIZE(mt7628_clks))
return 0;
switch (mt7628_clks[clk->id]) {
case CLK_SRC_CPU:
return priv->cpu_clk;
case CLK_SRC_CPU_D2:
return priv->cpu_clk / 2;
case CLK_SRC_SYS:
return priv->sys_clk;
case CLK_SRC_XTAL:
return priv->xtal_clk;
case CLK_SRC_PERI:
val = readl(priv->base + CLKCFG0_REG);
if (val & PERI_CLK_FROM_XTAL_SEL)
return priv->xtal_clk;
else
return 40000000;
default:
return mt7628_clks[clk->id];
}
}
static int mt7628_clk_enable(struct clk *clk)
{
struct mt7628_clk_priv *priv = dev_get_priv(clk->dev);
if (clk->id > 31)
return -1;
setbits_32(priv->base + CLKCFG1_REG, BIT(clk->id));
return 0;
}
static int mt7628_clk_disable(struct clk *clk)
{
struct mt7628_clk_priv *priv = dev_get_priv(clk->dev);
if (clk->id > 31)
return -1;
clrbits_32(priv->base + CLKCFG1_REG, BIT(clk->id));
return 0;
}
const struct clk_ops mt7628_clk_ops = {
.enable = mt7628_clk_enable,
.disable = mt7628_clk_disable,
.get_rate = mt7628_clk_get_rate,
};
static int mt7628_clk_probe(struct udevice *dev)
{
struct mt7628_clk_priv *priv = dev_get_priv(dev);
void __iomem *syscfg_base;
u32 val;
priv->base = (void __iomem *)dev_remap_addr_index(dev, 0);
if (!priv->base)
return -EINVAL;
syscfg_base = (void __iomem *)dev_remap_addr_index(dev, 1);
if (!syscfg_base)
return -EINVAL;
val = readl(syscfg_base);
if (val & XTAL_40M_SEL)
priv->xtal_clk = 40000000;
else
priv->xtal_clk = 25000000;
val = readl(priv->base + CLKCFG0_REG);
if (val & CPU_PLL_FROM_BBP)
priv->cpu_clk = 480000000;
else if (val & CPU_PLL_FROM_XTAL)
priv->cpu_clk = priv->xtal_clk;
else if (priv->xtal_clk == 40000000)
priv->cpu_clk = 580000000; /* (xtal_freq / 2) * 29 */
else
priv->cpu_clk = 575000000; /* xtal_freq * 23 */
priv->sys_clk = priv->cpu_clk / 3;
return 0;
}
static const struct udevice_id mt7628_clk_ids[] = {
{ .compatible = "mediatek,mt7628-clk" },
{ }
};
U_BOOT_DRIVER(mt7628_clk) = {
.name = "mt7628-clk",
.id = UCLASS_CLK,
.of_match = mt7628_clk_ids,
.probe = mt7628_clk_probe,
.priv_auto_alloc_size = sizeof(struct mt7628_clk_priv),
.ops = &mt7628_clk_ops,
};

View File

@ -698,7 +698,7 @@ config FTSDC010_SDIO
config MMC_MTK
bool "MediaTek SD/MMC Card Interface support"
depends on ARCH_MEDIATEK
depends on ARCH_MEDIATEK || ARCH_MTMIPS
depends on BLK && DM_MMC
depends on OF_CONTROL
help

View File

@ -217,6 +217,7 @@ struct mtk_sd_regs {
struct msdc_compatible {
u8 clk_div_bits;
u8 sclk_cycle_shift;
bool pad_tune0;
bool async_fifo;
bool data_tune;
@ -269,6 +270,7 @@ struct msdc_host {
/* whether to use gpio detection or built-in hw detection */
bool builtin_cd;
bool cd_active_high;
/* card detection / write protection GPIOs */
#if CONFIG_IS_ENABLED(DM_GPIO)
@ -664,7 +666,7 @@ static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
{
u32 timeout, clk_ns;
u32 timeout, clk_ns, shift;
u32 mode = 0;
host->timeout_ns = ns;
@ -673,10 +675,11 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
if (host->sclk == 0) {
timeout = 0;
} else {
shift = host->dev_comp->sclk_cycle_shift;
clk_ns = 1000000000UL / host->sclk;
timeout = (ns + clk_ns - 1) / clk_ns + clks;
/* unit is 1048576 sclk cycles */
timeout = (timeout + (0x1 << 20) - 1) >> 20;
timeout = (timeout + (0x1 << shift) - 1) >> shift;
if (host->dev_comp->clk_div_bits == 8)
mode = (readl(&host->base->msdc_cfg) &
MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;
@ -850,7 +853,9 @@ static int msdc_ops_get_cd(struct udevice *dev)
if (host->builtin_cd) {
val = readl(&host->base->msdc_ps);
return !(val & MSDC_PS_CDSTS);
val = !!(val & MSDC_PS_CDSTS);
return !val ^ host->cd_active_high;
}
#if CONFIG_IS_ENABLED(DM_GPIO)
@ -1301,7 +1306,7 @@ static int msdc_drv_probe(struct udevice *dev)
host->mmc = &plat->mmc;
host->timeout_ns = 100000000;
host->timeout_clks = 3 * 1048576;
host->timeout_clks = 3 * (1 << host->dev_comp->sclk_cycle_shift);
#ifdef CONFIG_PINCTRL
pinctrl_select_state(dev, "default");
@ -1353,6 +1358,7 @@ static int msdc_ofdata_to_platdata(struct udevice *dev)
host->latch_ck = dev_read_u32_default(dev, "latch-ck", 0);
host->r_smpl = dev_read_u32_default(dev, "r_smpl", 0);
host->builtin_cd = dev_read_u32_default(dev, "builtin-cd", 0);
host->cd_active_high = dev_read_bool(dev, "cd-active-high");
return 0;
}
@ -1374,8 +1380,20 @@ static const struct dm_mmc_ops msdc_ops = {
#endif
};
static const struct msdc_compatible mt7620_compat = {
.clk_div_bits = 8,
.sclk_cycle_shift = 16,
.pad_tune0 = false,
.async_fifo = false,
.data_tune = false,
.busy_check = false,
.stop_clk_fix = false,
.enhance_rx = false
};
static const struct msdc_compatible mt7623_compat = {
.clk_div_bits = 12,
.sclk_cycle_shift = 20,
.pad_tune0 = true,
.async_fifo = true,
.data_tune = true,
@ -1386,6 +1404,7 @@ static const struct msdc_compatible mt7623_compat = {
static const struct msdc_compatible mt8516_compat = {
.clk_div_bits = 12,
.sclk_cycle_shift = 20,
.pad_tune0 = true,
.async_fifo = true,
.data_tune = true,
@ -1395,6 +1414,7 @@ static const struct msdc_compatible mt8516_compat = {
static const struct msdc_compatible mt8183_compat = {
.clk_div_bits = 12,
.sclk_cycle_shift = 20,
.pad_tune0 = true,
.async_fifo = true,
.data_tune = true,
@ -1403,6 +1423,7 @@ static const struct msdc_compatible mt8183_compat = {
};
static const struct udevice_id msdc_ids[] = {
{ .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat },
{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
{ .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat },
{ .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat },

View File

@ -72,6 +72,12 @@ config NAND_BRCMNAND
Enable the driver for NAND flash on platforms using a Broadcom NAND
controller.
config NAND_BRCMNAND_6368
bool "Support Broadcom NAND controller on bcm6368"
depends on NAND_BRCMNAND && ARCH_BMIPS
help
Enable support for broadcom nand driver on bcm6368.
config NAND_BRCMNAND_6838
bool "Support Broadcom NAND controller on bcm6838"
depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838

View File

@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_NAND_BRCMNAND_6368) += bcm6368_nand.o
obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o
obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o
obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o

View File

@ -0,0 +1,117 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <asm/io.h>
#include <memalign.h>
#include <nand.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <dm.h>
#include "brcmnand.h"
struct bcm6368_nand_soc {
struct brcmnand_soc soc;
void __iomem *base;
};
#define soc_to_priv(_soc) container_of(_soc, struct bcm6368_nand_soc, soc)
#define BCM6368_NAND_INT 0x00
#define BCM6368_NAND_STATUS_SHIFT 0
#define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT)
#define BCM6368_NAND_ENABLE_SHIFT 16
#define BCM6368_NAND_ENABLE_MASK (0xffff << BCM6368_NAND_ENABLE_SHIFT)
enum {
BCM6368_NP_READ = BIT(0),
BCM6368_BLOCK_ERASE = BIT(1),
BCM6368_COPY_BACK = BIT(2),
BCM6368_PAGE_PGM = BIT(3),
BCM6368_CTRL_READY = BIT(4),
BCM6368_DEV_RBPIN = BIT(5),
BCM6368_ECC_ERR_UNC = BIT(6),
BCM6368_ECC_ERR_CORR = BIT(7),
};
static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc)
{
struct bcm6368_nand_soc *priv = soc_to_priv(soc);
void __iomem *mmio = priv->base + BCM6368_NAND_INT;
u32 val = brcmnand_readl(mmio);
if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) {
/* Ack interrupt */
val &= ~BCM6368_NAND_STATUS_MASK;
val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT;
brcmnand_writel(val, mmio);
return true;
}
return false;
}
static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en)
{
struct bcm6368_nand_soc *priv = soc_to_priv(soc);
void __iomem *mmio = priv->base + BCM6368_NAND_INT;
u32 val = brcmnand_readl(mmio);
/* Don't ack any interrupts */
val &= ~BCM6368_NAND_STATUS_MASK;
if (en)
val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT;
else
val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT);
brcmnand_writel(val, mmio);
}
static int bcm6368_nand_probe(struct udevice *dev)
{
struct bcm6368_nand_soc *priv = dev_get_priv(dev);
struct brcmnand_soc *soc = &priv->soc;
priv->base = dev_remap_addr_name(dev, "nand-int-base");
if (!priv->base)
return -EINVAL;
soc->ctlrdy_ack = bcm6368_nand_intc_ack;
soc->ctlrdy_set_enabled = bcm6368_nand_intc_set;
/* Disable and ack all interrupts */
brcmnand_writel(0, priv->base + BCM6368_NAND_INT);
brcmnand_writel(BCM6368_NAND_STATUS_MASK,
priv->base + BCM6368_NAND_INT);
return brcmnand_probe(dev, soc);
}
static const struct udevice_id bcm6368_nand_dt_ids[] = {
{
.compatible = "brcm,nand-bcm6368",
},
{ /* sentinel */ }
};
U_BOOT_DRIVER(bcm6368_nand) = {
.name = "bcm6368-nand",
.id = UCLASS_MTD,
.of_match = bcm6368_nand_dt_ids,
.probe = bcm6368_nand_probe,
.priv_auto_alloc_size = sizeof(struct bcm6368_nand_soc),
};
void board_nand_init(void)
{
struct udevice *dev;
int ret;
ret = uclass_get_device_by_driver(UCLASS_MTD,
DM_GET_DRIVER(bcm6368_nand), &dev);
if (ret && ret != -ENODEV)
pr_err("Failed to initialize %s. (error %d)\n", dev->name,
ret);
}

View File

@ -888,161 +888,59 @@ static inline bool is_hamming_ecc(struct brcmnand_controller *ctrl,
}
/*
* Set mtd->ooblayout to the appropriate mtd_ooblayout_ops given
* the layout/configuration.
* Returns -ERRCODE on failure.
* Returns a nand_ecclayout strucutre for the given layout/configuration.
* Returns NULL on failure.
*/
static int brcmnand_hamming_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
static struct nand_ecclayout *brcmnand_create_layout(int ecc_level,
struct brcmnand_host *host)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
int i, j;
struct nand_ecclayout *layout;
int req;
int sectors;
int sas;
int idx1, idx2;
if (section >= sectors)
return -ERANGE;
#ifndef __UBOOT__
layout = devm_kzalloc(&host->pdev->dev, sizeof(*layout), GFP_KERNEL);
#else
layout = devm_kzalloc(host->pdev, sizeof(*layout), GFP_KERNEL);
#endif
if (!layout)
return NULL;
oobregion->offset = (section * sas) + 6;
oobregion->length = 3;
sectors = cfg->page_size / (512 << cfg->sector_size_1k);
sas = cfg->spare_area_size << cfg->sector_size_1k;
return 0;
}
static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
if (section >= sectors * 2)
return -ERANGE;
oobregion->offset = (section / 2) * sas;
if (section & 1) {
oobregion->offset += 9;
oobregion->length = 7;
} else {
oobregion->length = 6;
/* First sector of each page may have BBI */
if (!section) {
/*
* Small-page NAND use byte 6 for BBI while large-page
* NAND use byte 0.
*/
if (cfg->page_size > 512)
oobregion->offset++;
oobregion->length--;
/* Hamming */
if (is_hamming_ecc(host->ctrl, cfg)) {
for (i = 0, idx1 = 0, idx2 = 0; i < sectors; i++) {
/* First sector of each page may have BBI */
if (i == 0) {
layout->oobfree[idx2].offset = i * sas + 1;
/* Small-page NAND use byte 6 for BBI */
if (cfg->page_size == 512)
layout->oobfree[idx2].offset--;
layout->oobfree[idx2].length = 5;
} else {
layout->oobfree[idx2].offset = i * sas;
layout->oobfree[idx2].length = 6;
}
idx2++;
layout->eccpos[idx1++] = i * sas + 6;
layout->eccpos[idx1++] = i * sas + 7;
layout->eccpos[idx1++] = i * sas + 8;
layout->oobfree[idx2].offset = i * sas + 9;
layout->oobfree[idx2].length = 7;
idx2++;
/* Leave zero-terminated entry for OOBFREE */
if (idx1 >= MTD_MAX_ECCPOS_ENTRIES_LARGE ||
idx2 >= MTD_MAX_OOBFREE_ENTRIES_LARGE - 1)
break;
}
}
return 0;
}
static const struct mtd_ooblayout_ops brcmnand_hamming_ooblayout_ops = {
.ecc = brcmnand_hamming_ooblayout_ecc,
.free = brcmnand_hamming_ooblayout_free,
};
static int brcmnand_bch_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
if (section >= sectors)
return -ERANGE;
oobregion->offset = (section * (sas + 1)) - chip->ecc.bytes;
oobregion->length = chip->ecc.bytes;
return 0;
}
static int brcmnand_bch_ooblayout_free_lp(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
int sectors = cfg->page_size / (512 << cfg->sector_size_1k);
if (section >= sectors)
return -ERANGE;
if (sas <= chip->ecc.bytes)
return 0;
oobregion->offset = section * sas;
oobregion->length = sas - chip->ecc.bytes;
if (!section) {
oobregion->offset++;
oobregion->length--;
}
return 0;
}
static int brcmnand_bch_ooblayout_free_sp(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
struct nand_chip *chip = mtd_to_nand(mtd);
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_cfg *cfg = &host->hwcfg;
int sas = cfg->spare_area_size << cfg->sector_size_1k;
if (section > 1 || sas - chip->ecc.bytes < 6 ||
(section && sas - chip->ecc.bytes == 6))
return -ERANGE;
if (!section) {
oobregion->offset = 0;
oobregion->length = 5;
} else {
oobregion->offset = 6;
oobregion->length = sas - chip->ecc.bytes - 6;
}
return 0;
}
static const struct mtd_ooblayout_ops brcmnand_bch_lp_ooblayout_ops = {
.ecc = brcmnand_bch_ooblayout_ecc,
.free = brcmnand_bch_ooblayout_free_lp,
};
static const struct mtd_ooblayout_ops brcmnand_bch_sp_ooblayout_ops = {
.ecc = brcmnand_bch_ooblayout_ecc,
.free = brcmnand_bch_ooblayout_free_sp,
};
static int brcmstb_choose_ecc_layout(struct brcmnand_host *host)
{
struct brcmnand_cfg *p = &host->hwcfg;
struct mtd_info *mtd = nand_to_mtd(&host->chip);
struct nand_ecc_ctrl *ecc = &host->chip.ecc;
unsigned int ecc_level = p->ecc_level;
int sas = p->spare_area_size << p->sector_size_1k;
int sectors = p->page_size / (512 << p->sector_size_1k);
if (p->sector_size_1k)
ecc_level <<= 1;
if (is_hamming_ecc(host->ctrl, p)) {
ecc->bytes = 3 * sectors;
mtd_set_ooblayout(mtd, &brcmnand_hamming_ooblayout_ops);
return 0;
return layout;
}
/*
@ -1051,20 +949,70 @@ static int brcmstb_choose_ecc_layout(struct brcmnand_host *host)
* >= v5.0: ECC_REQ = ceil(BCH_T * 14/8)
* But we will just be conservative.
*/
ecc->bytes = DIV_ROUND_UP(ecc_level * 14, 8);
if (p->page_size == 512)
mtd_set_ooblayout(mtd, &brcmnand_bch_sp_ooblayout_ops);
else
mtd_set_ooblayout(mtd, &brcmnand_bch_lp_ooblayout_ops);
if (ecc->bytes >= sas) {
req = DIV_ROUND_UP(ecc_level * 14, 8);
if (req >= sas) {
dev_err(&host->pdev->dev,
"error: ECC too large for OOB (ECC bytes %d, spare sector %d)\n",
ecc->bytes, sas);
return -EINVAL;
req, sas);
return NULL;
}
return 0;
layout->eccbytes = req * sectors;
for (i = 0, idx1 = 0, idx2 = 0; i < sectors; i++) {
for (j = sas - req; j < sas && idx1 <
MTD_MAX_ECCPOS_ENTRIES_LARGE; j++, idx1++)
layout->eccpos[idx1] = i * sas + j;
/* First sector of each page may have BBI */
if (i == 0) {
if (cfg->page_size == 512 && (sas - req >= 6)) {
/* Small-page NAND use byte 6 for BBI */
layout->oobfree[idx2].offset = 0;
layout->oobfree[idx2].length = 5;
idx2++;
if (sas - req > 6) {
layout->oobfree[idx2].offset = 6;
layout->oobfree[idx2].length =
sas - req - 6;
idx2++;
}
} else if (sas > req + 1) {
layout->oobfree[idx2].offset = i * sas + 1;
layout->oobfree[idx2].length = sas - req - 1;
idx2++;
}
} else if (sas > req) {
layout->oobfree[idx2].offset = i * sas;
layout->oobfree[idx2].length = sas - req;
idx2++;
}
/* Leave zero-terminated entry for OOBFREE */
if (idx1 >= MTD_MAX_ECCPOS_ENTRIES_LARGE ||
idx2 >= MTD_MAX_OOBFREE_ENTRIES_LARGE - 1)
break;
}
return layout;
}
static struct nand_ecclayout *brcmstb_choose_ecc_layout(
struct brcmnand_host *host)
{
struct nand_ecclayout *layout;
struct brcmnand_cfg *p = &host->hwcfg;
unsigned int ecc_level = p->ecc_level;
if (p->sector_size_1k)
ecc_level <<= 1;
layout = brcmnand_create_layout(ecc_level, host);
if (!layout) {
dev_err(&host->pdev->dev,
"no proper ecc_layout for this NAND cfg\n");
return NULL;
}
return layout;
}
static void brcmnand_wp(struct mtd_info *mtd, int wp)
@ -2383,9 +2331,9 @@ static int brcmnand_init_cs(struct brcmnand_host *host, ofnode dn)
/* only use our internal HW threshold */
mtd->bitflip_threshold = 1;
ret = brcmstb_choose_ecc_layout(host);
if (ret)
return ret;
chip->ecc.layout = brcmstb_choose_ecc_layout(host);
if (!chip->ecc.layout)
return -ENXIO;
ret = nand_scan_tail(mtd);
if (ret)

View File

@ -322,6 +322,7 @@ config MACB_ZYNQ
config MT7628_ETH
bool "MediaTek MT7628 Ethernet Interface"
depends on SOC_MT7628
select PHYLIB
help
The MediaTek MT7628 ethernet interface is used on MT7628 and
MT7688 based boards.

View File

@ -18,23 +18,12 @@
#include <malloc.h>
#include <miiphy.h>
#include <net.h>
#include <regmap.h>
#include <syscon.h>
#include <reset.h>
#include <wait_bit.h>
#include <asm/io.h>
#include <linux/bitfield.h>
#include <linux/err.h>
/* System controller register */
#define MT7628_RSTCTRL_REG 0x34
#define RSTCTRL_EPHY_RST BIT(24)
#define MT7628_AGPIO_CFG_REG 0x3c
#define MT7628_EPHY_GPIO_AIO_EN GENMASK(20, 17)
#define MT7628_EPHY_P0_DIS BIT(16)
#define MT7628_GPIO2_MODE_REG 0x64
/* Ethernet frame engine register */
#define PDMA_RELATED 0x0800
@ -68,6 +57,11 @@
/* Ethernet switch register */
#define MT7628_SWITCH_FCT0 0x0008
#define MT7628_SWITCH_PFC1 0x0014
#define MT7628_SWITCH_PVIDC0 0x0040
#define MT7628_SWITCH_PVIDC1 0x0044
#define MT7628_SWITCH_PVIDC2 0x0048
#define MT7628_SWITCH_PVIDC3 0x004c
#define MT7628_SWITCH_VMSC0 0x0070
#define MT7628_SWITCH_FPA 0x0084
#define MT7628_SWITCH_SOCPC 0x008c
#define MT7628_SWITCH_POC0 0x0090
@ -122,6 +116,7 @@ struct fe_tx_dma {
#define NUM_RX_DESC 256
#define NUM_TX_DESC 4
#define NUM_PHYS 5
#define PADDING_LENGTH 60
@ -131,13 +126,9 @@ struct fe_tx_dma {
#define CONFIG_DMA_STOP_TIMEOUT 100
#define CONFIG_TX_DMA_TIMEOUT 100
#define LINK_DELAY_TIME 500 /* 500 ms */
#define LINK_TIMEOUT 10000 /* 10 seconds */
struct mt7628_eth_dev {
void __iomem *base; /* frame engine base address */
void __iomem *eth_sw_base; /* switch base address */
struct regmap *sysctrl_regmap; /* system-controller reg-map */
struct mii_dev *bus;
@ -150,8 +141,16 @@ struct mt7628_eth_dev {
int rx_dma_idx;
/* Point to the next TXD in TXD Ring0 CPU wants to use */
int tx_dma_idx;
struct reset_ctl rst_ephy;
struct phy_device *phy;
int wan_port;
};
static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length);
static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
{
void __iomem *base = priv->eth_sw_base;
@ -280,6 +279,9 @@ static void mt7628_ephy_init(struct mt7628_eth_dev *priv)
static void rt305x_esw_init(struct mt7628_eth_dev *priv)
{
void __iomem *base = priv->eth_sw_base;
void __iomem *reg;
u32 val = 0, pvid;
int i;
/*
* FC_RLS_TH=200, FC_SET_TH=160
@ -301,20 +303,28 @@ static void rt305x_esw_init(struct mt7628_eth_dev *priv)
/* 1us cycle number=125 (FE's clock=125Mhz) */
writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
/* Configure analog GPIO setup */
regmap_update_bits(priv->sysctrl_regmap, MT7628_AGPIO_CFG_REG,
MT7628_EPHY_P0_DIS, MT7628_EPHY_GPIO_AIO_EN);
/* LAN/WAN partition, WAN port will be unusable in u-boot network */
if (priv->wan_port >= 0 && priv->wan_port < 6) {
for (i = 0; i < 8; i++) {
pvid = i == priv->wan_port ? 2 : 1;
reg = base + MT7628_SWITCH_PVIDC0 + (i / 2) * 4;
if (i % 2 == 0) {
val = pvid;
} else {
val |= (pvid << 12);
writel(val, reg);
}
}
val = 0xffff407f;
val |= 1 << (8 + priv->wan_port);
val &= ~(1 << priv->wan_port);
writel(val, base + MT7628_SWITCH_VMSC0);
}
/* Reset PHY */
regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
0, RSTCTRL_EPHY_RST);
regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
RSTCTRL_EPHY_RST, 0);
mdelay(10);
/* Set P0 EPHY LED mode */
regmap_update_bits(priv->sysctrl_regmap, MT7628_GPIO2_MODE_REG,
0x0ffc0ffc, 0x05540554);
reset_assert(&priv->rst_ephy);
reset_deassert(&priv->rst_ephy);
mdelay(10);
mt7628_ephy_init(priv);
@ -424,6 +434,7 @@ static int mt7628_eth_recv(struct udevice *dev, int flags, uchar **packetp)
length = FIELD_GET(RX_DMA_PLEN0, priv->rx_ring[idx].rxd2);
if (length == 0 || length > MTK_QDMA_PAGE_SIZE) {
printf("%s: invalid length (%d bytes)\n", __func__, length);
mt7628_eth_free_pkt(dev, NULL, 0);
return -EIO;
}
@ -458,20 +469,13 @@ static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
return 0;
}
static int phy_link_up(struct mt7628_eth_dev *priv)
{
u32 val;
mii_mgr_read(priv, 0x00, MII_BMSR, &val);
return !!(val & BMSR_LSTATUS);
}
static int mt7628_eth_start(struct udevice *dev)
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
void __iomem *base = priv->base;
uchar packet[MTK_QDMA_PAGE_SIZE];
uchar *packetp;
int ret;
int i;
for (i = 0; i < NUM_RX_DESC; i++) {
@ -514,25 +518,13 @@ static int mt7628_eth_start(struct udevice *dev)
wmb();
eth_dma_start(priv);
/* Check if link is not up yet */
if (!phy_link_up(priv)) {
/* Wait for link to come up */
if (priv->phy) {
ret = phy_startup(priv->phy);
if (ret)
return ret;
printf("Waiting for link to come up .");
for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
mdelay(LINK_DELAY_TIME);
if (phy_link_up(priv)) {
mdelay(100); /* Ensure all is ready */
break;
}
printf(".");
}
if (phy_link_up(priv))
printf(" done\n");
else
printf(" timeout! Trying anyways\n");
if (!priv->phy->link)
return -EAGAIN;
}
/*
@ -558,8 +550,8 @@ static void mt7628_eth_stop(struct udevice *dev)
static int mt7628_eth_probe(struct udevice *dev)
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
struct udevice *syscon;
struct mii_dev *bus;
int poll_link_phy;
int ret;
int i;
@ -573,19 +565,15 @@ static int mt7628_eth_probe(struct udevice *dev)
if (IS_ERR(priv->eth_sw_base))
return PTR_ERR(priv->eth_sw_base);
/* Get system controller regmap */
ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
"syscon", &syscon);
/* Reset controller */
ret = reset_get_by_name(dev, "ephy", &priv->rst_ephy);
if (ret) {
pr_err("unable to find syscon device\n");
pr_err("unable to find reset controller for ethernet PHYs\n");
return ret;
}
priv->sysctrl_regmap = syscon_get_regmap(syscon);
if (!priv->sysctrl_regmap) {
pr_err("unable to find regmap\n");
return -ENODEV;
}
/* WAN port will be isolated from LAN ports */
priv->wan_port = dev_read_u32_default(dev, "mediatek,wan-port", -1);
/* Put rx and tx rings into KSEG1 area (uncached) */
priv->tx_ring = (struct fe_tx_dma *)
@ -613,6 +601,25 @@ static int mt7628_eth_probe(struct udevice *dev)
if (ret)
return ret;
poll_link_phy = dev_read_u32_default(dev, "mediatek,poll-link-phy", -1);
if (poll_link_phy >= 0) {
if (poll_link_phy >= NUM_PHYS) {
pr_err("invalid phy %d for poll-link-phy\n",
poll_link_phy);
return ret;
}
priv->phy = phy_connect(bus, poll_link_phy, dev,
PHY_INTERFACE_MODE_MII);
if (!priv->phy) {
pr_err("failed to probe phy %d\n", poll_link_phy);
return -ENODEV;
}
priv->phy->advertising = priv->phy->supported;
phy_config(priv->phy);
}
/* Switch configuration */
rt305x_esw_init(priv);

View File

@ -200,6 +200,7 @@ config KEYSTONE_USB_PHY
config MT76X8_USB_PHY
bool "MediaTek MT76x8 (7628/88) USB PHY support"
depends on PHY
depends on SOC_MT7628
help
Support the USB PHY in MT76x8 SoCs

View File

@ -6,93 +6,185 @@
* Copyright (C) 2017 John Crispin <john@phrozen.org>
*/
#include <clk.h>
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <regmap.h>
#include <reset-uclass.h>
#include <syscon.h>
#include <reset.h>
#include <asm/io.h>
#define RT_SYSC_REG_SYSCFG1 0x014
#define RT_SYSC_REG_CLKCFG1 0x030
#define RT_SYSC_REG_USB_PHY_CFG 0x05c
#include <linux/bitops.h>
#define OFS_U2_PHY_AC0 0x800
#define USBPLL_FBDIV_S 16
#define USBPLL_FBDIV_M GENMASK(22, 16)
#define BG_TRIM_S 8
#define BG_TRIM_M GENMASK(11, 8)
#define BG_RBSEL_S 6
#define BG_RBSEL_M GENMASK(7, 6)
#define BG_RASEL_S 4
#define BG_RASEL_M GENMASK(5, 4)
#define BGR_DIV_S 2
#define BGR_DIV_M GENMASK(3, 2)
#define CHP_EN BIT(1)
#define OFS_U2_PHY_AC1 0x804
#define VRT_VREF_SEL_S 28
#define VRT_VREF_SEL_M GENMASK(30, 28)
#define TERM_VREF_SEL_S 24
#define TERM_VREF_SEL_M GENMASK(26, 24)
#define USBPLL_RSVD BIT(4)
#define USBPLL_ACCEN BIT(3)
#define USBPLL_LF BIT(2)
#define OFS_U2_PHY_AC2 0x808
#define OFS_U2_PHY_ACR0 0x810
#define OFS_U2_PHY_ACR1 0x814
#define OFS_U2_PHY_ACR2 0x818
#define HSTX_SRCAL_EN BIT(23)
#define HSTX_SRCTRL_S 16
#define HSTX_SRCTRL_M GENMASK(18, 16)
#define OFS_U2_PHY_ACR3 0x81C
#define OFS_U2_PHY_ACR4 0x820
#define OFS_U2_PHY_AMON0 0x824
#define HSTX_DBIST_S 28
#define HSTX_DBIST_M GENMASK(31, 28)
#define HSRX_BIAS_EN_SEL_S 20
#define HSRX_BIAS_EN_SEL_M GENMASK(21, 20)
#define OFS_U2_PHY_DCR0 0x860
#define OFS_U2_PHY_DCR1 0x864
#define PHYD_RESERVE_S 8
#define PHYD_RESERVE_M GENMASK(23, 8)
#define CDR_FILT_S 0
#define CDR_FILT_M GENMASK(3, 0)
#define OFS_U2_PHY_DTM0 0x868
#define OFS_U2_PHY_DTM1 0x86C
#define FORCE_USB_CLKEN BIT(25)
#define RT_RSTCTRL_UDEV BIT(25)
#define RT_RSTCTRL_UHST BIT(22)
#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
#define OFS_FM_CR0 0xf00
#define FREQDET_EN BIT(24)
#define CYCLECNT_S 0
#define CYCLECNT_M GENMASK(23, 0)
#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22)
#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
#define OFS_FM_MONR0 0xf0c
#define USB_PHY_UTMI_8B60M BIT(1)
#define UDEV_WAKEUP BIT(0)
#define OFS_FM_MONR1 0xf10
#define FRCK_EN BIT(8)
#define U2_SR_COEF_7628 32
struct mt76x8_usb_phy {
u32 clk;
void __iomem *base;
struct regmap *sysctl;
struct clk cg; /* for clock gating */
struct reset_ctl rst_phy;
};
static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg)
static void phy_w32(struct mt76x8_usb_phy *phy, u32 reg, u32 val)
{
writel(val, phy->base + reg);
}
static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg)
static u32 phy_r32(struct mt76x8_usb_phy *phy, u32 reg)
{
return readl(phy->base + reg);
}
static void phy_rmw32(struct mt76x8_usb_phy *phy, u32 reg, u32 clr, u32 set)
{
clrsetbits_32(phy->base + reg, clr, set);
}
static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy)
{
u2_phy_r32(phy, OFS_U2_PHY_AC2);
u2_phy_r32(phy, OFS_U2_PHY_ACR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
phy_r32(phy, OFS_U2_PHY_AC2);
phy_r32(phy, OFS_U2_PHY_ACR0);
phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0);
u2_phy_r32(phy, OFS_U2_PHY_DCR0);
u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0);
u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1);
u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3);
u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0);
phy_w32(phy, OFS_U2_PHY_DCR0,
(0xffff << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
phy_r32(phy, OFS_U2_PHY_DCR0);
phy_w32(phy, OFS_U2_PHY_DCR0,
(0x5555 << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
phy_r32(phy, OFS_U2_PHY_DCR0);
phy_w32(phy, OFS_U2_PHY_DCR0,
(0xaaaa << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
phy_r32(phy, OFS_U2_PHY_DCR0);
phy_w32(phy, OFS_U2_PHY_DCR0,
(4 << PHYD_RESERVE_S) | (2 << CDR_FILT_S));
phy_r32(phy, OFS_U2_PHY_DCR0);
phy_w32(phy, OFS_U2_PHY_AC0,
(0x48 << USBPLL_FBDIV_S) | (8 << BG_TRIM_S) |
(1 << BG_RBSEL_S) | (2 << BG_RASEL_S) | (2 << BGR_DIV_S) |
CHP_EN);
phy_w32(phy, OFS_U2_PHY_AC1,
(4 << VRT_VREF_SEL_S) | (4 << TERM_VREF_SEL_S) | USBPLL_RSVD |
USBPLL_ACCEN | USBPLL_LF);
phy_w32(phy, OFS_U2_PHY_ACR3,
(12 << HSTX_DBIST_S) | (2 << HSRX_BIAS_EN_SEL_S));
phy_w32(phy, OFS_U2_PHY_DTM0, FORCE_USB_CLKEN);
}
static void mt76x8_usb_phy_sr_calibrate(struct mt76x8_usb_phy *phy)
{
u32 fmout, tmp = 4;
int i;
/* Enable HS TX SR calibration */
phy_rmw32(phy, OFS_U2_PHY_ACR0, 0, HSTX_SRCAL_EN);
mdelay(1);
/* Enable free run clock */
phy_rmw32(phy, OFS_FM_MONR1, 0, FRCK_EN);
/* Set cycle count = 0x400 */
phy_rmw32(phy, OFS_FM_CR0, CYCLECNT_M, 0x400 << CYCLECNT_S);
/* Enable frequency meter */
phy_rmw32(phy, OFS_FM_CR0, 0, FREQDET_EN);
/* Wait for FM detection done, set timeout to 10ms */
for (i = 0; i < 10; i++) {
fmout = phy_r32(phy, OFS_FM_MONR0);
if (fmout)
break;
mdelay(1);
}
/* Disable frequency meter */
phy_rmw32(phy, OFS_FM_CR0, FREQDET_EN, 0);
/* Disable free run clock */
phy_rmw32(phy, OFS_FM_MONR1, FRCK_EN, 0);
/* Disable HS TX SR calibration */
phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCAL_EN, 0);
mdelay(1);
if (fmout) {
/*
* set reg = (1024 / FM_OUT) * 25 * 0.028
* (round to the nearest digits)
*/
tmp = (((1024 * 25 * U2_SR_COEF_7628) / fmout) + 500) / 1000;
}
phy_rmw32(phy, OFS_U2_PHY_ACR0, HSTX_SRCTRL_M,
(tmp << HSTX_SRCTRL_S) & HSTX_SRCTRL_M);
}
static int mt76x8_usb_phy_power_on(struct phy *_phy)
{
struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
u32 t;
/* enable the phy */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
phy->clk, phy->clk);
clk_enable(&phy->cg);
/* setup host mode */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1,
RT_SYSCFG1_USB0_HOST_MODE,
RT_SYSCFG1_USB0_HOST_MODE);
reset_deassert(&phy->rst_phy);
/*
* The SDK kernel had a delay of 100ms. however on device
@ -100,17 +192,8 @@ static int mt76x8_usb_phy_power_on(struct phy *_phy)
*/
mdelay(10);
if (phy->base)
mt76x8_usb_phy_init(phy);
/* print some status info */
regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t);
printf("remote usb device wakeup %s\n",
(t & UDEV_WAKEUP) ? "enabled" : "disabled");
if (t & USB_PHY_UTMI_8B60M)
printf("UTMI 8bit 60MHz\n");
else
printf("UTMI 16bit 30MHz\n");
mt76x8_usb_phy_init(phy);
mt76x8_usb_phy_sr_calibrate(phy);
return 0;
}
@ -119,9 +202,9 @@ static int mt76x8_usb_phy_power_off(struct phy *_phy)
{
struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
/* disable the phy */
regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
phy->clk, 0);
clk_disable(&phy->cg);
reset_assert(&phy->rst_phy);
return 0;
}
@ -129,15 +212,21 @@ static int mt76x8_usb_phy_power_off(struct phy *_phy)
static int mt76x8_usb_phy_probe(struct udevice *dev)
{
struct mt76x8_usb_phy *phy = dev_get_priv(dev);
phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl");
if (IS_ERR(phy->sysctl))
return PTR_ERR(phy->sysctl);
int ret;
phy->base = dev_read_addr_ptr(dev);
if (!phy->base)
return -EINVAL;
/* clock gate */
ret = clk_get_by_name(dev, "cg", &phy->cg);
if (ret)
return ret;
ret = reset_get_by_name(dev, "phy", &phy->rst_phy);
if (ret)
return ret;
return 0;
}

View File

@ -269,6 +269,7 @@ source "drivers/pinctrl/exynos/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
source "drivers/pinctrl/mscc/Kconfig"
source "drivers/pinctrl/mtmips/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/renesas/Kconfig"

View File

@ -9,6 +9,7 @@ obj-y += nxp/
obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_ATH79) += ath79/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_RMOBILE) += renesas/
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o

View File

@ -0,0 +1,13 @@
config PINCTRL_MTMIPS
depends on ARCH_MTMIPS
bool
config PINCTRL_MT7628
bool "MediaTek MT7628 pin control driver"
select PINCTRL_MTMIPS
depends on SOC_MT7628 && PINCTRL_GENERIC
help
Support pin multiplexing control on MediaTek MT7628.
The driver is controlled by a device tree node which contains
the pin mux functions for each available pin groups.

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
# Core
obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o

View File

@ -0,0 +1,585 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <common.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include "pinctrl-mtmips-common.h"
DECLARE_GLOBAL_DATA_PTR;
#define AGPIO_OFS 0
#define GPIOMODE1_OFS 0x24
#define GPIOMODE2_OFS 0x28
#define EPHY4_1_PAD_SHIFT 17
#define EPHY4_1_PAD_MASK 0x0f
#define EPHY0_SHIFT 16
#define RF_OLT_MODE_SHIFT 12
#define N9_EINT_SRC_SHIFT 9
#define WLED_OD_SHIFT 8
#define REF_CLKO_PAD_SHIFT 4
#define I2S_CLK_PAD_SHIFT 3
#define I2S_WS_PAD_SHIFT 2
#define I2S_SDO_PAD_SHIFT 1
#define I2S_SDI_PAD_SHIFT 0
#define GM4_MASK 3
#define P4LED_K_SHIFT 26
#define P3LED_K_SHIFT 24
#define P2LED_K_SHIFT 22
#define P1LED_K_SHIFT 20
#define P0LED_K_SHIFT 18
#define WLED_K_SHIFT 16
#define P4LED_A_SHIFT 10
#define P3LED_A_SHIFT 8
#define P2LED_A_SHIFT 6
#define P1LED_A_SHIFT 4
#define P0LED_A_SHIFT 2
#define WLED_A_SHIFT 0
#define PWM1_SHIFT 30
#define PWM0_SHIFT 28
#define UART2_SHIFT 26
#define UART1_SHIFT 24
#define I2C_SHIFT 20
#define REFCLK_SHIFT 18
#define PERST_SHIFT 16
#define ESD_SHIFT 15
#define WDT_SHIFT 14
#define SPI_SHIFT 12
#define SDMODE_SHIFT 10
#define UART0_SHIFT 8
#define I2S_SHIFT 6
#define SPI_CS1_SHIFT 4
#define SPIS_SHIFT 2
#define GPIO0_SHIFT 0
#define PAD_PU_G0_REG 0x00
#define PAD_PU_G1_REG 0x04
#define PAD_PD_G0_REG 0x10
#define PAD_PD_G1_REG 0x14
#define PAD_SR_G0_REG 0x20
#define PAD_SR_G1_REG 0x24
#define PAD_SMT_G0_REG 0x30
#define PAD_SMT_G1_REG 0x34
#define PAD_E2_G0_REG 0x40
#define PAD_E2_G1_REG 0x44
#define PAD_E4_G0_REG 0x50
#define PAD_E4_G1_REG 0x54
#define PAD_E8_G0_REG 0x60
#define PAD_E8_G1_REG 0x64
#define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1)
#define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2)
struct mt7628_pinctrl_priv {
struct mtmips_pinctrl_priv mp;
void __iomem *pcbase;
};
#if CONFIG_IS_ENABLED(PINMUX)
static const struct mtmips_pmx_func ephy4_1_pad_grp[] = {
FUNC("digital", 0xf),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func ephy0_grp[] = {
FUNC("disable", 1),
FUNC("enable", 0),
};
static const struct mtmips_pmx_func rf_olt_grp[] = {
FUNC("enable", 1),
FUNC("disable", 0),
};
static const struct mtmips_pmx_func n9_eint_src_grp[] = {
FUNC("gpio", 1),
FUNC("utif", 0),
};
static const struct mtmips_pmx_func wlen_od_grp[] = {
FUNC("enable", 1),
FUNC("disable", 0),
};
static const struct mtmips_pmx_func ref_clko_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_clk_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_ws_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_sdo_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_sdi_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func pwm1_grp[] = {
FUNC("sdxc d6", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("pwm1", 0),
};
static const struct mtmips_pmx_func pwm0_grp[] = {
FUNC("sdxc d7", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("pwm0", 0),
};
static const struct mtmips_pmx_func uart2_grp[] = {
FUNC("sdxc d5 d4", 3),
FUNC("pwm", 2),
FUNC("gpio", 1),
FUNC("uart2", 0),
};
static const struct mtmips_pmx_func uart1_grp[] = {
FUNC("sw_r", 3),
FUNC("pwm", 2),
FUNC("gpio", 1),
FUNC("uart1", 0),
};
static const struct mtmips_pmx_func i2c_grp[] = {
FUNC("-", 3),
FUNC("debug", 2),
FUNC("gpio", 1),
FUNC("i2c", 0),
};
static const struct mtmips_pmx_func refclk_grp[] = {
FUNC("gpio", 1),
FUNC("refclk", 0),
};
static const struct mtmips_pmx_func perst_grp[] = {
FUNC("gpio", 1),
FUNC("perst", 0),
};
static const struct mtmips_pmx_func esd_grp[] = {
FUNC("router", 1),
FUNC("iot", 0),
};
static const struct mtmips_pmx_func wdt_grp[] = {
FUNC("gpio", 1),
FUNC("wdt", 0),
};
static const struct mtmips_pmx_func spi_grp[] = {
FUNC("gpio", 1),
FUNC("spi", 0),
};
static const struct mtmips_pmx_func sd_mode_grp[] = {
FUNC("n9 jtag", 3),
FUNC("utif1", 2),
FUNC("gpio", 1),
FUNC("sdxc", 0),
};
static const struct mtmips_pmx_func uart0_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("uart0", 0),
};
static const struct mtmips_pmx_func i2s_grp[] = {
FUNC("antenna", 3),
FUNC("pcm", 2),
FUNC("gpio", 1),
FUNC("i2s", 0),
};
static const struct mtmips_pmx_func spi_cs1_grp[] = {
FUNC("-", 3),
FUNC("refclk", 2),
FUNC("gpio", 1),
FUNC("spi cs1", 0),
};
static const struct mtmips_pmx_func spis_grp[] = {
FUNC("pwm_uart2", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("spis", 0),
};
static const struct mtmips_pmx_func gpio0_grp[] = {
FUNC("perst", 3),
FUNC("refclk", 2),
FUNC("gpio", 1),
FUNC("gpio0", 0),
};
static const struct mtmips_pmx_func wled_a_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p0led_a_grp[] = {
FUNC("jtag", 3),
FUNC("rsvd", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p1led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p2led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p3led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p4led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func wled_k_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p0led_k_grp[] = {
FUNC("jtag", 3),
FUNC("rsvd", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p1led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p2led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p3led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p4led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_group mt7628_pinmux_data[] = {
GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT,
EPHY4_1_PAD_MASK),
GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1),
GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1),
GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1),
GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1),
GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1),
GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1),
GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1),
GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1),
GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1),
GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK),
GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK),
GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK),
GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK),
GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK),
GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1),
GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1),
GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1),
GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1),
GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1),
GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK),
GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK),
GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK),
GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK),
GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK),
GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK),
GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK),
GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK),
GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK),
GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK),
GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK),
GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK),
GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK),
GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK),
GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK),
GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK),
GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK),
GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK),
};
static int mt7628_get_groups_count(struct udevice *dev)
{
return ARRAY_SIZE(mt7628_pinmux_data);
}
static const char *mt7628_get_group_name(struct udevice *dev,
unsigned int selector)
{
return mt7628_pinmux_data[selector].name;
}
#endif /* CONFIG_IS_ENABLED(PINMUX) */
#if CONFIG_IS_ENABLED(PINCONF)
static const struct pinconf_param mt7628_conf_params[] = {
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
{ "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 },
{ "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 },
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
};
static const char *const mt7628_pins[] = {
"i2s_sdi",
"i2s_sdo",
"i2s_ws",
"i2s_clk",
"i2s_sclk",
"i2c_sd",
"spi_cs1",
"spi_clk",
"spi_mosi",
"spi_miso",
"spi_cs0",
"gpio0",
"uart0_txd",
"uart0_rxd",
"spis_cs",
"spis_clk",
"spis_miso",
"spis_mosi",
"pwm_ch0",
"pwm_ch1",
"uart2_txd",
"uart2_rxd",
"sd_wp",
"sd_cd",
"sd_d1",
"sd_d0",
"sd_clk",
"sd_cmd",
"sd_d3",
"sd_d2",
"ephy_led4_k",
"ephy_led3_k",
"ephy_led2_k",
"ephy_led1_k",
"ephy_led0_k",
"wled_k",
"perst_n",
"co_clko",
"wdt",
"ephy_led4_a",
"ephy_led3_a",
"ephy_led2_a",
"ephy_led1_a",
"ephy_led0_a",
"wled_a",
"uart1_txd",
"uart1_rxd",
};
static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8};
static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16};
static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit,
const u32 tbl[], u32 reg_lo, u32 reg_hi)
{
int i;
for (i = 0; i < 4; i++)
if (tbl[i] == val)
break;
if (i >= 4)
return -EINVAL;
clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit);
clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit);
return 0;
}
static int mt7628_get_pins_count(struct udevice *dev)
{
return ARRAY_SIZE(mt7628_pins);
}
static const char *mt7628_get_pin_name(struct udevice *dev,
unsigned int selector)
{
return mt7628_pins[selector];
}
static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector,
unsigned int param, unsigned int argument)
{
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
u32 offs, bit;
int ret = 0;
offs = (pin_selector / 32) * 4;
bit = pin_selector % 32;
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
case PIN_CONFIG_BIAS_PULL_UP:
setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG,
BIT(bit), (!!argument) << bit);
break;
case PIN_CONFIG_DRIVE_STRENGTH_28:
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
bit, mt7628_drv_strength_28_tbl,
PAD_E2_G0_REG, PAD_E4_G0_REG);
break;
case PIN_CONFIG_DRIVE_STRENGTH_4G:
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
bit, mt7628_drv_strength_4g_tbl,
PAD_E4_G0_REG, PAD_E8_G0_REG);
break;
case PIN_CONFIG_SLEW_RATE:
clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG,
BIT(bit), (!!argument) << bit);
break;
default:
ret = -EINVAL;
}
return ret;
}
#endif
static int mt7628_pinctrl_probe(struct udevice *dev)
{
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
int ret = 0;
#if CONFIG_IS_ENABLED(PINMUX)
ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data),
mt7628_pinmux_data);
#endif /* CONFIG_IS_ENABLED(PINMUX) */
return ret;
}
static int mt7628_pinctrl_ofdata_to_platdata(struct udevice *dev)
{
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0);
if (!priv->mp.base)
return -EINVAL;
priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1);
if (!priv->pcbase)
return -EINVAL;
return 0;
}
static const struct pinctrl_ops mt7628_pinctrl_ops = {
#if CONFIG_IS_ENABLED(PINMUX)
.get_groups_count = mt7628_get_groups_count,
.get_group_name = mt7628_get_group_name,
.get_functions_count = mtmips_get_functions_count,
.get_function_name = mtmips_get_function_name,
.pinmux_group_set = mtmips_pinmux_group_set,
#endif /* CONFIG_IS_ENABLED(PINMUX) */
#if CONFIG_IS_ENABLED(PINCONF)
.pinconf_num_params = ARRAY_SIZE(mt7628_conf_params),
.pinconf_params = mt7628_conf_params,
.get_pins_count = mt7628_get_pins_count,
.get_pin_name = mt7628_get_pin_name,
.pinconf_set = mt7628_pinconf_set,
#endif /* CONFIG_IS_ENABLED(PINCONF) */
.set_state = pinctrl_generic_set_state,
};
static const struct udevice_id mt7628_pinctrl_ids[] = {
{ .compatible = "mediatek,mt7628-pinctrl" },
{ }
};
U_BOOT_DRIVER(mt7628_pinctrl) = {
.name = "mt7628-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = mt7628_pinctrl_ids,
.ofdata_to_platdata = mt7628_pinctrl_ofdata_to_platdata,
.ops = &mt7628_pinctrl_ops,
.probe = mt7628_pinctrl_probe,
.priv_auto_alloc_size = sizeof(struct mt7628_pinctrl_priv),
};

View File

@ -0,0 +1,87 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <common.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <linux/io.h>
#include "pinctrl-mtmips-common.h"
static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
u32 reg, u32 shift, u32 mask, u32 value)
{
u32 val;
val = readl(priv->base + reg);
val &= ~(mask << shift);
val |= value << shift;
writel(val, priv->base + reg);
}
int mtmips_get_functions_count(struct udevice *dev)
{
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
return priv->nfuncs;
}
const char *mtmips_get_function_name(struct udevice *dev, unsigned int selector)
{
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
return priv->funcs[selector]->name;
}
int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
unsigned int func_selector)
{
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
const struct mtmips_pmx_group *grp = &priv->groups[group_selector];
const struct mtmips_pmx_func *func = priv->funcs[func_selector];
int i;
if (!grp->nfuncs)
return 0;
for (i = 0; i < grp->nfuncs; i++) {
if (!strcmp(grp->funcs[i].name, func->name)) {
mtmips_pinctrl_reg_set(priv, grp->reg, grp->shift,
grp->mask, grp->funcs[i].value);
return 0;
}
}
return -EINVAL;
}
int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
const struct mtmips_pmx_group *groups)
{
int i, j, n;
priv->ngroups = ngroups;
priv->groups = groups;
priv->nfuncs = 0;
for (i = 0; i < ngroups; i++)
priv->nfuncs += groups[i].nfuncs;
priv->funcs = malloc(priv->nfuncs * sizeof(*priv->funcs));
if (!priv->funcs)
return -ENOMEM;
n = 0;
for (i = 0; i < ngroups; i++) {
for (j = 0; j < groups[i].nfuncs; j++)
priv->funcs[n++] = &groups[i].funcs[j];
}
return 0;
}

View File

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _PINCTRL_MTMIPS_COMMON_H_
#define _PINCTRL_MTMIPS_COMMON_H_
#include <common.h>
struct mtmips_pmx_func {
const char *name;
int value;
};
struct mtmips_pmx_group {
const char *name;
u32 reg;
u32 shift;
char mask;
int nfuncs;
const struct mtmips_pmx_func *funcs;
};
struct mtmips_pinctrl_priv {
void __iomem *base;
u32 ngroups;
const struct mtmips_pmx_group *groups;
u32 nfuncs;
const struct mtmips_pmx_func **funcs;
};
#define FUNC(name, value) { name, value }
#define GRP(_name, _funcs, _reg, _shift, _mask) \
{ .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \
.funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) }
int mtmips_get_functions_count(struct udevice *dev);
const char *mtmips_get_function_name(struct udevice *dev,
unsigned int selector);
int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
unsigned int func_selector);
int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
const struct mtmips_pmx_group *groups);
#endif /* _PINCTRL_MTMIPS_COMMON_H_ */

View File

@ -113,6 +113,13 @@ config RESET_MEDIATEK
help
Support for reset controller on MediaTek SoCs.
config RESET_MTMIPS
bool "Reset controller driver for MediaTek MIPS platform"
depends on DM_RESET && ARCH_MTMIPS
default y
help
Support for reset controller on MediaTek MIPS platform.
config RESET_SUNXI
bool "RESET support for Allwinner SoCs"
depends on DM_RESET && ARCH_SUNXI

View File

@ -18,6 +18,7 @@ obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o
obj-$(CONFIG_RESET_MESON) += reset-meson.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o

View File

@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <reset-uclass.h>
#include <linux/io.h>
struct mtmips_reset_priv {
void __iomem *base;
};
static int mtmips_reset_request(struct reset_ctl *reset_ctl)
{
return 0;
}
static int mtmips_reset_free(struct reset_ctl *reset_ctl)
{
return 0;
}
static int mtmips_reset_assert(struct reset_ctl *reset_ctl)
{
struct mtmips_reset_priv *priv = dev_get_priv(reset_ctl->dev);
setbits_32(priv->base, BIT(reset_ctl->id));
return 0;
}
static int mtmips_reset_deassert(struct reset_ctl *reset_ctl)
{
struct mtmips_reset_priv *priv = dev_get_priv(reset_ctl->dev);
clrbits_32(priv->base, BIT(reset_ctl->id));
return 0;
}
static const struct reset_ops mtmips_reset_ops = {
.request = mtmips_reset_request,
.free = mtmips_reset_free,
.rst_assert = mtmips_reset_assert,
.rst_deassert = mtmips_reset_deassert,
};
static int mtmips_reset_probe(struct udevice *dev)
{
return 0;
}
static int mtmips_reset_ofdata_to_platdata(struct udevice *dev)
{
struct mtmips_reset_priv *priv = dev_get_priv(dev);
priv->base = (void __iomem *)dev_remap_addr_index(dev, 0);
if (!priv->base)
return -EINVAL;
return 0;
}
static const struct udevice_id mtmips_reset_ids[] = {
{ .compatible = "mediatek,mtmips-reset" },
{ }
};
U_BOOT_DRIVER(mtmips_reset) = {
.name = "mtmips-reset",
.id = UCLASS_RESET,
.of_match = mtmips_reset_ids,
.ofdata_to_platdata = mtmips_reset_ofdata_to_platdata,
.probe = mtmips_reset_probe,
.priv_auto_alloc_size = sizeof(struct mtmips_reset_priv),
.ops = &mtmips_reset_ops,
};

View File

@ -124,6 +124,7 @@ serial_initfunc(ns16550_serial_initialize);
serial_initfunc(pl01x_serial_initialize);
serial_initfunc(pxa_serial_initialize);
serial_initfunc(sh_serial_initialize);
serial_initfunc(mtk_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@ -177,6 +178,7 @@ void serial_initialize(void)
pl01x_serial_initialize();
pxa_serial_initialize();
sh_serial_initialize();
mtk_serial_initialize();
serial_assign(default_serial_console()->name);
}

View File

@ -46,6 +46,22 @@ struct mtk_serial_regs {
#define UART_LSR_DR 0x01 /* Data ready */
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
#define UART_LSR_TEMT 0x40 /* Xmitter empty */
#define UART_MCR_DTR 0x01 /* DTR */
#define UART_MCR_RTS 0x02 /* RTS */
#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */
#define UART_FCR_RXSR 0x02 /* Receiver soft reset */
#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */
#define UART_MCRVAL (UART_MCR_DTR | \
UART_MCR_RTS)
/* Clear & enable FIFOs */
#define UART_FCRVAL (UART_FCR_FIFO_EN | \
UART_FCR_RXSR | \
UART_FCR_TXSR)
/* the data is correct if the real baud is within 3%. */
#define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100)
@ -124,6 +140,37 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
}
}
static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch)
{
if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
return -EAGAIN;
writel(ch, &priv->regs->thr);
if (ch == '\n')
WATCHDOG_RESET();
return 0;
}
static int _mtk_serial_getc(struct mtk_serial_priv *priv)
{
if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
return -EAGAIN;
return readl(&priv->regs->rbr);
}
static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input)
{
if (input)
return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
else
return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
}
#if defined(CONFIG_DM_SERIAL) && \
(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_DM))
static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
@ -137,35 +184,21 @@ static int mtk_serial_putc(struct udevice *dev, const char ch)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
return -EAGAIN;
writel(ch, &priv->regs->thr);
if (ch == '\n')
WATCHDOG_RESET();
return 0;
return _mtk_serial_putc(priv, ch);
}
static int mtk_serial_getc(struct udevice *dev)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
return -EAGAIN;
return readl(&priv->regs->rbr);
return _mtk_serial_getc(priv);
}
static int mtk_serial_pending(struct udevice *dev, bool input)
{
struct mtk_serial_priv *priv = dev_get_priv(dev);
if (input)
return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
else
return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
return _mtk_serial_pending(priv, input);
}
static int mtk_serial_probe(struct udevice *dev)
@ -175,6 +208,9 @@ static int mtk_serial_probe(struct udevice *dev)
/* Disable interrupt */
writel(0, &priv->regs->ier);
writel(UART_MCRVAL, &priv->regs->mcr);
writel(UART_FCRVAL, &priv->regs->fcr);
return 0;
}
@ -235,6 +271,157 @@ U_BOOT_DRIVER(serial_mtk) = {
.ops = &mtk_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
#else
DECLARE_GLOBAL_DATA_PTR;
#define DECLARE_HSUART_PRIV(port) \
static struct mtk_serial_priv mtk_hsuart##port = { \
.regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \
.clock = CONFIG_SYS_NS16550_CLK \
};
#define DECLARE_HSUART_FUNCTIONS(port) \
static int mtk_serial##port##_init(void) \
{ \
writel(0, &mtk_hsuart##port.regs->ier); \
writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \
writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \
_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
return 0 ; \
} \
static void mtk_serial##port##_setbrg(void) \
{ \
_mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \
} \
static int mtk_serial##port##_getc(void) \
{ \
int err; \
do { \
err = _mtk_serial_getc(&mtk_hsuart##port); \
if (err == -EAGAIN) \
WATCHDOG_RESET(); \
} while (err == -EAGAIN); \
return err >= 0 ? err : 0; \
} \
static int mtk_serial##port##_tstc(void) \
{ \
return _mtk_serial_pending(&mtk_hsuart##port, true); \
} \
static void mtk_serial##port##_putc(const char c) \
{ \
int err; \
if (c == '\n') \
mtk_serial##port##_putc('\r'); \
do { \
err = _mtk_serial_putc(&mtk_hsuart##port, c); \
} while (err == -EAGAIN); \
} \
static void mtk_serial##port##_puts(const char *s) \
{ \
while (*s) { \
mtk_serial##port##_putc(*s++); \
} \
}
/* Serial device descriptor */
#define INIT_HSUART_STRUCTURE(port, __name) { \
.name = __name, \
.start = mtk_serial##port##_init, \
.stop = NULL, \
.setbrg = mtk_serial##port##_setbrg, \
.getc = mtk_serial##port##_getc, \
.tstc = mtk_serial##port##_tstc, \
.putc = mtk_serial##port##_putc, \
.puts = mtk_serial##port##_puts, \
}
#define DECLARE_HSUART(port, __name) \
DECLARE_HSUART_PRIV(port); \
DECLARE_HSUART_FUNCTIONS(port); \
struct serial_device mtk_hsuart##port##_device = \
INIT_HSUART_STRUCTURE(port, __name);
#if !defined(CONFIG_CONS_INDEX)
#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6)
#error "Invalid console index value."
#endif
#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1)
#error "Console port 1 defined but not configured."
#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2)
#error "Console port 2 defined but not configured."
#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3)
#error "Console port 3 defined but not configured."
#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
#error "Console port 4 defined but not configured."
#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5)
#error "Console port 5 defined but not configured."
#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6)
#error "Console port 6 defined but not configured."
#endif
#if defined(CONFIG_SYS_NS16550_COM1)
DECLARE_HSUART(1, "mtk-hsuart0");
#endif
#if defined(CONFIG_SYS_NS16550_COM2)
DECLARE_HSUART(2, "mtk-hsuart1");
#endif
#if defined(CONFIG_SYS_NS16550_COM3)
DECLARE_HSUART(3, "mtk-hsuart2");
#endif
#if defined(CONFIG_SYS_NS16550_COM4)
DECLARE_HSUART(4, "mtk-hsuart3");
#endif
#if defined(CONFIG_SYS_NS16550_COM5)
DECLARE_HSUART(5, "mtk-hsuart4");
#endif
#if defined(CONFIG_SYS_NS16550_COM6)
DECLARE_HSUART(6, "mtk-hsuart5");
#endif
__weak struct serial_device *default_serial_console(void)
{
#if CONFIG_CONS_INDEX == 1
return &mtk_hsuart1_device;
#elif CONFIG_CONS_INDEX == 2
return &mtk_hsuart2_device;
#elif CONFIG_CONS_INDEX == 3
return &mtk_hsuart3_device;
#elif CONFIG_CONS_INDEX == 4
return &mtk_hsuart4_device;
#elif CONFIG_CONS_INDEX == 5
return &mtk_hsuart5_device;
#elif CONFIG_CONS_INDEX == 6
return &mtk_hsuart6_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
}
void mtk_serial_initialize(void)
{
#if defined(CONFIG_SYS_NS16550_COM1)
serial_register(&mtk_hsuart1_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM2)
serial_register(&mtk_hsuart2_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM3)
serial_register(&mtk_hsuart3_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM4)
serial_register(&mtk_hsuart4_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM5)
serial_register(&mtk_hsuart5_device);
#endif
#if defined(CONFIG_SYS_NS16550_COM6)
serial_register(&mtk_hsuart6_device);
#endif
}
#endif
#ifdef CONFIG_DEBUG_UART_MTK
@ -248,6 +435,8 @@ static inline void _debug_uart_init(void)
priv.clock = CONFIG_DEBUG_UART_CLOCK;
writel(0, &priv.regs->ier);
writel(UART_MCRVAL, &priv.regs->mcr);
writel(UART_FCRVAL, &priv.regs->fcr);
_mtk_serial_setbrg(&priv, CONFIG_BAUDRATE);
}

View File

@ -9,18 +9,22 @@
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <spi.h>
#include <wait_bit.h>
#include <linux/io.h>
#define SPI_MSG_SIZE_MAX 32 /* SPI message chunk size */
/* Enough for SPI NAND page read / write with page size 2048 bytes */
#define SPI_MSG_SIZE_OVERALL (2048 + 16)
#define MT7621_RX_FIFO_LEN 32
#define MT7621_TX_FIFO_LEN 36
#define MT7621_SPI_TRANS 0x00
#define MT7621_SPI_TRANS_START BIT(8)
#define MT7621_SPI_TRANS_BUSY BIT(16)
#define TRANS_ADDR_SZ GENMASK(20, 19)
#define TRANS_ADDR_SZ_SHIFT 19
#define TRANS_MOSI_BCNT GENMASK(3, 0)
#define TRANS_MOSI_BCNT_SHIFT 0
#define MT7621_SPI_OPCODE 0x04
#define MT7621_SPI_DATA0 0x08
@ -38,27 +42,34 @@
#define MASTER_RS_CLK_SEL_SHIFT 16
#define MASTER_RS_SLAVE_SEL GENMASK(31, 29)
#define MOREBUF_CMD_CNT GENMASK(29, 24)
#define MOREBUF_CMD_CNT_SHIFT 24
#define MOREBUF_MISO_CNT GENMASK(20, 12)
#define MOREBUF_MISO_CNT_SHIFT 12
#define MOREBUF_MOSI_CNT GENMASK(8, 0)
#define MOREBUF_MOSI_CNT_SHIFT 0
struct mt7621_spi {
void __iomem *base;
unsigned int sys_freq;
u32 data[(SPI_MSG_SIZE_OVERALL / 4) + 1];
int tx_len;
};
static void mt7621_spi_reset(struct mt7621_spi *rs, int duplex)
{
setbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
}
static void mt7621_spi_set_cs(struct mt7621_spi *rs, int cs, int enable)
{
u32 val = 0;
debug("%s: cs#%d -> %s\n", __func__, cs, enable ? "enable" : "disable");
if (enable)
val = BIT(cs);
iowrite32(val, rs->base + MT7621_SPI_POLAR);
if (enable) {
setbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
iowrite32(BIT(cs), rs->base + MT7621_SPI_POLAR);
} else {
iowrite32(0, rs->base + MT7621_SPI_POLAR);
iowrite32((2 << TRANS_ADDR_SZ_SHIFT) |
(1 << TRANS_MOSI_BCNT_SHIFT),
rs->base + MT7621_SPI_TRANS);
clrbits_le32(rs->base + MT7621_SPI_MASTER,
MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
}
}
static int mt7621_spi_set_mode(struct udevice *bus, uint mode)
@ -128,20 +139,89 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
return ret;
}
static int mt7621_spi_read(struct mt7621_spi *rs, u8 *buf, size_t len)
{
size_t rx_len;
int i, ret;
u32 val = 0;
while (len) {
rx_len = min_t(size_t, len, MT7621_RX_FIFO_LEN);
iowrite32((rx_len * 8) << MOREBUF_MISO_CNT_SHIFT,
rs->base + MT7621_SPI_MOREBUF);
iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS);
ret = mt7621_spi_wait_till_ready(rs);
if (ret)
return ret;
for (i = 0; i < rx_len; i++) {
if ((i % 4) == 0)
val = ioread32(rs->base + MT7621_SPI_DATA0 + i);
*buf++ = val & 0xff;
val >>= 8;
}
len -= rx_len;
}
return ret;
}
static int mt7621_spi_write(struct mt7621_spi *rs, const u8 *buf, size_t len)
{
size_t tx_len, opcode_len, dido_len;
int i, ret;
u32 val;
while (len) {
tx_len = min_t(size_t, len, MT7621_TX_FIFO_LEN);
opcode_len = min_t(size_t, tx_len, 4);
dido_len = tx_len - opcode_len;
val = 0;
for (i = 0; i < opcode_len; i++) {
val <<= 8;
val |= *buf++;
}
iowrite32(val, rs->base + MT7621_SPI_OPCODE);
val = 0;
for (i = 0; i < dido_len; i++) {
val |= (*buf++) << ((i % 4) * 8);
if ((i % 4 == 3) || (i == dido_len - 1)) {
iowrite32(val, rs->base + MT7621_SPI_DATA0 +
(i & ~3));
val = 0;
}
}
iowrite32(((opcode_len * 8) << MOREBUF_CMD_CNT_SHIFT) |
((dido_len * 8) << MOREBUF_MOSI_CNT_SHIFT),
rs->base + MT7621_SPI_MOREBUF);
iowrite32(MT7621_SPI_TRANS_START, rs->base + MT7621_SPI_TRANS);
ret = mt7621_spi_wait_till_ready(rs);
if (ret)
return ret;
len -= tx_len;
}
return 0;
}
static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
struct udevice *bus = dev->parent;
struct mt7621_spi *rs = dev_get_priv(bus);
const u8 *tx_buf = dout;
u8 *ptr = (u8 *)dout;
u8 *rx_buf = din;
int total_size = bitlen >> 3;
int chunk_size;
int rx_len = 0;
u32 data[(SPI_MSG_SIZE_MAX / 4) + 1] = { 0 };
u32 val;
int i;
int ret = 0;
debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
total_size, flags);
@ -155,13 +235,6 @@ static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen,
return -EIO;
}
if (dout) {
debug("TX-DATA: ");
for (i = 0; i < total_size; i++)
debug("%02x ", *ptr++);
debug("\n");
}
mt7621_spi_wait_till_ready(rs);
/*
@ -171,118 +244,40 @@ static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (flags & SPI_XFER_BEGIN)
mt7621_spi_set_cs(rs, spi_chip_select(dev), 1);
while (total_size > 0) {
/* Don't exceed the max xfer size */
chunk_size = min_t(int, total_size, SPI_MSG_SIZE_MAX);
if (din)
ret = mt7621_spi_read(rs, din, total_size);
else if (dout)
ret = mt7621_spi_write(rs, dout, total_size);
/*
* We might have some TX data buffered from the last xfer
* message. Make sure, that this does not exceed the max
* xfer size
*/
if (rs->tx_len > 4)
chunk_size -= rs->tx_len;
if (din)
rx_len = chunk_size;
if (tx_buf) {
/* Check if this message does not exceed the buffer */
if ((chunk_size + rs->tx_len) > SPI_MSG_SIZE_OVERALL) {
printf("TX message size too big (%d)\n",
chunk_size + rs->tx_len);
return -EMSGSIZE;
}
/*
* Write all TX data into internal buffer to collect
* all TX messages into one buffer (might be split into
* multiple calls to this function)
*/
for (i = 0; i < chunk_size; i++, rs->tx_len++) {
rs->data[rs->tx_len / 4] |=
tx_buf[i] << (8 * (rs->tx_len & 3));
}
}
if (flags & SPI_XFER_END) {
/* Write TX data into controller */
if (rs->tx_len) {
rs->data[0] = swab32(rs->data[0]);
if (rs->tx_len < 4)
rs->data[0] >>= (4 - rs->tx_len) * 8;
for (i = 0; i < rs->tx_len; i += 4) {
iowrite32(rs->data[i / 4], rs->base +
MT7621_SPI_OPCODE + i);
}
}
/* Write length into controller */
val = (min_t(int, rs->tx_len, 4) * 8) << 24;
if (rs->tx_len > 4)
val |= (rs->tx_len - 4) * 8;
val |= (rx_len * 8) << 12;
iowrite32(val, rs->base + MT7621_SPI_MOREBUF);
/* Start the xfer */
setbits_le32(rs->base + MT7621_SPI_TRANS,
MT7621_SPI_TRANS_START);
/* Wait until xfer is finished on bus */
mt7621_spi_wait_till_ready(rs);
/* Reset TX length and TX buffer for next xfer */
rs->tx_len = 0;
memset(rs->data, 0, sizeof(rs->data));
}
for (i = 0; i < rx_len; i += 4)
data[i / 4] = ioread32(rs->base + MT7621_SPI_DATA0 + i);
if (rx_len) {
debug("RX-DATA: ");
for (i = 0; i < rx_len; i++) {
rx_buf[i] = data[i / 4] >> (8 * (i & 3));
debug("%02x ", rx_buf[i]);
}
debug("\n");
}
if (tx_buf)
tx_buf += chunk_size;
if (rx_buf)
rx_buf += chunk_size;
total_size -= chunk_size;
}
/* Wait until xfer is finished on bus and de-assert CS */
mt7621_spi_wait_till_ready(rs);
if (flags & SPI_XFER_END)
mt7621_spi_set_cs(rs, spi_chip_select(dev), 0);
return 0;
return ret;
}
static int mt7621_spi_probe(struct udevice *dev)
{
struct mt7621_spi *rs = dev_get_priv(dev);
struct clk clk;
int ret;
rs->base = dev_remap_addr(dev);
if (!rs->base)
return -EINVAL;
/*
* Read input clock via DT for now. At some point this should be
* replaced by implementing a clock driver for this SoC and getting
* the SPI frequency via this clock driver.
*/
rs->sys_freq = dev_read_u32_default(dev, "clock-frequency", 0);
if (!rs->sys_freq) {
printf("Please provide clock-frequency!\n");
return -EINVAL;
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0) {
printf("Please provide a clock!\n");
return ret;
}
mt7621_spi_reset(rs, 0);
clk_enable(&clk);
rs->sys_freq = clk_get_rate(&clk);
if (!rs->sys_freq) {
printf("Please provide a valid clock!\n");
return -EINVAL;
}
return 0;
}

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM3380_H
#define __CONFIG_BMIPS_BCM3380_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 166500000
@ -13,11 +15,11 @@
#define CONFIG_SYS_SDRAM_BASE 0x80000000
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM3380_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6318_H
#define __CONFIG_BMIPS_BCM6318_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 166500000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM6318_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM63268_H
#define __CONFIG_BMIPS_BCM63268_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 200000000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM63268_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6328_H
#define __CONFIG_BMIPS_BCM6328_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 160000000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM6328_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6338_H
#define __CONFIG_BMIPS_BCM6338_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 120000000
@ -13,11 +15,11 @@
#define CONFIG_SYS_SDRAM_BASE 0x80000000
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#define CONFIG_SYS_FLASH_BASE 0xbfc00000

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6348_H
#define __CONFIG_BMIPS_BCM6348_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 128000000
@ -18,11 +20,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#define CONFIG_SYS_FLASH_BASE 0xbfc00000

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6358_H
#define __CONFIG_BMIPS_BCM6358_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 150000000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#define CONFIG_SYS_FLASH_BASE 0xbe000000

View File

@ -1,11 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
#ifndef __CONFIG_BMIPS_BCM6362_H
#define __CONFIG_BMIPS_BCM6362_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 200000000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM6362_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6368_H
#define __CONFIG_BMIPS_BCM6368_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 200000000
@ -20,11 +22,11 @@
#define CONFIG_USB_OHCI_NEW
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#define CONFIG_SYS_FLASH_BASE 0xb8000000

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_BCM6838_H
#define __CONFIG_BMIPS_BCM6838_H
#include <linux/sizes.h>
/* CPU */
#define CONFIG_SYS_MIPS_TIMER_FREQ 160000000
@ -13,11 +15,11 @@
#define CONFIG_SYS_SDRAM_BASE 0x80000000
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
#if defined(CONFIG_BMIPS_BOOT_RAM)
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_INIT_SP_OFFSET 0x2000
#define CONFIG_SYS_INIT_SP_OFFSET SZ_8K
#endif
#endif /* __CONFIG_BMIPS_BCM6838_H */

View File

@ -6,6 +6,8 @@
#ifndef __CONFIG_BMIPS_COMMON_H
#define __CONFIG_BMIPS_COMMON_H
#include <linux/sizes.h>
/* ETH */
#define CONFIG_PHY_RESET_DELAY 20
#define CONFIG_SYS_RX_ETH_BUFFER 6
@ -14,15 +16,11 @@
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
/* RAM */
#define CONFIG_SYS_MEMTEST_START 0xa0000000
#define CONFIG_SYS_MEMTEST_END 0xa2000000
/* Memory usage */
#define CONFIG_SYS_MAXARGS 24
#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)
#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
#define CONFIG_SYS_CBSIZE 512
#define CONFIG_SYS_MALLOC_LEN SZ_2M
#define CONFIG_SYS_BOOTPARAMS_LEN SZ_128K
#define CONFIG_SYS_CBSIZE SZ_512
/* U-Boot */
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE

View File

@ -6,7 +6,7 @@
#include <configs/bmips_common.h>
#include <configs/bmips_bcm6838.h>
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K
#ifdef CONFIG_NAND
#define CONFIG_SYS_MAX_NAND_DEVICE 1

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -8,5 +8,10 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K
#ifdef CONFIG_NAND
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_SELF_INIT
#define CONFIG_SYS_NAND_ONFI_DETECTION
#endif /* CONFIG_NAND */

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -22,7 +22,7 @@
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */
#define CONFIG_SYS_MEMTEST_START 0x80100000

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -22,7 +22,7 @@
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
230400, 460800, 921600 }
/* RAM */
#define CONFIG_SYS_MEMTEST_START 0x80100000

View File

@ -6,5 +6,4 @@
#include <configs/bmips_common.h>
#include <configs/bmips_bcm3380.h>
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
#include <configs/bmips_common.h>
@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -6,5 +6,4 @@
#include <configs/bmips_common.h>
#include <configs/bmips_bcm6338.h>
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -8,5 +8,4 @@
#define CONFIG_REMAKE_ELF
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SIZE SZ_8K

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*
* Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
*/

View File

@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019 MediaTek Inc.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _DT_BINDINGS_MT7628_CLK_H_
#define _DT_BINDINGS_MT7628_CLK_H_
/* Base clocks */
#define CLK_SYS 34
#define CLK_CPU 33
#define CLK_XTAL 32
/* Peripheral clocks */
#define CLK_PWM 31
#define CLK_SDXC 30
#define CLK_CRYPTO 29
#define CLK_MIPS_CNT 28
#define CLK_PCIE 26
#define CLK_UPHY 25
#define CLK_ETH 23
#define CLK_UART2 20
#define CLK_UART1 19
#define CLK_SPI 18
#define CLK_I2S 17
#define CLK_I2C 16
#define CLK_GDMA 14
#define CLK_PIO 13
#define CLK_UART0 12
#define CLK_PCM 11
#define CLK_MC 10
#define CLK_INTC 9
#define CLK_TIMER 8
#endif /* _DT_BINDINGS_MT7628_CLK_H_ */

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*/
#ifndef __DT_BINDINGS_POWER_DOMAIN_BCM6362_H

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
*
* Derived from linux/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
*/

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019 MediaTek Inc.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#ifndef _DT_BINDINGS_MT7628_RESET_H_
#define _DT_BINDINGS_MT7628_RESET_H_
#define MT7628_PWM_RST 31
#define MT7628_SDXC_RST 30
#define MT7628_CRYPTO_RST 29
#define MT7628_AUX_STCK_RST 28
#define MT7628_PCIE_RST 26
#define MT7628_EPHY_RST 24
#define MT7628_ETH_RST 23
#define MT7628_UPHY_RST 22
#define MT7628_UART2_RST 20
#define MT7628_UART1_RST 19
#define MT7628_SPI_RST 18
#define MT7628_I2S_RST 17
#define MT7628_I2C_RST 16
#define MT7628_GDMA_RST 14
#define MT7628_PIO_RST 13
#define MT7628_UART0_RST 12
#define MT7628_PCM_RST 11
#define MT7628_MC_RST 10
#define MT7628_INT_RST 9
#define MT7628_TIMER_RST 8
#define MT7628_HIF_RST 5
#define MT7628_WIFI_RST 4
#define MT7628_SPIS_RST 3
#define MT7628_SYS_RST 0
#endif /* _DT_BINDINGS_MT7628_RESET_H_ */