Merge branch '2018-11-28-master-imports'
- Add MediaTek support
This commit is contained in:
commit
e16c888fab
20
MAINTAINERS
20
MAINTAINERS
@ -158,6 +158,26 @@ T: git git://git.denx.de/u-boot-pxa.git
|
||||
F: arch/arm/cpu/pxa/
|
||||
F: arch/arm/include/asm/arch-pxa/
|
||||
|
||||
ARM MEDIATEK
|
||||
M: Ryder Lee <ryder.lee@mediatek.com>
|
||||
M: Weijie Gao <weijie.gao@mediatek.com>
|
||||
S: Maintained
|
||||
F: arch/arm/mach-mediatek/
|
||||
F: arch/arm/include/asm/arch-mediatek/
|
||||
F: board/mediatek/
|
||||
F: doc/README.mediatek
|
||||
F: drivers/clk/mediatek/
|
||||
F: drivers/mmc/mtk-sd.c
|
||||
F: drivers/pinctrl/mediatek/
|
||||
F: drivers/power/domain/mtk-power-domain.c
|
||||
F: drivers/ram/mediatek/
|
||||
F: drivers/spi/mtk_qspi.c
|
||||
F: drivers/timer/mtk_timer.c
|
||||
F: drivers/watchdog/mtk_wdt.c
|
||||
F: tools/mtk_image.c
|
||||
F: tools/mtk_image.h
|
||||
N: mediatek
|
||||
|
||||
ARM OWL
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
S: Maintained
|
||||
|
22
Makefile
22
Makefile
@ -852,6 +852,8 @@ ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin
|
||||
ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
|
||||
endif
|
||||
|
||||
ALL-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
|
||||
|
||||
# Add optional build target if defined in board/cpu/soc headers
|
||||
ifneq ($(CONFIG_BUILD_TARGET),)
|
||||
ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
|
||||
@ -1361,6 +1363,26 @@ u-boot.elf: u-boot.bin
|
||||
$(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o
|
||||
$(call if_changed,u-boot-elf)
|
||||
|
||||
# MediaTek's ARM-based u-boot needs a header to contains its load address
|
||||
# which is parsed by the BootROM.
|
||||
# If the SPL build is enabled, the header will be added to the spl binary,
|
||||
# and the spl binary and the u-boot.img will be combined into one file.
|
||||
# Otherwise the header will be added to the u-boot.bin directly.
|
||||
|
||||
ifeq ($(CONFIG_SPL),y)
|
||||
spl/u-boot-spl-mtk.bin: spl/u-boot-spl
|
||||
|
||||
u-boot-mtk.bin: u-boot.dtb u-boot.img spl/u-boot-spl-mtk.bin FORCE
|
||||
$(call if_changed,binman)
|
||||
else
|
||||
MKIMAGEFLAGS_u-boot-mtk.bin = -T mtk_image \
|
||||
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
|
||||
-n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
|
||||
|
||||
u-boot-mtk.bin: u-boot.bin FORCE
|
||||
$(call if_changed,mkimage)
|
||||
endif
|
||||
|
||||
ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
|
||||
|
||||
# Rule to link u-boot
|
||||
|
@ -664,6 +664,20 @@ config ARCH_MESON
|
||||
targeted at media players and tablet computers. We currently
|
||||
support the S905 (GXBaby) 64-bit SoC.
|
||||
|
||||
config ARCH_MEDIATEK
|
||||
bool "MediaTek SoCs"
|
||||
select BINMAN
|
||||
select DM
|
||||
select OF_CONTROL
|
||||
select SPL_DM if SPL
|
||||
select SPL_LIBCOMMON_SUPPORT if SPL
|
||||
select SPL_LIBGENERIC_SUPPORT if SPL
|
||||
select SPL_OF_CONTROL if SPL
|
||||
select SUPPORT_SPL
|
||||
help
|
||||
Support for the MediaTek SoCs family developed by MediaTek Inc.
|
||||
Please refer to doc/README.mediatek for more information.
|
||||
|
||||
config ARCH_LPC32XX
|
||||
bool "NXP LPC32xx platform"
|
||||
select CPU_ARM926EJS
|
||||
@ -1449,6 +1463,8 @@ source "arch/arm/mach-rmobile/Kconfig"
|
||||
|
||||
source "arch/arm/mach-meson/Kconfig"
|
||||
|
||||
source "arch/arm/mach-mediatek/Kconfig"
|
||||
|
||||
source "arch/arm/mach-qemu/Kconfig"
|
||||
|
||||
source "arch/arm/mach-rockchip/Kconfig"
|
||||
|
@ -62,6 +62,7 @@ machine-$(CONFIG_ARCH_K3) += k3
|
||||
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
|
||||
# TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD
|
||||
machine-$(CONFIG_KIRKWOOD) += kirkwood
|
||||
machine-$(CONFIG_ARCH_MEDIATEK) += mediatek
|
||||
machine-$(CONFIG_ARCH_MESON) += meson
|
||||
machine-$(CONFIG_ARCH_MVEBU) += mvebu
|
||||
# TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA
|
||||
|
@ -563,6 +563,10 @@ dtb-$(CONFIG_TARGET_STM32MP1) += \
|
||||
|
||||
dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb k3-am654-r5-base-board.dtb
|
||||
|
||||
dtb-$(CONFIG_ARCH_MEDIATEK) += \
|
||||
mt7623n-bananapi-bpi-r2.dtb \
|
||||
mt7629-rfb.dtb
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
||||
# Add any required device tree compiler flags here
|
||||
|
255
arch/arm/dts/mt7623.dtsi
Normal file
255
arch/arm/dts/mt7623.dtsi
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*
|
||||
* SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/mt7623-clk.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/mt7623-power.h>
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7623";
|
||||
interrupt-parent = <&sysirq>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
enable-method = "mediatek,mt6589-smp";
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x0>;
|
||||
clocks = <&infracfg CLK_INFRA_CPUSEL>,
|
||||
<&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
clock-frequency = <1300000000>;
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x1>;
|
||||
clocks = <&infracfg CLK_INFRA_CPUSEL>,
|
||||
<&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
clock-frequency = <1300000000>;
|
||||
};
|
||||
|
||||
cpu2: cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x2>;
|
||||
clocks = <&infracfg CLK_INFRA_CPUSEL>,
|
||||
<&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
clock-frequency = <1300000000>;
|
||||
};
|
||||
|
||||
cpu3: cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x3>;
|
||||
clocks = <&infracfg CLK_INFRA_CPUSEL>,
|
||||
<&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
clock-frequency = <1300000000>;
|
||||
};
|
||||
};
|
||||
|
||||
system_clk: dummy13m {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <13000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
rtc32k: oscillator-1 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32000>;
|
||||
clock-output-names = "rtc32k";
|
||||
};
|
||||
|
||||
clk26m: oscillator-0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <26000000>;
|
||||
clock-output-names = "clk26m";
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
clock-frequency = <13000000>;
|
||||
arm,cpu-registers-not-fw-configured;
|
||||
};
|
||||
|
||||
topckgen: clock-controller@10000000 {
|
||||
compatible = "mediatek,mt7623-topckgen";
|
||||
reg = <0x10000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
infracfg: syscon@10001000 {
|
||||
compatible = "mediatek,mt7623-infracfg", "syscon";
|
||||
reg = <0x10001000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
pericfg: syscon@10003000 {
|
||||
compatible = "mediatek,mt7623-pericfg", "syscon";
|
||||
reg = <0x10003000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@10005000 {
|
||||
compatible = "mediatek,mt7623-pinctrl";
|
||||
reg = <0x10005000 0x1000>;
|
||||
|
||||
gpio: gpio-controller {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
scpsys: scpsys@10006000 {
|
||||
compatible = "mediatek,mt7623-scpsys";
|
||||
#power-domain-cells = <1>;
|
||||
reg = <0x10006000 0x1000>;
|
||||
infracfg = <&infracfg>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>,
|
||||
<&topckgen CLK_TOP_MFG_SEL>,
|
||||
<&topckgen CLK_TOP_ETHIF_SEL>;
|
||||
clock-names = "mm", "mfg", "ethif";
|
||||
};
|
||||
|
||||
watchdog: watchdog@10007000 {
|
||||
compatible = "mediatek,wdt";
|
||||
reg = <0x10007000 0x100>;
|
||||
};
|
||||
|
||||
wdt-reboot {
|
||||
compatible = "wdt-reboot";
|
||||
wdt = <&watchdog>;
|
||||
};
|
||||
|
||||
timer0: timer@10008000 {
|
||||
compatible = "mediatek,timer";
|
||||
reg = <0x10008000 0x80>;
|
||||
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&system_clk>;
|
||||
clock-names = "system-clk";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
sysirq: interrupt-controller@10200100 {
|
||||
compatible = "mediatek,sysirq";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
reg = <0x10200100 0x1c>;
|
||||
};
|
||||
|
||||
apmixedsys: clock-controller@10209000 {
|
||||
compatible = "mediatek,mt7623-apmixedsys";
|
||||
reg = <0x10209000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@10211000 {
|
||||
compatible = "arm,cortex-a7-gic";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
reg = <0x10211000 0x1000>,
|
||||
<0x10212000 0x1000>,
|
||||
<0x10214000 0x2000>,
|
||||
<0x10216000 0x2000>;
|
||||
};
|
||||
|
||||
uart0: serial@11002000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11002000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART0>;
|
||||
clock-names = "baud", "bus";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart1: serial@11003000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11003000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART1>;
|
||||
clock-names = "baud", "bus";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@11004000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11004000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART2>;
|
||||
clock-names = "baud", "bus";
|
||||
status = "disabled";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
uart3: serial@11005000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11005000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART3>;
|
||||
clock-names = "baud", "bus";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc0: mmc@11230000 {
|
||||
compatible = "mediatek,mt7623-mmc";
|
||||
reg = <0x11230000 0x1000>;
|
||||
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&pericfg CLK_PERI_MSDC30_0>,
|
||||
<&topckgen CLK_TOP_MSDC30_0_SEL>;
|
||||
clock-names = "source", "hclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc1: mmc@11240000 {
|
||||
compatible = "mediatek,mt7623-mmc";
|
||||
reg = <0x11240000 0x1000>;
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&pericfg CLK_PERI_MSDC30_1>,
|
||||
<&topckgen CLK_TOP_MSDC30_1_SEL>;
|
||||
clock-names = "source", "hclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ethsys: syscon@1b000000 {
|
||||
compatible = "mediatek,mt7623-ethsys";
|
||||
reg = <0x1b000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
207
arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
Normal file
207
arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*
|
||||
* SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7623.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Bananapi BPI-R2";
|
||||
compatible = "bananapi,bpi-r2", "mediatek,mt7623";
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart2;
|
||||
tick-timer = &timer0;
|
||||
};
|
||||
|
||||
reg_1p8v: regulator-1p8v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-1.8V";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
reg_3p3v: regulator-3p3v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-3.3V";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
reg_5v: regulator-5v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-5V";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
blue {
|
||||
label = "bpi-r2:pio:blue";
|
||||
gpios = <&gpio 241 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
green {
|
||||
label = "bpi-r2:pio:green";
|
||||
gpios = <&gpio 240 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
red {
|
||||
label = "bpi-r2:pio:red";
|
||||
gpios = <&gpio 239 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins_default>;
|
||||
status = "okay";
|
||||
bus-width = <8>;
|
||||
max-frequency = <50000000>;
|
||||
cap-mmc-highspeed;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
vqmmc-supply = <®_1p8v>;
|
||||
non-removable;
|
||||
};
|
||||
|
||||
&mmc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc1_pins_default>;
|
||||
status = "okay";
|
||||
bus-width = <4>;
|
||||
max-frequency = <50000000>;
|
||||
cap-sd-highspeed;
|
||||
cd-gpios = <&gpio 261 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
vqmmc-supply = <®_3p3v>;
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
ephy_default: ephy_default {
|
||||
mux {
|
||||
function = "eth";
|
||||
groups = "mdc_mdio", "ephy";
|
||||
};
|
||||
|
||||
conf {
|
||||
pins = "G2_TXEN", "G2_TXD0", "G2_TXD1", "G2_TXD2",
|
||||
"G2_TXD3", "G2_TXC", "G2_RXC", "G2_RXD0",
|
||||
"G2_RXD1", "G2_RXD2", "G2_RXD3", "G2_RXDV",
|
||||
"MDC", "MDIO";
|
||||
drive-strength = <12>;
|
||||
mediatek,tdsel = <5>;
|
||||
};
|
||||
};
|
||||
|
||||
mmc0_pins_default: mmc0default {
|
||||
mux {
|
||||
function = "msdc";
|
||||
groups = "msdc0";
|
||||
};
|
||||
|
||||
conf-cmd-data {
|
||||
pins = "MSDC0_CMD", "MSDC0_DAT0", "MSDC0_DAT1",
|
||||
"MSDC0_DAT2", "MSDC0_DAT3", "MSDC0_DAT4",
|
||||
"MSDC0_DAT5", "MSDC0_DAT6", "MSDC0_DAT7";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
conf-clk {
|
||||
pins = "MSDC0_CLK";
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
conf-rst {
|
||||
pins = "MSDC0_RSTB";
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
mmc1_pins_default: mmc1default {
|
||||
mux {
|
||||
function = "msdc";
|
||||
groups = "msdc1", "msdc1_wp_0";
|
||||
};
|
||||
|
||||
conf-cmd-data {
|
||||
pins = "MSDC1_DAT0", "MSDC1_DAT1", "MSDC1_DAT2",
|
||||
"MSDC1_DAT3", "MSDC1_DAT3", "MSDC1_CMD";
|
||||
input-enable;
|
||||
drive-strength = <4>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
conf-clk {
|
||||
pins = "MSDC1_CLK";
|
||||
drive-strength = <4>;
|
||||
};
|
||||
|
||||
conf-wp {
|
||||
pins = "EINT7";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
uart0_pins_a: uart0-default {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart0_0_txd_rxd";
|
||||
};
|
||||
};
|
||||
|
||||
uart1_pins_a: uart1-default {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart1_0_txd_rxd";
|
||||
};
|
||||
};
|
||||
|
||||
uart2_pins_a: uart2-default {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart2_0_txd_rxd";
|
||||
};
|
||||
};
|
||||
|
||||
uart2_pins_b: uart2-alt {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart2_1_txd_rxd";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pins_a>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart2_pins_a>;
|
||||
status = "okay";
|
||||
};
|
24
arch/arm/dts/mt7629-rfb-u-boot.dtsi
Normal file
24
arch/arm/dts/mt7629-rfb-u-boot.dtsi
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
/ {
|
||||
binman {
|
||||
filename = "u-boot-mtk.bin";
|
||||
pad-byte = <0xff>;
|
||||
|
||||
#ifdef CONFIG_SPL
|
||||
blob {
|
||||
filename = "spl/u-boot-spl-mtk.bin";
|
||||
size = <CONFIG_SPL_PAD_TO>;
|
||||
};
|
||||
|
||||
u-boot-img {
|
||||
};
|
||||
#endif
|
||||
};
|
||||
};
|
70
arch/arm/dts/mt7629-rfb.dts
Normal file
70
arch/arm/dts/mt7629-rfb.dts
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*
|
||||
* SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7629.dtsi"
|
||||
|
||||
/ {
|
||||
model = "MediaTek MT7629 RFB";
|
||||
compatible = "mediatek,mt7629-rfb", "mediatek,mt7629";
|
||||
|
||||
aliases {
|
||||
spi0 = &qspi;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
tick-timer = &timer0;
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
qspi_pins: qspi-pins {
|
||||
mux {
|
||||
function = "flash";
|
||||
groups = "spi_nor";
|
||||
};
|
||||
};
|
||||
|
||||
uart0_pins: uart0-default {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart0_txd_rxd";
|
||||
};
|
||||
};
|
||||
|
||||
watchdog_pins: watchdog-default {
|
||||
mux {
|
||||
function = "watchdog";
|
||||
groups = "watchdog";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&qspi {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&qspi_pins>;
|
||||
status = "okay";
|
||||
|
||||
spi-flash@0{
|
||||
compatible = "spi-flash";
|
||||
reg = <0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&watchdog_pins>;
|
||||
status = "okay";
|
||||
};
|
244
arch/arm/dts/mt7629.dtsi
Normal file
244
arch/arm/dts/mt7629.dtsi
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*
|
||||
* SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/mt7629-clk.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/mt7629-power.h>
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7629";
|
||||
interrupt-parent = <&sysirq>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
enable-method = "mediatek,mt6589-smp";
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x0>;
|
||||
clock-frequency = <1250000000>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x1>;
|
||||
clock-frequency = <1250000000>;
|
||||
};
|
||||
};
|
||||
|
||||
clk20m: oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <20000000>;
|
||||
clock-output-names = "clk20m";
|
||||
};
|
||||
|
||||
clk40m: oscillator@1 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <40000000>;
|
||||
clock-output-names = "clkxtal";
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
|
||||
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
clock-frequency = <20000000>;
|
||||
arm,cpu-registers-not-fw-configured;
|
||||
};
|
||||
|
||||
infracfg: syscon@10000000 {
|
||||
compatible = "mediatek,mt7629-infracfg", "syscon";
|
||||
reg = <0x10000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
pericfg: syscon@10002000 {
|
||||
compatible = "mediatek,mt7629-pericfg", "syscon";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
timer0: timer@10004000 {
|
||||
compatible = "mediatek,timer";
|
||||
reg = <0x10004000 0x80>;
|
||||
interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_10M_SEL>,
|
||||
<&topckgen CLK_TOP_CLKXTAL_D4>;
|
||||
clock-names = "mux", "src";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
scpsys: scpsys@10006000 {
|
||||
compatible = "mediatek,mt7629-scpsys";
|
||||
reg = <0x10006000 0x1000>;
|
||||
clocks = <&topckgen CLK_TOP_HIF_SEL>;
|
||||
clock-names = "hif_sel";
|
||||
assigned-clocks = <&topckgen CLK_TOP_HIF_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
|
||||
#power-domain-cells = <1>;
|
||||
infracfg = <&infracfg>;
|
||||
};
|
||||
|
||||
mcucfg: syscon@10200000 {
|
||||
compatible = "mediatek,mt7629-mcucfg", "syscon";
|
||||
reg = <0x10200000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
sysirq: interrupt-controller@10200a80 {
|
||||
compatible = "mediatek,sysirq";
|
||||
reg = <0x10200a80 0x20>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
};
|
||||
|
||||
dramc: dramc@10203000 {
|
||||
compatible = "mediatek,mt7629-dramc";
|
||||
reg = <0x10203000 0x600>, /* EMI */
|
||||
<0x10213000 0x1000>, /* DDRPHY */
|
||||
<0x10214000 0xd00>; /* DRAMC_AO */
|
||||
clocks = <&topckgen CLK_TOP_DDRPHYCFG_SEL>,
|
||||
<&topckgen CLK_TOP_SYSPLL1_D8>,
|
||||
<&topckgen CLK_TOP_MEM_SEL>,
|
||||
<&topckgen CLK_TOP_DMPLL>;
|
||||
clock-names = "phy", "phy_mux", "mem", "mem_mux";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
apmixedsys: clock-controller@10209000 {
|
||||
compatible = "mediatek,mt7629-apmixedsys";
|
||||
reg = <0x10209000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
topckgen: clock-controller@10210000 {
|
||||
compatible = "mediatek,mt7629-topckgen";
|
||||
reg = <0x10210000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
watchdog: watchdog@10212000 {
|
||||
compatible = "mediatek,wdt";
|
||||
reg = <0x10212000 0x600>;
|
||||
interrupts = <GIC_SPI 128 IRQ_TYPE_EDGE_FALLING>;
|
||||
#reset-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
wdt-reboot {
|
||||
compatible = "wdt-reboot";
|
||||
wdt = <&watchdog>;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@10217000 {
|
||||
compatible = "mediatek,mt7629-pinctrl";
|
||||
reg = <0x10217000 0x8000>;
|
||||
|
||||
gpio: gpio-controller {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
gic: interrupt-controller@10300000 {
|
||||
compatible = "arm,gic-400";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
reg = <0x10310000 0x1000>,
|
||||
<0x10320000 0x1000>,
|
||||
<0x10340000 0x2000>,
|
||||
<0x10360000 0x2000>;
|
||||
};
|
||||
|
||||
uart0: serial@11002000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11002000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART0_PD>;
|
||||
clock-names = "baud", "bus";
|
||||
status = "disabled";
|
||||
assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
uart1: serial@11003000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11003000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART1_PD>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@11004000 {
|
||||
compatible = "mediatek,hsuart";
|
||||
reg = <0x11004000 0x400>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&pericfg CLK_PERI_UART2_PD>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
qspi: qspi@11014000 {
|
||||
compatible = "mediatek,mt7629-qspi";
|
||||
reg = <0x11014000 0xe0>, <0x30000000 0x10000000>;
|
||||
reg-names = "reg_base", "mem_base";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
ethsys: syscon@1b000000 {
|
||||
compatible = "mediatek,mt7629-ethsys", "syscon";
|
||||
reg = <0x1b000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
sgmiisys0: syscon@1b128000 {
|
||||
compatible = "mediatek,mt7629-sgmiisys", "syscon";
|
||||
reg = <0x1b128000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
sgmiisys1: syscon@1b130000 {
|
||||
compatible = "mediatek,mt7629-sgmiisys", "syscon";
|
||||
reg = <0x1b130000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
9
arch/arm/include/asm/arch-mediatek/gpio.h
Normal file
9
arch/arm/include/asm/arch-mediatek/gpio.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MEDIATEK_GPIO_H
|
||||
#define __MEDIATEK_GPIO_H
|
||||
|
||||
#endif /* __MEDIATEK_GPIO_H */
|
17
arch/arm/include/asm/arch-mediatek/misc.h
Normal file
17
arch/arm/include/asm/arch-mediatek/misc.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MEDIATEK_MISC_H_
|
||||
#define __MEDIATEK_MISC_H_
|
||||
|
||||
#define VER_BASE 0x08000000
|
||||
#define VER_SIZE 0x10
|
||||
|
||||
#define APHW_CODE 0x00
|
||||
#define APHW_SUBCODE 0x04
|
||||
#define APHW_VER 0x08
|
||||
#define APSW_VER 0x0c
|
||||
|
||||
#endif /* __MEDIATEK_MISC_H_ */
|
39
arch/arm/mach-mediatek/Kconfig
Normal file
39
arch/arm/mach-mediatek/Kconfig
Normal file
@ -0,0 +1,39 @@
|
||||
if ARCH_MEDIATEK
|
||||
|
||||
config SYS_SOC
|
||||
default "mediatek"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "mediatek"
|
||||
|
||||
choice
|
||||
prompt "MediaTek board select"
|
||||
|
||||
config TARGET_MT7623
|
||||
bool "MediaTek MT7623 SoC"
|
||||
select CPU_V7A
|
||||
select ARCH_MISC_INIT
|
||||
help
|
||||
The MediaTek MT7623 is a ARM-based SoC with a quad-core Cortex-A7
|
||||
including NEON and GPU, Mali-450 graphics, several DDR3 options,
|
||||
crypto engine, built-in Wi-Fi / Bluetooth combo chip, JPEG decoder,
|
||||
video interfaces supporting HDMI and MIPI, and video codec support.
|
||||
Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe,
|
||||
I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM.
|
||||
|
||||
config TARGET_MT7629
|
||||
bool "MediaTek MT7629 SoC"
|
||||
select CPU_V7A
|
||||
select SPL
|
||||
select ARCH_MISC_INIT
|
||||
help
|
||||
The MediaTek MT7629 is a ARM-based SoC with a dual-core Cortex-A7
|
||||
including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
|
||||
switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/mediatek/mt7623/Kconfig"
|
||||
source "board/mediatek/mt7629/Kconfig"
|
||||
|
||||
endif
|
7
arch/arm/mach-mediatek/Makefile
Normal file
7
arch/arm/mach-mediatek/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o
|
||||
|
||||
obj-$(CONFIG_TARGET_MT7623) += mt7623/
|
||||
obj-$(CONFIG_TARGET_MT7629) += mt7629/
|
34
arch/arm/mach-mediatek/cpu.c
Normal file
34
arch/arm/mach-mediatek/cpu.c
Normal file
@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <wdt.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
|
||||
int arch_misc_init(void)
|
||||
{
|
||||
struct udevice *wdt;
|
||||
int ret;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_WDT, &wdt);
|
||||
if (!ret)
|
||||
wdt_stop(wdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
icache_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
/* Enable D-cache. I-cache is already enabled in start.S */
|
||||
dcache_enable();
|
||||
}
|
11
arch/arm/mach-mediatek/init.h
Normal file
11
arch/arm/mach-mediatek/init.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MEDIATEK_INIT_H_
|
||||
#define __MEDIATEK_INIT_H_
|
||||
|
||||
extern int mtk_soc_early_init(void);
|
||||
|
||||
#endif /* __MEDIATEK_INIT_H_ */
|
4
arch/arm/mach-mediatek/mt7623/Makefile
Normal file
4
arch/arm/mach-mediatek/mt7623/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += init.o
|
||||
obj-y += lowlevel_init.o
|
54
arch/arm/mach-mediatek/mt7623/init.c
Normal file
54
arch/arm/mach-mediatek/mt7623/init.c
Normal file
@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/arch/misc.h>
|
||||
|
||||
#include "preloader.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct boot_argument *preloader_param;
|
||||
|
||||
int mtk_soc_early_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (((size_t)preloader_param >= CONFIG_SYS_SDRAM_BASE) &&
|
||||
((size_t)preloader_param % sizeof(size_t) == 0) &&
|
||||
preloader_param->magic == BOOT_ARGUMENT_MAGIC &&
|
||||
preloader_param->dram_rank_num <=
|
||||
ARRAY_SIZE(preloader_param->dram_rank_size)) {
|
||||
gd->ram_size = 0;
|
||||
|
||||
for (i = 0; i < preloader_param->dram_rank_num; i++)
|
||||
gd->ram_size += preloader_param->dram_rank_size[i];
|
||||
} else {
|
||||
gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
|
||||
SZ_2G);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
void __iomem *chipid;
|
||||
u32 swver;
|
||||
|
||||
chipid = ioremap(VER_BASE, VER_SIZE);
|
||||
swver = readl(chipid + APSW_VER);
|
||||
|
||||
printf("CPU: MediaTek MT7623 E%d\n", (swver & 0xf) + 1);
|
||||
|
||||
return 0;
|
||||
}
|
22
arch/arm/mach-mediatek/mt7623/lowlevel_init.S
Normal file
22
arch/arm/mach-mediatek/mt7623/lowlevel_init.S
Normal file
@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.extern preloader_param
|
||||
|
||||
ENTRY(save_boot_params)
|
||||
ldr r6, =preloader_param
|
||||
str r4, [r6]
|
||||
b save_boot_params_ret
|
||||
ENDPROC(save_boot_params)
|
||||
|
||||
ENTRY(lowlevel_init)
|
||||
/* enable SMP bit */
|
||||
mrc p15, 0, r0, c1, c0, 1
|
||||
orr r0, r0, #0x40
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
mov pc, lr
|
||||
ENDPROC(lowlevel_init)
|
99
arch/arm/mach-mediatek/mt7623/preloader.h
Normal file
99
arch/arm/mach-mediatek/mt7623/preloader.h
Normal file
@ -0,0 +1,99 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __PRELOADER_H_
|
||||
#define __PRELOADER_H_
|
||||
|
||||
enum forbidden_mode {
|
||||
F_FACTORY_MODE = 0x0001
|
||||
};
|
||||
|
||||
union lk_hdr {
|
||||
struct {
|
||||
u32 magic;
|
||||
u32 size;
|
||||
char name[32];
|
||||
u32 loadaddr;
|
||||
};
|
||||
|
||||
u8 data[512];
|
||||
};
|
||||
|
||||
struct sec_limit {
|
||||
unsigned int magic_num;
|
||||
enum forbidden_mode forbid_mode;
|
||||
};
|
||||
|
||||
enum bootmode {
|
||||
NORMAL_BOOT = 0,
|
||||
META_BOOT = 1,
|
||||
RECOVERY_BOOT = 2,
|
||||
SW_REBOOT = 3,
|
||||
FACTORY_BOOT = 4,
|
||||
ADVMETA_BOOT = 5,
|
||||
ATE_FACTORY_BOOT = 6,
|
||||
ALARM_BOOT = 7,
|
||||
|
||||
KERNEL_POWER_OFF_CHARGING_BOOT = 8,
|
||||
LOW_POWER_OFF_CHARGING_BOOT = 9,
|
||||
|
||||
FAST_BOOT = 99,
|
||||
DOWNLOAD_BOOT = 100,
|
||||
UNKNOWN_BOOT
|
||||
};
|
||||
|
||||
enum boot_reason {
|
||||
BR_POWER_KEY = 0,
|
||||
BR_USB,
|
||||
BR_RTC,
|
||||
BR_WDT,
|
||||
BR_WDT_BY_PASS_PWK,
|
||||
BR_TOOL_BY_PASS_PWK,
|
||||
BR_2SEC_REBOOT,
|
||||
BR_UNKNOWN
|
||||
};
|
||||
|
||||
enum meta_com_type {
|
||||
META_UNKNOWN_COM = 0,
|
||||
META_UART_COM,
|
||||
META_USB_COM
|
||||
};
|
||||
|
||||
struct da_info_t {
|
||||
u32 addr;
|
||||
u32 arg1;
|
||||
u32 arg2;
|
||||
u32 len;
|
||||
u32 sig_len;
|
||||
};
|
||||
|
||||
struct boot_argument {
|
||||
u32 magic;
|
||||
enum bootmode boot_mode;
|
||||
u32 e_flag;
|
||||
u32 log_port;
|
||||
u32 log_baudrate;
|
||||
u8 log_enable;
|
||||
u8 part_num;
|
||||
u8 reserved[2];
|
||||
u32 dram_rank_num;
|
||||
u32 dram_rank_size[4];
|
||||
u32 boot_reason;
|
||||
enum meta_com_type meta_com_type;
|
||||
u32 meta_com_id;
|
||||
u32 boot_time;
|
||||
struct da_info_t da_info;
|
||||
struct sec_limit sec_limit;
|
||||
union lk_hdr *part_info;
|
||||
u8 md_type[4];
|
||||
u32 ddr_reserve_enable;
|
||||
u32 ddr_reserve_success;
|
||||
u32 chip_ver;
|
||||
char pl_version[8];
|
||||
};
|
||||
|
||||
#define BOOT_ARGUMENT_MAGIC 0x504c504c
|
||||
|
||||
#endif /* __PRELOADER_H_ */
|
4
arch/arm/mach-mediatek/mt7629/Makefile
Normal file
4
arch/arm/mach-mediatek/mt7629/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += init.o
|
||||
obj-y += lowlevel_init.o
|
128
arch/arm/mach-mediatek/mt7629/init.c
Normal file
128
arch/arm/mach-mediatek/mt7629/init.c
Normal file
@ -0,0 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <ram.h>
|
||||
#include <asm/arch/misc.h>
|
||||
#include <asm/sections.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <dt-bindings/clock/mt7629-clk.h>
|
||||
|
||||
#define L2_CFG_BASE 0x10200000
|
||||
#define L2_CFG_SIZE 0x1000
|
||||
#define L2_SHARE_CFG_MP0 0x7f0
|
||||
#define L2_SHARE_MODE_OFF BIT(8)
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int mtk_pll_early_init(void)
|
||||
{
|
||||
unsigned long pll_rates[] = {
|
||||
[CLK_APMIXED_ARMPLL] = 1250000000,
|
||||
[CLK_APMIXED_MAINPLL] = 1120000000,
|
||||
[CLK_APMIXED_UNIV2PLL] = 1200000000,
|
||||
[CLK_APMIXED_ETH1PLL] = 500000000,
|
||||
[CLK_APMIXED_ETH2PLL] = 700000000,
|
||||
[CLK_APMIXED_SGMIPLL] = 650000000,
|
||||
};
|
||||
struct udevice *dev;
|
||||
int ret, i;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(mtk_clk_apmixedsys), &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* configure default rate then enable apmixedsys */
|
||||
for (i = 0; i < ARRAY_SIZE(pll_rates); i++) {
|
||||
struct clk clk = { .id = i, .dev = dev };
|
||||
|
||||
ret = clk_set_rate(&clk, pll_rates[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(&clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* setup mcu bus */
|
||||
ret = uclass_get_device_by_driver(UCLASS_SYSCON,
|
||||
DM_GET_DRIVER(mtk_mcucfg), &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_soc_early_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
/* initialize early clocks */
|
||||
ret = mtk_pll_early_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_RAM, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mach_cpu_init(void)
|
||||
{
|
||||
void __iomem *base;
|
||||
|
||||
base = ioremap(L2_CFG_BASE, L2_CFG_SIZE);
|
||||
|
||||
/* disable L2C shared mode */
|
||||
writel(L2_SHARE_MODE_OFF, base + L2_SHARE_CFG_MP0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
struct ram_info ram;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_RAM, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ram_get_info(dev, &ram);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
debug("RAM init base=%lx, size=%x\n", ram.base, ram.size);
|
||||
|
||||
gd->ram_size = ram.size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
void __iomem *chipid;
|
||||
u32 hwcode, swver;
|
||||
|
||||
chipid = ioremap(VER_BASE, VER_SIZE);
|
||||
hwcode = readl(chipid + APHW_CODE);
|
||||
swver = readl(chipid + APSW_VER);
|
||||
|
||||
printf("CPU: MediaTek MT%04x E%d\n", hwcode, (swver & 0xf) + 1);
|
||||
|
||||
return 0;
|
||||
}
|
50
arch/arm/mach-mediatek/mt7629/lowlevel_init.S
Normal file
50
arch/arm/mach-mediatek/mt7629/lowlevel_init.S
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(lowlevel_init)
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/* Return to U-Boot via saved link register */
|
||||
mov pc, lr
|
||||
#else
|
||||
/*
|
||||
* Arch timer :
|
||||
* set CNTFRQ = 20Mhz, set CNTVOFF = 0
|
||||
*/
|
||||
movw r0, #0x2d00
|
||||
movt r0, #0x131
|
||||
mcr p15, 0, r0, c14, c0, 0
|
||||
|
||||
/* enable SMP bit */
|
||||
mrc p15, 0, r0, c1, c0, 1
|
||||
orr r0, r0, #0x40
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
|
||||
/* if MP core, handle secondary cores */
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
ands r1, r0, #0x40000000
|
||||
bne go @ Go if UP
|
||||
ands r0, r0, #0x0f
|
||||
beq go @ Go if core0 on primary core tile
|
||||
b secondary
|
||||
|
||||
go:
|
||||
/* master CPU */
|
||||
mov pc, lr
|
||||
|
||||
secondary:
|
||||
/* read slave CPU number into r0 firstly */
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
and r0, r0, #0x0f
|
||||
|
||||
loop:
|
||||
dsb
|
||||
isb
|
||||
wfi @Zzz...
|
||||
b loop
|
||||
#endif
|
||||
ENDPROC(lowlevel_init)
|
43
arch/arm/mach-mediatek/spl.c
Normal file
43
arch/arm/mach-mediatek/spl.c
Normal file
@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <spl.h>
|
||||
|
||||
#include "init.h"
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spl_early_init();
|
||||
if (ret)
|
||||
hang();
|
||||
|
||||
/* enable console uart printing */
|
||||
preloader_console_init();
|
||||
|
||||
/* soc early initialization */
|
||||
ret = mtk_soc_early_init();
|
||||
if (ret)
|
||||
hang();
|
||||
}
|
||||
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
#if defined(CONFIG_SPL_SPI_SUPPORT)
|
||||
return BOOT_DEVICE_SPI;
|
||||
#elif defined(CONFIG_SPL_MMC_SUPPORT)
|
||||
return BOOT_DEVICE_MMC1;
|
||||
#elif defined(CONFIG_SPL_NAND_SUPPORT)
|
||||
return BOOT_DEVICE_NAND;
|
||||
#elif defined(CONFIG_SPL_NOR_SUPPORT)
|
||||
return BOOT_DEVICE_NOR;
|
||||
#else
|
||||
return BOOT_DEVICE_NONE;
|
||||
#endif
|
||||
}
|
13
board/mediatek/mt7623/Kconfig
Normal file
13
board/mediatek/mt7623/Kconfig
Normal file
@ -0,0 +1,13 @@
|
||||
if TARGET_MT7623
|
||||
|
||||
config SYS_BOARD
|
||||
default "mt7623"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "mt7623"
|
||||
|
||||
config MTK_BROM_HEADER_INFO
|
||||
string
|
||||
default "lk=1"
|
||||
|
||||
endif
|
7
board/mediatek/mt7623/MAINTAINERS
Normal file
7
board/mediatek/mt7623/MAINTAINERS
Normal file
@ -0,0 +1,7 @@
|
||||
MT7623
|
||||
M: Ryder Lee <ryder.lee@mediatek.com>
|
||||
M: Weijie Gao <weijie.gao@mediatek.com>
|
||||
S: Maintained
|
||||
F: board/mediatek/mt7623
|
||||
F: include/configs/mt7623.h
|
||||
F: configs/mt7623n_bpir2_defconfig
|
3
board/mediatek/mt7623/Makefile
Normal file
3
board/mediatek/mt7623/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += mt7623_rfb.o
|
16
board/mediatek/mt7623/mt7623_rfb.c
Normal file
16
board/mediatek/mt7623/mt7623_rfb.c
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
17
board/mediatek/mt7629/Kconfig
Normal file
17
board/mediatek/mt7629/Kconfig
Normal file
@ -0,0 +1,17 @@
|
||||
if TARGET_MT7629
|
||||
|
||||
config SYS_BOARD
|
||||
default "mt7629"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "mt7629"
|
||||
|
||||
config MTK_SPL_PAD_SIZE
|
||||
hex
|
||||
default 0x10000
|
||||
|
||||
config MTK_BROM_HEADER_INFO
|
||||
string
|
||||
default "media=nor"
|
||||
|
||||
endif
|
7
board/mediatek/mt7629/MAINTAINERS
Normal file
7
board/mediatek/mt7629/MAINTAINERS
Normal file
@ -0,0 +1,7 @@
|
||||
MT7629
|
||||
M: Ryder Lee <ryder.lee@mediatek.com>
|
||||
M: Weijie Gao <weijie.gao@mediatek.com>
|
||||
S: Maintained
|
||||
F: board/mediatek/mt7629
|
||||
F: include/configs/mt7629.h
|
||||
F: configs/mt7629_rfb_defconfig
|
3
board/mediatek/mt7629/Makefile
Normal file
3
board/mediatek/mt7629/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += mt7629_rfb.o
|
16
board/mediatek/mt7629/mt7629_rfb.c
Normal file
16
board/mediatek/mt7629/mt7629_rfb.c
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
@ -166,6 +166,7 @@ static const table_entry_t uimage_type[] = {
|
||||
{ IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
|
||||
{ IH_TYPE_PMMC, "pmmc", "TI Power Management Micro-Controller Firmware",},
|
||||
{ IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
|
||||
{ IH_TYPE_MTKIMAGE, "mtk_image", "MediaTek BootROM loadable Image" },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
|
54
configs/mt7623n_bpir2_defconfig
Normal file
54
configs/mt7623n_bpir2_defconfig
Normal file
@ -0,0 +1,54 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_THUMB_BUILD=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_SYS_TEXT_BASE=0x81e00000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_TARGET_MT7623=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2"
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_SYS_PROMPT="U-Boot> "
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PART=y
|
||||
CONFIG_CMD_READ=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_OF_EMBED=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
# CONFIG_BLOCK_CACHE is not set
|
||||
CONFIG_CLK=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_DM_MMC=y
|
||||
# CONFIG_MMC_QUIRKS is not set
|
||||
CONFIG_MMC_HS400_SUPPORT=y
|
||||
CONFIG_MMC_MTK=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL_MT7623=y
|
||||
CONFIG_POWER_DOMAIN=y
|
||||
CONFIG_MTK_POWER_DOMAIN=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_MTK_SERIAL=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_WATCHDOG=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_MTK_TIMER=y
|
||||
CONFIG_WDT_MTK=y
|
||||
CONFIG_LZMA=y
|
||||
# CONFIG_EFI_LOADER is not set
|
73
configs/mt7629_rfb_defconfig
Normal file
73
configs/mt7629_rfb_defconfig
Normal file
@ -0,0 +1,73 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_THUMB_BUILD=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_SYS_TEXT_BASE=0x41e00000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_TARGET_MT7629=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7629-rfb"
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SPL_NOR_SUPPORT=y
|
||||
CONFIG_SPL_WATCHDOG_SUPPORT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_SYS_PROMPT="U-Boot> "
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SF_TEST=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_PING=y
|
||||
# CONFIG_PARTITIONS is not set
|
||||
CONFIG_OF_EMBED=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
|
||||
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SPL_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
CONFIG_SPL_SYSCON=y
|
||||
CONFIG_CLK=y
|
||||
CONFIG_SPL_CLK=y
|
||||
CONFIG_DM_GPIO=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_ISSI=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL_MT7629=y
|
||||
CONFIG_POWER_DOMAIN=y
|
||||
CONFIG_MTK_POWER_DOMAIN=y
|
||||
CONFIG_RAM=y
|
||||
CONFIG_SPL_RAM=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_MTK_SERIAL=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_MTK_QSPI=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_WATCHDOG=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_SPL_TIMER=y
|
||||
CONFIG_MTK_TIMER=y
|
||||
CONFIG_WDT_MTK=y
|
||||
CONFIG_LZMA=y
|
||||
# CONFIG_EFI_LOADER is not set
|
221
doc/README.mediatek
Normal file
221
doc/README.mediatek
Normal file
@ -0,0 +1,221 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2018 MediaTek Inc.
|
||||
# Ryder Lee <ryder.lee@kernel.org>
|
||||
|
||||
|
||||
This document describes how to compile the U-Boot and how to change U-Boot
|
||||
configuration about the MediaTek SoCs.
|
||||
|
||||
|
||||
Build Procedure
|
||||
===============
|
||||
-Set the cross compiler:
|
||||
|
||||
# export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi-
|
||||
|
||||
-Clean-up old residuals:
|
||||
|
||||
# make mrproper
|
||||
|
||||
-Configure the U-Boot:
|
||||
|
||||
# make <defconfig_file>
|
||||
# make
|
||||
|
||||
- For the MT7623n bananapi R2 board use "mt7623n_bpir2_defconfig"
|
||||
- For the MT7629 reference board use "mt7629_rfb_defconfig"
|
||||
|
||||
|
||||
Boot sequence
|
||||
=============
|
||||
-Bootrom -> MTK preloader -> U-Boot
|
||||
|
||||
- MT7623n
|
||||
|
||||
This version of U-Boot doesn't implement SPL. So, MTK preloader binary
|
||||
is needed to boot up:
|
||||
|
||||
https://github.com/BPI-SINOVOIP/BPI-R2-bsp/tree/master/mt-pack/mtk/bpi-r2/bin
|
||||
|
||||
|
||||
-Bootrom -> SPL -> U-Boot
|
||||
|
||||
- MT7629
|
||||
|
||||
|
||||
Configuration update
|
||||
====================
|
||||
To update the U-Boot configuration, please refer to doc/README.kconfig
|
||||
|
||||
|
||||
MediaTek image header
|
||||
=====================
|
||||
Currently there are two image headers used for MediaTek chips:
|
||||
|
||||
- BootROM image header. This header is used by the first stage bootloader. It records
|
||||
the desired compatible boot device, integrity information and its load address.
|
||||
|
||||
The on-chip BootROM will firstly verify integrity and compatibility of the bootloader.
|
||||
|
||||
If verification passed, the BootROM will then load the bootloader into on-chip SRAM,
|
||||
and pass control to it.
|
||||
|
||||
Note that this header is actually a combination of three independent headers:
|
||||
Device header, BRLYT header and GFH header.
|
||||
|
||||
Used by U-Boot SPL of MT7629 and preloader of MT7623.
|
||||
|
||||
|
||||
- MediaTek legacy image header. This header was originally used by the legacy image. It
|
||||
basically records the load address, image size and image name.
|
||||
|
||||
After all low level initializations passed, the preloader will locate the LK image and
|
||||
load it into DRAM, and pass control to it.
|
||||
|
||||
Now this header is used by U-Boot of MT7623.
|
||||
|
||||
|
||||
To generate these two headers with mkimage:
|
||||
|
||||
# mkimage -T mtk_image -a <load_addr> -n <option_string> -d <input_file> <image_file>
|
||||
|
||||
- mtk_image means using MediaTek's header generation method.
|
||||
|
||||
|
||||
- load_addr is the load address of this image.
|
||||
For first stage bootloader like U-Boot SPL or preloader, it usually points to the
|
||||
on-chip SRAM.
|
||||
|
||||
For second stage bootloader like U-Boot, it usually points to the DRAM.
|
||||
|
||||
|
||||
- option_string contains options to generate the header.
|
||||
|
||||
The option string is using the follow format:
|
||||
key1=value1;key2=value2;...
|
||||
|
||||
The following key names are valid:
|
||||
lk: If lk=1, LK image header is used. Otherwise BootROM image header is used.
|
||||
|
||||
lkname: The name of the LK image header. The maximum length is 32.
|
||||
The default value is "U-Boot".
|
||||
|
||||
media: Desired boot device. The valid values are:
|
||||
nand : Parallel NAND
|
||||
snand: Serial NAND
|
||||
nor : Serial NOR
|
||||
emmc : eMMC
|
||||
sdmmc: SD
|
||||
|
||||
nandinfo: Desired NAND device type, a combination of page size, oob size and
|
||||
optional device capacity. Valid types are:
|
||||
2k+64 : for Serial NAND, 2KiB page size + 64B oob size
|
||||
2k+120 : for Serial NAND, 2KiB page size + 120B oob size
|
||||
2k+128 : for Serial NAND, 2KiB page size + 128B oob size
|
||||
4k+256 : for Serial NAND, 4KiB page size + 256B oob size
|
||||
1g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 1Gbit size
|
||||
2g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 2Gbit size
|
||||
4g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 4Gbit size
|
||||
2g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 2Gbit size
|
||||
4g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 4Gbit size
|
||||
|
||||
|
||||
MT7629 partitions on Serial NOR
|
||||
===============================
|
||||
|
||||
Start End Size Description
|
||||
00000000 - 0000ffff: 64KiB U-Boot SPL
|
||||
00010000 - 0005ffff: 320KiB U-Boot
|
||||
00060000 - 0006ffff: 64KiB U-Boot env / MediaTek NVRAM
|
||||
00070000 - 000affff: 256KiB RF calibration data
|
||||
000b0000 - xxxxxxxx: all left Firmware image
|
||||
|
||||
|
||||
BPi-R2 (MT7623N) partitions on SD
|
||||
=================================
|
||||
Please note that the last two partitions can vary from different Linux distributions
|
||||
depending on the MBR partition table.
|
||||
|
||||
Start End Size Description
|
||||
00000000 - 000001ff: 512B Device header (with MBR partition table)
|
||||
00000200 - 000007ff: 1536B BRLYT header
|
||||
00000800 - 0004ffff: 318KiB Preloader (with GFH header)
|
||||
00050000 - 000fffff: 704KiB U-Boot
|
||||
00100000 - 063fffff: 99MiB Reserved
|
||||
06400000 - 163fffff: 256MiB Partition 1 (FAT32)
|
||||
16400000 - xxxxxxxx: all left Partition 2 (ext4)
|
||||
|
||||
|
||||
Upgrading notice on Serial NOR
|
||||
==============================
|
||||
Example: MT7629
|
||||
|
||||
The command sf is used to operate the Serial NOR device:
|
||||
|
||||
- To probe current NOR flash:
|
||||
|
||||
# sf probe
|
||||
|
||||
- To erase a region:
|
||||
|
||||
# sf erase <offset> <len>
|
||||
|
||||
- To write data to an offset:
|
||||
|
||||
# sf write <data_addr> <offset> <len>
|
||||
|
||||
- To boot kernel:
|
||||
|
||||
# bootm 0x300b0000
|
||||
|
||||
The memory address range 0x30000000 - 0x3fffffff is mapped to the NOR flash.
|
||||
The DRAM starts at 0x40000000.
|
||||
|
||||
Please note that the output binary u-boot-mtk.bin is a combination of SPL and U-Boot,
|
||||
and it should be write to beginning of the flash.
|
||||
|
||||
Otherwise you should use standalone files:
|
||||
|
||||
spl/u-boot-spl-mtk.bin for SPL,
|
||||
u-boot.img for U-Boot.
|
||||
|
||||
|
||||
Upgrading notice on SD / eMMC
|
||||
=============================
|
||||
Example: MT7623
|
||||
|
||||
Normally only Preloader and U-Boot can be upgraded within U-Boot, and other partitions
|
||||
should be written in PC.
|
||||
|
||||
- To probe current SD card / eMMC:
|
||||
|
||||
# mmc dev 0 for eMMC
|
||||
# mmc dev 1 for SD
|
||||
|
||||
- To erase a region:
|
||||
|
||||
# mmc erase <blk_offset> <blk_num>
|
||||
|
||||
- To write data to a block offset:
|
||||
|
||||
# mmc write <data_addr> <blk_offset> <blk_num>
|
||||
|
||||
- To load kernel image from partition 1:
|
||||
|
||||
# fatload mmc 0:1 <load_address> <path_to_kernel_uImage> for eMMC
|
||||
# fatload mmc 1:1 <load_address> <path_to_kernel_uImage> for SD
|
||||
|
||||
- To boot kernel:
|
||||
|
||||
# bootm <load_address>
|
||||
|
||||
The DRAM starts at 0x80000000.
|
||||
|
||||
Please note that we use block offset and block count for SD card, not the byte offset.
|
||||
The block size is always 512 bytes for SD card.
|
||||
|
||||
|
||||
Documentation
|
||||
=============
|
||||
http://wiki.banana-pi.org/Banana_Pi_BPI-R2
|
@ -10,6 +10,7 @@ obj-y += imx/
|
||||
obj-y += tegra/
|
||||
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
|
||||
obj-$(CONFIG_ARCH_MESON) += clk_meson.o
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += altera/
|
||||
obj-$(CONFIG_CLK_AT91) += at91/
|
||||
|
7
drivers/clk/mediatek/Makefile
Normal file
7
drivers/clk/mediatek/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Core
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += clk-mtk.o
|
||||
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
|
||||
obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
|
870
drivers/clk/mediatek/clk-mt7623.c
Normal file
870
drivers/clk/mediatek/clk-mt7623.c
Normal file
@ -0,0 +1,870 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek clock driver for MT7623 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
#include <dt-bindings/clock/mt7623-clk.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#define MT7623_CLKSQ_STB_CON0 0x18
|
||||
#define MT7623_PLL_ISO_CON0 0x24
|
||||
#define MT7623_PLL_FMAX (2000UL * MHZ)
|
||||
#define MT7623_CON0_RST_BAR BIT(27)
|
||||
|
||||
#define MCU_AXI_DIV 0x60
|
||||
#define AXI_DIV_MSK GENMASK(4, 0)
|
||||
#define AXI_DIV_SEL(x) (x)
|
||||
|
||||
/* apmixedsys */
|
||||
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
|
||||
_pd_shift, _pcw_reg, _pcw_shift) { \
|
||||
.id = _id, \
|
||||
.reg = _reg, \
|
||||
.pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, \
|
||||
.rst_bar_mask = MT7623_CON0_RST_BAR, \
|
||||
.fmax = MT7623_PLL_FMAX, \
|
||||
.flags = _flags, \
|
||||
.pcwbits = _pcwbits, \
|
||||
.pd_reg = _pd_reg, \
|
||||
.pd_shift = _pd_shift, \
|
||||
.pcw_reg = _pcw_reg, \
|
||||
.pcw_shift = _pcw_shift, \
|
||||
}
|
||||
|
||||
static const struct mtk_pll_data apmixed_plls[] = {
|
||||
PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x80000001, 0,
|
||||
21, 0x204, 24, 0x204, 0),
|
||||
PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0xf0000001, HAVE_RST_BAR,
|
||||
21, 0x210, 4, 0x214, 0),
|
||||
PLL(CLK_APMIXED_UNIVPLL, 0x220, 0x22c, 0xf3000001, HAVE_RST_BAR,
|
||||
7, 0x220, 4, 0x224, 14),
|
||||
PLL(CLK_APMIXED_MMPLL, 0x230, 0x23c, 0x00000001, 0,
|
||||
21, 0x230, 4, 0x234, 0),
|
||||
PLL(CLK_APMIXED_MSDCPLL, 0x240, 0x24c, 0x00000001, 0,
|
||||
21, 0x240, 4, 0x244, 0),
|
||||
PLL(CLK_APMIXED_TVDPLL, 0x250, 0x25c, 0x00000001, 0,
|
||||
21, 0x250, 4, 0x254, 0),
|
||||
PLL(CLK_APMIXED_AUD1PLL, 0x270, 0x27c, 0x00000001, 0,
|
||||
31, 0x270, 4, 0x274, 0),
|
||||
PLL(CLK_APMIXED_TRGPLL, 0x280, 0x28c, 0x00000001, 0,
|
||||
31, 0x280, 4, 0x284, 0),
|
||||
PLL(CLK_APMIXED_ETHPLL, 0x290, 0x29c, 0x00000001, 0,
|
||||
31, 0x290, 4, 0x294, 0),
|
||||
PLL(CLK_APMIXED_VDECPLL, 0x2a0, 0x2ac, 0x00000001, 0,
|
||||
31, 0x2a0, 4, 0x2a4, 0),
|
||||
PLL(CLK_APMIXED_HADDS2PLL, 0x2b0, 0x2bc, 0x00000001, 0,
|
||||
31, 0x2b0, 4, 0x2b4, 0),
|
||||
PLL(CLK_APMIXED_AUD2PLL, 0x2c0, 0x2cc, 0x00000001, 0,
|
||||
31, 0x2c0, 4, 0x2c4, 0),
|
||||
PLL(CLK_APMIXED_TVD2PLL, 0x2d0, 0x2dc, 0x00000001, 0,
|
||||
21, 0x2d0, 4, 0x2d4, 0),
|
||||
};
|
||||
|
||||
/* topckgen */
|
||||
#define FACTOR0(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
|
||||
|
||||
#define FACTOR1(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
|
||||
|
||||
#define FACTOR2(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, 0)
|
||||
|
||||
static const struct mtk_fixed_clk top_fixed_clks[] = {
|
||||
FIXED_CLK(CLK_TOP_DPI, CLK_XTAL, 108 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_DMPLL, CLK_XTAL, 400 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_VENCPLL, CLK_XTAL, 295.75 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, CLK_XTAL, 340 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, CLK_XTAL, 340 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, CLK_XTAL, 340 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_HADDS2_FB, CLK_XTAL, 27 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_WBG_DIG_416M, CLK_XTAL, 416 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, CLK_XTAL, 143 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_HDMI_SCL_RX, CLK_XTAL, 27 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_32K_EXTERNAL, CLK_XTAL, 32000),
|
||||
FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, CLK_XTAL, 300 * MHZ),
|
||||
FIXED_CLK(CLK_TOP_AUD_EXT1, CLK_XTAL, 0),
|
||||
FIXED_CLK(CLK_TOP_AUD_EXT2, CLK_XTAL, 0),
|
||||
FIXED_CLK(CLK_TOP_NFI1X_PAD, CLK_XTAL, 0),
|
||||
};
|
||||
|
||||
static const struct mtk_fixed_factor top_fixed_divs[] = {
|
||||
FACTOR0(CLK_TOP_SYSPLL, CLK_APMIXED_MAINPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D3, CLK_APMIXED_MAINPLL, 1, 3),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
|
||||
FACTOR1(CLK_TOP_SYSPLL1_D2, CLK_TOP_SYSPLL_D2, 1, 2),
|
||||
FACTOR1(CLK_TOP_SYSPLL1_D4, CLK_TOP_SYSPLL_D2, 1, 4),
|
||||
FACTOR1(CLK_TOP_SYSPLL1_D8, CLK_TOP_SYSPLL_D2, 1, 8),
|
||||
FACTOR1(CLK_TOP_SYSPLL1_D16, CLK_TOP_SYSPLL_D2, 1, 16),
|
||||
FACTOR1(CLK_TOP_SYSPLL2_D2, CLK_TOP_SYSPLL_D3, 1, 2),
|
||||
FACTOR1(CLK_TOP_SYSPLL2_D4, CLK_TOP_SYSPLL_D3, 1, 4),
|
||||
FACTOR1(CLK_TOP_SYSPLL2_D8, CLK_TOP_SYSPLL_D3, 1, 8),
|
||||
FACTOR1(CLK_TOP_SYSPLL3_D2, CLK_TOP_SYSPLL_D5, 1, 2),
|
||||
FACTOR1(CLK_TOP_SYSPLL3_D4, CLK_TOP_SYSPLL_D5, 1, 4),
|
||||
FACTOR1(CLK_TOP_SYSPLL4_D2, CLK_TOP_SYSPLL_D7, 1, 2),
|
||||
FACTOR1(CLK_TOP_SYSPLL4_D4, CLK_TOP_SYSPLL_D7, 1, 4),
|
||||
|
||||
FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIVPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D2, CLK_APMIXED_UNIVPLL, 1, 2),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D3, CLK_APMIXED_UNIVPLL, 1, 3),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D5, CLK_APMIXED_UNIVPLL, 1, 5),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D7, CLK_APMIXED_UNIVPLL, 1, 7),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D26, CLK_APMIXED_UNIVPLL, 1, 26),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D52, CLK_APMIXED_UNIVPLL, 1, 52),
|
||||
FACTOR0(CLK_TOP_UNIVPLL_D108, CLK_APMIXED_UNIVPLL, 1, 108),
|
||||
FACTOR0(CLK_TOP_USB_PHY48M, CLK_APMIXED_UNIVPLL, 1, 26),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL_D2, 1, 2),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL_D2, 1, 4),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL_D2, 1, 8),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL_D3, 1, 2),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL_D3, 1, 4),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL_D3, 1, 8),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL_D3, 1, 16),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D32, CLK_TOP_UNIVPLL_D3, 1, 32),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL_D5, 1, 2),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL_D5, 1, 4),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D8, CLK_TOP_UNIVPLL_D5, 1, 8),
|
||||
|
||||
FACTOR0(CLK_TOP_MSDCPLL, CLK_APMIXED_MSDCPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_MSDCPLL_D2, CLK_APMIXED_MSDCPLL, 1, 2),
|
||||
FACTOR0(CLK_TOP_MSDCPLL_D4, CLK_APMIXED_MSDCPLL, 1, 4),
|
||||
FACTOR0(CLK_TOP_MSDCPLL_D8, CLK_APMIXED_MSDCPLL, 1, 8),
|
||||
|
||||
FACTOR0(CLK_TOP_MMPLL, CLK_APMIXED_MMPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_MMPLL_D2, CLK_APMIXED_MMPLL, 1, 2),
|
||||
|
||||
FACTOR1(CLK_TOP_DMPLL_D2, CLK_TOP_DMPLL, 1, 2),
|
||||
FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_DMPLL, 1, 4),
|
||||
FACTOR1(CLK_TOP_DMPLL_X2, CLK_TOP_DMPLL, 1, 1),
|
||||
|
||||
FACTOR0(CLK_TOP_TVDPLL, CLK_APMIXED_TVDPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_TVDPLL_D2, CLK_APMIXED_TVDPLL, 1, 2),
|
||||
FACTOR0(CLK_TOP_TVDPLL_D4, CLK_APMIXED_TVDPLL, 1, 4),
|
||||
|
||||
FACTOR0(CLK_TOP_VDECPLL, CLK_APMIXED_VDECPLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_TVD2PLL, CLK_APMIXED_TVD2PLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_TVD2PLL_D2, CLK_APMIXED_TVD2PLL, 1, 2),
|
||||
|
||||
FACTOR1(CLK_TOP_MIPIPLL, CLK_TOP_DPI, 1, 1),
|
||||
FACTOR1(CLK_TOP_MIPIPLL_D2, CLK_TOP_DPI, 1, 2),
|
||||
FACTOR1(CLK_TOP_MIPIPLL_D4, CLK_TOP_DPI, 1, 4),
|
||||
|
||||
FACTOR1(CLK_TOP_HDMIPLL, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 1),
|
||||
FACTOR1(CLK_TOP_HDMIPLL_D2, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 2),
|
||||
FACTOR1(CLK_TOP_HDMIPLL_D3, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 3),
|
||||
|
||||
FACTOR0(CLK_TOP_ARMPLL_1P3G, CLK_APMIXED_ARMPLL, 1, 1),
|
||||
|
||||
FACTOR1(CLK_TOP_AUDPLL, CLK_TOP_AUDPLL_MUX_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_AUDPLL_D4, CLK_TOP_AUDPLL_MUX_SEL, 1, 4),
|
||||
FACTOR1(CLK_TOP_AUDPLL_D8, CLK_TOP_AUDPLL_MUX_SEL, 1, 8),
|
||||
FACTOR1(CLK_TOP_AUDPLL_D16, CLK_TOP_AUDPLL_MUX_SEL, 1, 16),
|
||||
FACTOR1(CLK_TOP_AUDPLL_D24, CLK_TOP_AUDPLL_MUX_SEL, 1, 24),
|
||||
|
||||
FACTOR0(CLK_TOP_AUD1PLL_98M, CLK_APMIXED_AUD1PLL, 1, 3),
|
||||
FACTOR0(CLK_TOP_AUD2PLL_90M, CLK_APMIXED_AUD2PLL, 1, 3),
|
||||
FACTOR0(CLK_TOP_HADDS2PLL_98M, CLK_APMIXED_HADDS2PLL, 1, 3),
|
||||
FACTOR0(CLK_TOP_HADDS2PLL_294M, CLK_APMIXED_HADDS2PLL, 1, 1),
|
||||
FACTOR0(CLK_TOP_ETHPLL_500M, CLK_APMIXED_ETHPLL, 1, 1),
|
||||
FACTOR2(CLK_TOP_CLK26M_D8, CLK_XTAL, 1, 8),
|
||||
FACTOR2(CLK_TOP_32K_INTERNAL, CLK_XTAL, 1, 793),
|
||||
FACTOR1(CLK_TOP_AXISEL_D4, CLK_TOP_AXI_SEL, 1, 4),
|
||||
FACTOR1(CLK_TOP_8BDAC, CLK_TOP_UNIVPLL_D2, 1, 1),
|
||||
};
|
||||
|
||||
static const int axi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_MMPLL_D2,
|
||||
CLK_TOP_DMPLL_D2
|
||||
};
|
||||
|
||||
static const int mem_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int ddrphycfg_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8
|
||||
};
|
||||
|
||||
static const int mm_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_VENCPLL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int pwm_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL3_D2,
|
||||
CLK_TOP_UNIVPLL1_D4
|
||||
};
|
||||
|
||||
static const int vdec_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_VDECPLL,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_VENCPLL,
|
||||
CLK_TOP_MSDCPLL_D2,
|
||||
CLK_TOP_MMPLL_D2
|
||||
};
|
||||
|
||||
static const int mfg_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_MMPLL,
|
||||
CLK_TOP_DMPLL_X2,
|
||||
CLK_TOP_MSDCPLL,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL_D3,
|
||||
CLK_TOP_UNIVPLL_D3,
|
||||
CLK_TOP_UNIVPLL1_D2
|
||||
};
|
||||
|
||||
static const int camtg_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL_D26,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_MSDCPLL_D2,
|
||||
CLK_TOP_MMPLL_D2
|
||||
};
|
||||
|
||||
static const int uart_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D8
|
||||
};
|
||||
|
||||
static const int spi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL1_D8
|
||||
};
|
||||
|
||||
static const int usb20_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL1_D8,
|
||||
CLK_TOP_UNIVPLL3_D4
|
||||
};
|
||||
|
||||
static const int msdc30_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_MSDCPLL_D2,
|
||||
CLK_TOP_SYSPLL2_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL1_D4,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
};
|
||||
|
||||
static const int aud_intbus_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_UNIVPLL3_D2,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int pmicspi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_SYSPLL2_D8,
|
||||
CLK_TOP_SYSPLL1_D16,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_UNIVPLL_D26,
|
||||
CLK_TOP_DMPLL_D2,
|
||||
CLK_TOP_DMPLL_D4
|
||||
};
|
||||
|
||||
static const int scp_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_DMPLL_D2,
|
||||
CLK_TOP_DMPLL_D4
|
||||
};
|
||||
|
||||
static const int dpi0_tve_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_MIPIPLL,
|
||||
CLK_TOP_MIPIPLL_D2,
|
||||
CLK_TOP_MIPIPLL_D4,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_TVDPLL,
|
||||
CLK_TOP_TVDPLL_D2,
|
||||
CLK_TOP_TVDPLL_D4
|
||||
};
|
||||
|
||||
static const int dpi1_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_TVDPLL,
|
||||
CLK_TOP_TVDPLL_D2,
|
||||
CLK_TOP_TVDPLL_D4
|
||||
};
|
||||
|
||||
static const int hdmi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_HDMIPLL,
|
||||
CLK_TOP_HDMIPLL_D2,
|
||||
CLK_TOP_HDMIPLL_D3
|
||||
};
|
||||
|
||||
static const int apll_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_AUDPLL,
|
||||
CLK_TOP_AUDPLL_D4,
|
||||
CLK_TOP_AUDPLL_D8,
|
||||
CLK_TOP_AUDPLL_D16,
|
||||
CLK_TOP_AUDPLL_D24,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int rtc_parents[] = {
|
||||
CLK_TOP_32K_INTERNAL,
|
||||
CLK_TOP_32K_EXTERNAL,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL3_D8
|
||||
};
|
||||
|
||||
static const int nfi2x_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL2_D2,
|
||||
CLK_TOP_SYSPLL_D7,
|
||||
CLK_TOP_UNIVPLL3_D2,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_SYSPLL4_D4,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int emmc_hclk_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_SYSPLL2_D2
|
||||
};
|
||||
|
||||
static const int flash_parents[] = {
|
||||
CLK_TOP_CLK26M_D8,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL2_D8,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int di_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_TVD2PLL,
|
||||
CLK_TOP_TVD2PLL_D2,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int nr_osd_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_VENCPLL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int hdmirx_bist_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL_D3,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D16,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_VENCPLL,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int intdir_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_MMPLL,
|
||||
CLK_TOP_SYSPLL_D2,
|
||||
CLK_TOP_UNIVPLL_D2
|
||||
};
|
||||
|
||||
static const int asm_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_SYSPLL_D5
|
||||
};
|
||||
|
||||
static const int ms_card_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL3_D8,
|
||||
CLK_TOP_SYSPLL4_D4
|
||||
};
|
||||
|
||||
static const int ethif_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_DMPLL,
|
||||
CLK_TOP_DMPLL_D2
|
||||
};
|
||||
|
||||
static const int hdmirx_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL_D52
|
||||
};
|
||||
|
||||
static const int cmsys_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_SYSPLL2_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int clk_8bdac_parents[] = {
|
||||
CLK_TOP_32K_INTERNAL,
|
||||
CLK_TOP_8BDAC,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int aud2dvd_parents[] = {
|
||||
CLK_TOP_AUD_48K_TIMING,
|
||||
CLK_TOP_AUD_44K_TIMING
|
||||
};
|
||||
|
||||
static const int padmclk_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL_D26,
|
||||
CLK_TOP_UNIVPLL_D52,
|
||||
CLK_TOP_UNIVPLL_D108,
|
||||
CLK_TOP_UNIVPLL2_D8,
|
||||
CLK_TOP_UNIVPLL2_D16,
|
||||
CLK_TOP_UNIVPLL2_D32
|
||||
};
|
||||
|
||||
static const int aud_mux_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_AUD1PLL_98M,
|
||||
CLK_TOP_AUD2PLL_90M,
|
||||
CLK_TOP_HADDS2PLL_98M,
|
||||
CLK_TOP_AUD_EXTCK1_DIV,
|
||||
CLK_TOP_AUD_EXTCK2_DIV
|
||||
};
|
||||
|
||||
static const int aud_src_parents[] = {
|
||||
CLK_TOP_AUD_MUX1_SEL,
|
||||
CLK_TOP_AUD_MUX2_SEL
|
||||
};
|
||||
|
||||
static const struct mtk_composite top_muxes[] = {
|
||||
MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
|
||||
MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
|
||||
MUX_GATE_FLAGS(CLK_TOP_MM_SEL, mm_parents, 0x40, 24, 3, 31,
|
||||
CLK_DOMAIN_SCPSYS),
|
||||
|
||||
MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_VDEC_SEL, vdec_parents, 0x50, 8, 4, 15),
|
||||
MUX_GATE_FLAGS(CLK_TOP_MFG_SEL, mfg_parents, 0x50, 16, 3, 23,
|
||||
CLK_DOMAIN_SCPSYS),
|
||||
MUX_GATE(CLK_TOP_CAMTG_SEL, camtg_parents, 0x50, 24, 3, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
|
||||
MUX_GATE(CLK_TOP_SPI0_SEL, spi_parents, 0x60, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_USB20_SEL, usb20_parents, 0x60, 16, 2, 23),
|
||||
MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_parents, 0x60, 24, 3, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_parents, 0x70, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_MSDC30_2_SEL, msdc30_parents, 0x70, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_AUDIO_SEL, msdc30_parents, 0x70, 16, 1, 23),
|
||||
MUX_GATE(CLK_TOP_AUDINTBUS_SEL, aud_intbus_parents, 0x70, 24, 3, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 0, 4, 7),
|
||||
MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_DPI0_SEL, dpi0_tve_parents, 0x80, 16, 3, 23),
|
||||
MUX_GATE(CLK_TOP_DPI1_SEL, dpi1_parents, 0x80, 24, 2, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_TVE_SEL, dpi0_tve_parents, 0x90, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_HDMI_SEL, hdmi_parents, 0x90, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_APLL_SEL, apll_parents, 0x90, 16, 3, 23),
|
||||
|
||||
MUX_GATE(CLK_TOP_RTC_SEL, rtc_parents, 0xA0, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_NFI2X_SEL, nfi2x_parents, 0xA0, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, emmc_hclk_parents, 0xA0, 24, 2, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0xB0, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_DI_SEL, di_parents, 0xB0, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_NR_SEL, nr_osd_parents, 0xB0, 16, 3, 23),
|
||||
MUX_GATE(CLK_TOP_OSD_SEL, nr_osd_parents, 0xB0, 24, 3, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, hdmirx_bist_parents, 0xC0, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_INTDIR_SEL, intdir_parents, 0xC0, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_ASM_I_SEL, asm_parents, 0xC0, 16, 2, 23),
|
||||
MUX_GATE(CLK_TOP_ASM_M_SEL, asm_parents, 0xC0, 24, 3, 31),
|
||||
|
||||
MUX_GATE(CLK_TOP_ASM_H_SEL, asm_parents, 0xD0, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_MS_CARD_SEL, ms_card_parents, 0xD0, 16, 2, 23),
|
||||
MUX_GATE_FLAGS(CLK_TOP_ETHIF_SEL, ethif_parents, 0xD0, 24, 3, 31,
|
||||
CLK_DOMAIN_SCPSYS),
|
||||
|
||||
MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, hdmirx_parents, 0xE0, 0, 1, 7),
|
||||
MUX_GATE(CLK_TOP_MSDC30_3_SEL, msdc30_parents, 0xE0, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_CMSYS_SEL, cmsys_parents, 0xE0, 16, 4, 23),
|
||||
|
||||
MUX_GATE(CLK_TOP_SPI1_SEL, spi_parents, 0xE0, 24, 3, 31),
|
||||
MUX_GATE(CLK_TOP_SPI2_SEL, spi_parents, 0xF0, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_8BDAC_SEL, clk_8bdac_parents, 0xF0, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_AUD2DVD_SEL, aud2dvd_parents, 0xF0, 16, 1, 23),
|
||||
|
||||
MUX(CLK_TOP_PADMCLK_SEL, padmclk_parents, 0x100, 0, 3),
|
||||
|
||||
MUX(CLK_TOP_AUD_MUX1_SEL, aud_mux_parents, 0x12c, 0, 3),
|
||||
MUX(CLK_TOP_AUD_MUX2_SEL, aud_mux_parents, 0x12c, 3, 3),
|
||||
MUX(CLK_TOP_AUDPLL_MUX_SEL, aud_mux_parents, 0x12c, 6, 3),
|
||||
|
||||
MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, aud_src_parents, 0x12c, 15, 1, 23),
|
||||
MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, aud_src_parents, 0x12c, 16, 1, 24),
|
||||
MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, aud_src_parents, 0x12c, 17, 1, 25),
|
||||
MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, aud_src_parents, 0x12c, 18, 1, 26),
|
||||
MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, aud_src_parents, 0x12c, 19, 1, 27),
|
||||
MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, aud_src_parents, 0x12c, 20, 1, 28),
|
||||
};
|
||||
|
||||
/* infracfg */
|
||||
static const struct mtk_gate_regs infra_cg_regs = {
|
||||
.set_ofs = 0x40,
|
||||
.clr_ofs = 0x44,
|
||||
.sta_ofs = 0x48,
|
||||
};
|
||||
|
||||
#define GATE_INFRA(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &infra_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate infra_cgs[] = {
|
||||
GATE_INFRA(CLK_INFRA_DBG, CLK_TOP_AXI_SEL, 0),
|
||||
GATE_INFRA(CLK_INFRA_SMI, CLK_TOP_MM_SEL, 1),
|
||||
GATE_INFRA(CLK_INFRA_QAXI_CM4, CLK_TOP_AXI_SEL, 2),
|
||||
GATE_INFRA(CLK_INFRA_AUD_SPLIN_B, CLK_TOP_HADDS2PLL_294M, 4),
|
||||
GATE_INFRA(CLK_INFRA_AUDIO, CLK_XTAL, 5),
|
||||
GATE_INFRA(CLK_INFRA_EFUSE, CLK_XTAL, 6),
|
||||
GATE_INFRA(CLK_INFRA_L2C_SRAM, CLK_TOP_MM_SEL, 7),
|
||||
GATE_INFRA(CLK_INFRA_M4U, CLK_TOP_MEM_SEL, 8),
|
||||
GATE_INFRA(CLK_INFRA_CONNMCU, CLK_TOP_WBG_DIG_416M, 12),
|
||||
GATE_INFRA(CLK_INFRA_TRNG, CLK_TOP_AXI_SEL, 13),
|
||||
GATE_INFRA(CLK_INFRA_RAMBUFIF, CLK_TOP_MEM_SEL, 14),
|
||||
GATE_INFRA(CLK_INFRA_CPUM, CLK_TOP_MEM_SEL, 15),
|
||||
GATE_INFRA(CLK_INFRA_KP, CLK_TOP_AXI_SEL, 16),
|
||||
GATE_INFRA(CLK_INFRA_CEC, CLK_TOP_RTC_SEL, 18),
|
||||
GATE_INFRA(CLK_INFRA_IRRX, CLK_TOP_AXI_SEL, 19),
|
||||
GATE_INFRA(CLK_INFRA_PMICSPI, CLK_TOP_PMICSPI_SEL, 22),
|
||||
GATE_INFRA(CLK_INFRA_PMICWRAP, CLK_TOP_AXI_SEL, 23),
|
||||
GATE_INFRA(CLK_INFRA_DDCCI, CLK_TOP_AXI_SEL, 24),
|
||||
};
|
||||
|
||||
/* pericfg */
|
||||
static const struct mtk_gate_regs peri0_cg_regs = {
|
||||
.set_ofs = 0x8,
|
||||
.clr_ofs = 0x10,
|
||||
.sta_ofs = 0x18,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs peri1_cg_regs = {
|
||||
.set_ofs = 0xC,
|
||||
.clr_ofs = 0x14,
|
||||
.sta_ofs = 0x1C,
|
||||
};
|
||||
|
||||
#define GATE_PERI0(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &peri0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
#define GATE_PERI1(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &peri1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate peri_cgs[] = {
|
||||
GATE_PERI0(CLK_PERI_NFI, CLK_TOP_NFI2X_SEL, 0),
|
||||
GATE_PERI0(CLK_PERI_THERM, CLK_TOP_AXI_SEL, 1),
|
||||
GATE_PERI0(CLK_PERI_PWM1, CLK_TOP_AXISEL_D4, 2),
|
||||
GATE_PERI0(CLK_PERI_PWM2, CLK_TOP_AXISEL_D4, 3),
|
||||
GATE_PERI0(CLK_PERI_PWM3, CLK_TOP_AXISEL_D4, 4),
|
||||
GATE_PERI0(CLK_PERI_PWM4, CLK_TOP_AXISEL_D4, 5),
|
||||
GATE_PERI0(CLK_PERI_PWM5, CLK_TOP_AXISEL_D4, 6),
|
||||
GATE_PERI0(CLK_PERI_PWM6, CLK_TOP_AXISEL_D4, 7),
|
||||
GATE_PERI0(CLK_PERI_PWM7, CLK_TOP_AXISEL_D4, 8),
|
||||
GATE_PERI0(CLK_PERI_PWM, CLK_TOP_AXI_SEL, 9),
|
||||
GATE_PERI0(CLK_PERI_USB0, CLK_TOP_USB20_SEL, 10),
|
||||
GATE_PERI0(CLK_PERI_USB1, CLK_TOP_USB20_SEL, 11),
|
||||
GATE_PERI0(CLK_PERI_AP_DMA, CLK_TOP_AXI_SEL, 12),
|
||||
GATE_PERI0(CLK_PERI_MSDC30_0, CLK_TOP_MSDC30_0_SEL, 13),
|
||||
GATE_PERI0(CLK_PERI_MSDC30_1, CLK_TOP_MSDC30_1_SEL, 14),
|
||||
GATE_PERI0(CLK_PERI_MSDC30_2, CLK_TOP_MSDC30_2_SEL, 15),
|
||||
GATE_PERI0(CLK_PERI_MSDC30_3, CLK_TOP_MSDC30_3_SEL, 16),
|
||||
GATE_PERI0(CLK_PERI_MSDC50_3, CLK_TOP_EMMC_HCLK_SEL, 17),
|
||||
GATE_PERI0(CLK_PERI_NLI, CLK_TOP_AXI_SEL, 18),
|
||||
GATE_PERI0(CLK_PERI_UART0, CLK_TOP_AXI_SEL, 19),
|
||||
GATE_PERI0(CLK_PERI_UART1, CLK_TOP_AXI_SEL, 20),
|
||||
GATE_PERI0(CLK_PERI_UART2, CLK_TOP_AXI_SEL, 21),
|
||||
GATE_PERI0(CLK_PERI_UART3, CLK_TOP_AXI_SEL, 22),
|
||||
GATE_PERI0(CLK_PERI_BTIF, CLK_TOP_AXI_SEL, 23),
|
||||
GATE_PERI0(CLK_PERI_I2C0, CLK_TOP_AXI_SEL, 24),
|
||||
GATE_PERI0(CLK_PERI_I2C1, CLK_TOP_AXI_SEL, 25),
|
||||
GATE_PERI0(CLK_PERI_I2C2, CLK_TOP_AXI_SEL, 26),
|
||||
GATE_PERI0(CLK_PERI_I2C3, CLK_XTAL, 27),
|
||||
GATE_PERI0(CLK_PERI_AUXADC, CLK_XTAL, 28),
|
||||
GATE_PERI0(CLK_PERI_SPI0, CLK_TOP_SPI0_SEL, 29),
|
||||
GATE_PERI0(CLK_PERI_ETH, CLK_XTAL, 30),
|
||||
GATE_PERI0(CLK_PERI_USB0_MCU, CLK_TOP_AXI_SEL, 31),
|
||||
|
||||
GATE_PERI1(CLK_PERI_USB1_MCU, CLK_TOP_AXI_SEL, 0),
|
||||
GATE_PERI1(CLK_PERI_USB_SLV, CLK_TOP_AXI_SEL, 1),
|
||||
GATE_PERI1(CLK_PERI_GCPU, CLK_TOP_AXI_SEL, 2),
|
||||
GATE_PERI1(CLK_PERI_NFI_ECC, CLK_TOP_NFI1X_PAD, 3),
|
||||
GATE_PERI1(CLK_PERI_NFI_PAD, CLK_TOP_NFI1X_PAD, 4),
|
||||
GATE_PERI1(CLK_PERI_FLASH, CLK_TOP_NFI2X_SEL, 5),
|
||||
GATE_PERI1(CLK_PERI_HOST89_INT, CLK_TOP_AXI_SEL, 6),
|
||||
GATE_PERI1(CLK_PERI_HOST89_SPI, CLK_TOP_SPI0_SEL, 7),
|
||||
GATE_PERI1(CLK_PERI_HOST89_DVD, CLK_TOP_AUD2DVD_SEL, 8),
|
||||
GATE_PERI1(CLK_PERI_SPI1, CLK_TOP_SPI1_SEL, 9),
|
||||
GATE_PERI1(CLK_PERI_SPI2, CLK_TOP_SPI2_SEL, 10),
|
||||
GATE_PERI1(CLK_PERI_FCI, CLK_TOP_MS_CARD_SEL, 11),
|
||||
};
|
||||
|
||||
/* ethsys */
|
||||
static const struct mtk_gate_regs eth_cg_regs = {
|
||||
.sta_ofs = 0x30,
|
||||
};
|
||||
|
||||
#define GATE_ETH(_id, _parent, _shift, _flag) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = ð_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_NO_SETCLR_INV | (_flag), \
|
||||
}
|
||||
|
||||
#define GATE_ETH0(_id, _parent, _shift) \
|
||||
GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
|
||||
|
||||
#define GATE_ETH1(_id, _parent, _shift) \
|
||||
GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
|
||||
|
||||
static const struct mtk_gate eth_cgs[] = {
|
||||
GATE_ETH1(CLK_ETHSYS_HSDMA, CLK_TOP_ETHIF_SEL, 5),
|
||||
GATE_ETH1(CLK_ETHSYS_ESW, CLK_TOP_ETHPLL_500M, 6),
|
||||
GATE_ETH0(CLK_ETHSYS_GP2, CLK_APMIXED_TRGPLL, 7),
|
||||
GATE_ETH1(CLK_ETHSYS_GP1, CLK_TOP_ETHPLL_500M, 8),
|
||||
GATE_ETH1(CLK_ETHSYS_PCM, CLK_TOP_ETHIF_SEL, 11),
|
||||
GATE_ETH1(CLK_ETHSYS_GDMA, CLK_TOP_ETHIF_SEL, 14),
|
||||
GATE_ETH1(CLK_ETHSYS_I2S, CLK_TOP_ETHIF_SEL, 17),
|
||||
GATE_ETH1(CLK_ETHSYS_CRYPTO, CLK_TOP_ETHIF_SEL, 29),
|
||||
};
|
||||
|
||||
static const struct mtk_clk_tree mt7623_clk_tree = {
|
||||
.xtal_rate = 26 * MHZ,
|
||||
.xtal2_rate = 26 * MHZ,
|
||||
.fdivs_offs = CLK_TOP_SYSPLL,
|
||||
.muxes_offs = CLK_TOP_AXI_SEL,
|
||||
.plls = apmixed_plls,
|
||||
.fclks = top_fixed_clks,
|
||||
.fdivs = top_fixed_divs,
|
||||
.muxes = top_muxes,
|
||||
};
|
||||
|
||||
static int mt7623_mcucfg_probe(struct udevice *dev)
|
||||
{
|
||||
void __iomem *base;
|
||||
|
||||
base = dev_read_addr_ptr(dev);
|
||||
if (!base)
|
||||
return -ENOENT;
|
||||
|
||||
clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
|
||||
AXI_DIV_SEL(0x12));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7623_apmixedsys_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = mtk_common_clk_init(dev, &mt7623_clk_tree);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* reduce clock square disable time */
|
||||
writel(0x50001, priv->base + MT7623_CLKSQ_STB_CON0);
|
||||
/* extend control timing to 1us */
|
||||
writel(0x888, priv->base + MT7623_PLL_ISO_CON0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7623_topckgen_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_init(dev, &mt7623_clk_tree);
|
||||
}
|
||||
|
||||
static int mt7623_infracfg_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, infra_cgs);
|
||||
}
|
||||
|
||||
static int mt7623_pericfg_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, peri_cgs);
|
||||
}
|
||||
|
||||
static int mt7623_ethsys_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs);
|
||||
}
|
||||
|
||||
static const struct udevice_id mt7623_apmixed_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-apmixedsys" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7623_topckgen_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-topckgen" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7623_infracfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-infracfg", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7623_pericfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-pericfg", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7623_ethsys_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-ethsys" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7623_mcucfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7623-mcucfg" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_mcucfg) = {
|
||||
.name = "mt7623-mcucfg",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = mt7623_mcucfg_compat,
|
||||
.probe = mt7623_mcucfg_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
|
||||
.name = "mt7623-clock-apmixedsys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7623_apmixed_compat,
|
||||
.probe = mt7623_apmixedsys_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
|
||||
.ops = &mtk_clk_apmixedsys_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_topckgen) = {
|
||||
.name = "mt7623-clock-topckgen",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7623_topckgen_compat,
|
||||
.probe = mt7623_topckgen_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
|
||||
.ops = &mtk_clk_topckgen_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_infracfg) = {
|
||||
.name = "mt7623-infracfg",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7623_infracfg_compat,
|
||||
.probe = mt7623_infracfg_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_pericfg) = {
|
||||
.name = "mt7623-pericfg",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7623_pericfg_compat,
|
||||
.probe = mt7623_pericfg_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_ethsys) = {
|
||||
.name = "mt7623-clock-ethsys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7623_ethsys_compat,
|
||||
.probe = mt7623_ethsys_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
};
|
709
drivers/clk/mediatek/clk-mt7629.c
Normal file
709
drivers/clk/mediatek/clk-mt7629.c
Normal file
@ -0,0 +1,709 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek clock driver for MT7629 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
#include <dt-bindings/clock/mt7629-clk.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#define MT7629_CLKSQ_STB_CON0 0x20
|
||||
#define MT7629_PLL_ISO_CON0 0x2c
|
||||
#define MT7629_PLL_FMAX (2500UL * MHZ)
|
||||
#define MT7629_CON0_RST_BAR BIT(24)
|
||||
|
||||
#define MCU_AXI_DIV 0x640
|
||||
#define AXI_DIV_MSK GENMASK(4, 0)
|
||||
#define AXI_DIV_SEL(x) (x)
|
||||
|
||||
#define MCU_BUS_MUX 0x7c0
|
||||
#define MCU_BUS_MSK GENMASK(10, 9)
|
||||
#define MCU_BUS_SEL(x) ((x) << 9)
|
||||
|
||||
/* apmixedsys */
|
||||
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
|
||||
_pd_shift, _pcw_reg, _pcw_shift) { \
|
||||
.id = _id, \
|
||||
.reg = _reg, \
|
||||
.pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, \
|
||||
.rst_bar_mask = MT7629_CON0_RST_BAR, \
|
||||
.fmax = MT7629_PLL_FMAX, \
|
||||
.flags = _flags, \
|
||||
.pcwbits = _pcwbits, \
|
||||
.pd_reg = _pd_reg, \
|
||||
.pd_shift = _pd_shift, \
|
||||
.pcw_reg = _pcw_reg, \
|
||||
.pcw_shift = _pcw_shift, \
|
||||
}
|
||||
|
||||
static const struct mtk_pll_data apmixed_plls[] = {
|
||||
PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x1, 0,
|
||||
21, 0x204, 24, 0x204, 0),
|
||||
PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0x1, HAVE_RST_BAR,
|
||||
21, 0x214, 24, 0x214, 0),
|
||||
PLL(CLK_APMIXED_UNIV2PLL, 0x220, 0x22c, 0x1, HAVE_RST_BAR,
|
||||
7, 0x224, 24, 0x224, 14),
|
||||
PLL(CLK_APMIXED_ETH1PLL, 0x300, 0x310, 0x1, 0,
|
||||
21, 0x300, 1, 0x304, 0),
|
||||
PLL(CLK_APMIXED_ETH2PLL, 0x314, 0x320, 0x1, 0,
|
||||
21, 0x314, 1, 0x318, 0),
|
||||
PLL(CLK_APMIXED_SGMIPLL, 0x358, 0x368, 0x1, 0,
|
||||
21, 0x358, 1, 0x35c, 0),
|
||||
};
|
||||
|
||||
/* topckgen */
|
||||
#define FACTOR0(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
|
||||
|
||||
#define FACTOR1(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
|
||||
|
||||
#define FACTOR2(_id, _parent, _mult, _div) \
|
||||
FACTOR(_id, _parent, _mult, _div, 0)
|
||||
|
||||
static const struct mtk_fixed_clk top_fixed_clks[] = {
|
||||
FIXED_CLK(CLK_TOP_TO_U2_PHY, CLK_XTAL, 31250000),
|
||||
FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, CLK_XTAL, 31250000),
|
||||
FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, CLK_XTAL, 125000000),
|
||||
FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, CLK_XTAL, 125000000),
|
||||
FIXED_CLK(CLK_TOP_SSUSB_TX250M, CLK_XTAL, 250000000),
|
||||
FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, CLK_XTAL, 250000000),
|
||||
FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, CLK_XTAL, 33333333),
|
||||
FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, CLK_XTAL, 50000000),
|
||||
FIXED_CLK(CLK_TOP_SATA_ASIC, CLK_XTAL, 50000000),
|
||||
FIXED_CLK(CLK_TOP_SATA_RBC, CLK_XTAL, 50000000),
|
||||
};
|
||||
|
||||
static const struct mtk_fixed_factor top_fixed_divs[] = {
|
||||
FACTOR0(CLK_TOP_TO_USB3_SYS, CLK_APMIXED_ETH1PLL, 1, 4),
|
||||
FACTOR0(CLK_TOP_P1_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
|
||||
FACTOR0(CLK_TOP_4MHZ, CLK_APMIXED_ETH1PLL, 1, 125),
|
||||
FACTOR0(CLK_TOP_P0_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
|
||||
FACTOR0(CLK_TOP_ETH_500M, CLK_APMIXED_ETH1PLL, 1, 1),
|
||||
FACTOR1(CLK_TOP_TXCLK_SRC_PRE, CLK_TOP_SGMIIPLL_D2, 1, 1),
|
||||
FACTOR2(CLK_TOP_RTC, CLK_XTAL, 1, 1024),
|
||||
FACTOR2(CLK_TOP_PWM_QTR_26M, CLK_XTAL, 1, 1),
|
||||
FACTOR2(CLK_TOP_CPUM_TCK_IN, CLK_XTAL, 1, 1),
|
||||
FACTOR2(CLK_TOP_TO_USB3_DA_TOP, CLK_XTAL, 1, 1),
|
||||
FACTOR2(CLK_TOP_MEMPLL, CLK_XTAL, 32, 1),
|
||||
FACTOR1(CLK_TOP_DMPLL, CLK_TOP_MEMPLL, 1, 1),
|
||||
FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_MEMPLL, 1, 4),
|
||||
FACTOR1(CLK_TOP_DMPLL_D8, CLK_TOP_MEMPLL, 1, 8),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
|
||||
FACTOR0(CLK_TOP_SYSPLL1_D2, CLK_APMIXED_MAINPLL, 1, 4),
|
||||
FACTOR0(CLK_TOP_SYSPLL1_D4, CLK_APMIXED_MAINPLL, 1, 8),
|
||||
FACTOR0(CLK_TOP_SYSPLL1_D8, CLK_APMIXED_MAINPLL, 1, 16),
|
||||
FACTOR0(CLK_TOP_SYSPLL1_D16, CLK_APMIXED_MAINPLL, 1, 32),
|
||||
FACTOR0(CLK_TOP_SYSPLL2_D2, CLK_APMIXED_MAINPLL, 1, 6),
|
||||
FACTOR0(CLK_TOP_SYSPLL2_D4, CLK_APMIXED_MAINPLL, 1, 12),
|
||||
FACTOR0(CLK_TOP_SYSPLL2_D8, CLK_APMIXED_MAINPLL, 1, 24),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
|
||||
FACTOR0(CLK_TOP_SYSPLL3_D2, CLK_APMIXED_MAINPLL, 1, 10),
|
||||
FACTOR0(CLK_TOP_SYSPLL3_D4, CLK_APMIXED_MAINPLL, 1, 20),
|
||||
FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
|
||||
FACTOR0(CLK_TOP_SYSPLL4_D2, CLK_APMIXED_MAINPLL, 1, 14),
|
||||
FACTOR0(CLK_TOP_SYSPLL4_D4, CLK_APMIXED_MAINPLL, 1, 28),
|
||||
FACTOR0(CLK_TOP_SYSPLL4_D16, CLK_APMIXED_MAINPLL, 1, 112),
|
||||
FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIV2PLL, 1, 2),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL, 1, 4),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL, 1, 8),
|
||||
FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL, 1, 16),
|
||||
FACTOR1(CLK_TOP_UNIVPLL_D3, CLK_TOP_UNIVPLL, 1, 3),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL, 1, 6),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL, 1, 12),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL, 1, 24),
|
||||
FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL, 1, 48),
|
||||
FACTOR1(CLK_TOP_UNIVPLL_D5, CLK_TOP_UNIVPLL, 1, 5),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL, 1, 10),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL, 1, 20),
|
||||
FACTOR1(CLK_TOP_UNIVPLL3_D16, CLK_TOP_UNIVPLL, 1, 80),
|
||||
FACTOR1(CLK_TOP_UNIVPLL_D7, CLK_TOP_UNIVPLL, 1, 7),
|
||||
FACTOR1(CLK_TOP_UNIVPLL_D80_D4, CLK_TOP_UNIVPLL, 1, 320),
|
||||
FACTOR1(CLK_TOP_UNIV48M, CLK_TOP_UNIVPLL, 1, 25),
|
||||
FACTOR0(CLK_TOP_SGMIIPLL_D2, CLK_APMIXED_SGMIPLL, 1, 2),
|
||||
FACTOR2(CLK_TOP_CLKXTAL_D4, CLK_XTAL, 1, 4),
|
||||
FACTOR1(CLK_TOP_HD_FAXI, CLK_TOP_AXI_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_FAXI, CLK_TOP_AXI_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_F_FAUD_INTBUS, CLK_TOP_AUD_INTBUS_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_AP2WBHIF_HCLK, CLK_TOP_SYSPLL1_D8, 1, 1),
|
||||
FACTOR1(CLK_TOP_10M_INFRAO, CLK_TOP_10M_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_MSDC30_1, CLK_TOP_MSDC30_1, 1, 1),
|
||||
FACTOR1(CLK_TOP_SPI, CLK_TOP_SPI0_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_SF, CLK_TOP_NFI_INFRA_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_FLASH, CLK_TOP_FLASH_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_TO_USB3_REF, CLK_TOP_SATA_SEL, 1, 4),
|
||||
FACTOR1(CLK_TOP_TO_USB3_MCU, CLK_TOP_AXI_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_TO_USB3_DMA, CLK_TOP_HIF_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_FROM_TOP_AHB, CLK_TOP_AXI_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_FROM_TOP_AXI, CLK_TOP_HIF_SEL, 1, 1),
|
||||
FACTOR1(CLK_TOP_PCIE1_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
|
||||
FACTOR1(CLK_TOP_PCIE0_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
|
||||
};
|
||||
|
||||
static const int axi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_UNIVPLL_D7,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int mem_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int ddrphycfg_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8
|
||||
};
|
||||
|
||||
static const int eth_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_SGMIIPLL_D2,
|
||||
CLK_TOP_UNIVPLL_D7,
|
||||
CLK_TOP_DMPLL
|
||||
};
|
||||
|
||||
static const int pwm_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int f10m_ref_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SGMIIPLL_D2
|
||||
};
|
||||
|
||||
static const int nfi_infra_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D8,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_UNIVPLL1_D8,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL3_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_SYSPLL_D7
|
||||
};
|
||||
|
||||
static const int flash_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL_D80_D4,
|
||||
CLK_TOP_SYSPLL2_D8,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_UNIVPLL1_D8,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int uart_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D8
|
||||
};
|
||||
|
||||
static const int spi0_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL1_D8,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int spi1_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL3_D2,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL4_D4,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_UNIVPLL1_D8,
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int msdc30_0_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D16,
|
||||
CLK_TOP_UNIV48M
|
||||
};
|
||||
|
||||
static const int msdc30_1_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D16,
|
||||
CLK_TOP_UNIV48M,
|
||||
CLK_TOP_SYSPLL2_D4,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_SYSPLL_D7,
|
||||
CLK_TOP_SYSPLL2_D2,
|
||||
CLK_TOP_UNIVPLL2_D2
|
||||
};
|
||||
|
||||
static const int ap2wbmcu_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_UNIV48M,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_SYSPLL_D7,
|
||||
CLK_TOP_SYSPLL2_D2,
|
||||
CLK_TOP_UNIVPLL2_D2
|
||||
};
|
||||
|
||||
static const int audio_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_SYSPLL4_D4,
|
||||
CLK_TOP_SYSPLL1_D16
|
||||
};
|
||||
|
||||
static const int aud_intbus_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_SYSPLL4_D2,
|
||||
CLK_TOP_DMPLL_D4
|
||||
};
|
||||
|
||||
static const int pmicspi_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_SYSPLL3_D4,
|
||||
CLK_TOP_SYSPLL1_D16,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D4,
|
||||
CLK_TOP_DMPLL_D8
|
||||
};
|
||||
|
||||
static const int scp_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D8,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int atb_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_SYSPLL_D5
|
||||
};
|
||||
|
||||
static const int hif_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D4,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
-1,
|
||||
CLK_TOP_UNIVPLL_D7
|
||||
};
|
||||
|
||||
static const int sata_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL2_D4
|
||||
};
|
||||
|
||||
static const int usb20_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL3_D4,
|
||||
CLK_TOP_SYSPLL1_D8
|
||||
};
|
||||
|
||||
static const int aud1_parents[] = {
|
||||
CLK_XTAL
|
||||
};
|
||||
|
||||
static const int irrx_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_SYSPLL4_D16
|
||||
};
|
||||
|
||||
static const int crypto_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_UNIVPLL_D3,
|
||||
CLK_TOP_UNIVPLL1_D2,
|
||||
CLK_TOP_SYSPLL1_D2,
|
||||
CLK_TOP_UNIVPLL_D5,
|
||||
CLK_TOP_SYSPLL_D5,
|
||||
CLK_TOP_UNIVPLL2_D2,
|
||||
CLK_TOP_SYSPLL_D2
|
||||
};
|
||||
|
||||
static const int gpt10m_parents[] = {
|
||||
CLK_XTAL,
|
||||
CLK_TOP_CLKXTAL_D4
|
||||
};
|
||||
|
||||
static const struct mtk_composite top_muxes[] = {
|
||||
/* CLK_CFG_0 */
|
||||
MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
|
||||
MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
|
||||
MUX_GATE(CLK_TOP_ETH_SEL, eth_parents, 0x40, 24, 3, 31),
|
||||
|
||||
/* CLK_CFG_1 */
|
||||
MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_F10M_REF_SEL, f10m_ref_parents, 0x50, 8, 1, 15),
|
||||
MUX_GATE(CLK_TOP_NFI_INFRA_SEL, nfi_infra_parents, 0x50, 16, 4, 23),
|
||||
MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0x50, 24, 3, 31),
|
||||
|
||||
/* CLK_CFG_2 */
|
||||
MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
|
||||
MUX_GATE(CLK_TOP_SPI0_SEL, spi0_parents, 0x60, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_SPI1_SEL, spi1_parents, 0x60, 16, 3, 23),
|
||||
MUX_GATE(CLK_TOP_MSDC50_0_SEL, uart_parents, 0x60, 24, 3, 31),
|
||||
|
||||
/* CLK_CFG_3 */
|
||||
MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_0_parents, 0x70, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_1_parents, 0x70, 8, 3, 15),
|
||||
MUX_GATE(CLK_TOP_AP2WBMCU_SEL, ap2wbmcu_parents, 0x70, 16, 3, 23),
|
||||
MUX_GATE(CLK_TOP_AP2WBHIF_SEL, ap2wbmcu_parents, 0x70, 24, 3, 31),
|
||||
|
||||
/* CLK_CFG_4 */
|
||||
MUX_GATE(CLK_TOP_AUDIO_SEL, audio_parents, 0x80, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, aud_intbus_parents, 0x80, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 16, 3, 23),
|
||||
MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 24, 2, 31),
|
||||
|
||||
/* CLK_CFG_5 */
|
||||
MUX_GATE(CLK_TOP_ATB_SEL, atb_parents, 0x90, 0, 2, 7),
|
||||
MUX_GATE_FLAGS(CLK_TOP_HIF_SEL, hif_parents, 0x90, 8, 3, 15,
|
||||
CLK_DOMAIN_SCPSYS),
|
||||
MUX_GATE(CLK_TOP_SATA_SEL, sata_parents, 0x90, 16, 1, 23),
|
||||
MUX_GATE(CLK_TOP_U2_SEL, usb20_parents, 0x90, 24, 2, 31),
|
||||
|
||||
/* CLK_CFG_6 */
|
||||
MUX_GATE(CLK_TOP_AUD1_SEL, aud1_parents, 0xA0, 0, 1, 7),
|
||||
MUX_GATE(CLK_TOP_AUD2_SEL, aud1_parents, 0xA0, 8, 1, 15),
|
||||
MUX_GATE(CLK_TOP_IRRX_SEL, irrx_parents, 0xA0, 16, 1, 23),
|
||||
MUX_GATE(CLK_TOP_IRTX_SEL, irrx_parents, 0xA0, 24, 1, 31),
|
||||
|
||||
/* CLK_CFG_7 */
|
||||
MUX_GATE(CLK_TOP_SATA_MCU_SEL, scp_parents, 0xB0, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_PCIE0_MCU_SEL, scp_parents, 0xB0, 8, 2, 15),
|
||||
MUX_GATE(CLK_TOP_PCIE1_MCU_SEL, scp_parents, 0xB0, 16, 2, 23),
|
||||
MUX_GATE(CLK_TOP_SSUSB_MCU_SEL, scp_parents, 0xB0, 24, 2, 31),
|
||||
|
||||
/* CLK_CFG_8 */
|
||||
MUX_GATE(CLK_TOP_CRYPTO_SEL, crypto_parents, 0xC0, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_SGMII_REF_1_SEL, f10m_ref_parents, 0xC0, 8, 1, 15),
|
||||
MUX_GATE(CLK_TOP_10M_SEL, gpt10m_parents, 0xC0, 16, 1, 23),
|
||||
};
|
||||
|
||||
/* infracfg */
|
||||
static const struct mtk_gate_regs infra_cg_regs = {
|
||||
.set_ofs = 0x40,
|
||||
.clr_ofs = 0x44,
|
||||
.sta_ofs = 0x48,
|
||||
};
|
||||
|
||||
#define GATE_INFRA(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &infra_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate infra_cgs[] = {
|
||||
GATE_INFRA(CLK_INFRA_DBGCLK_PD, CLK_TOP_HD_FAXI, 0),
|
||||
GATE_INFRA(CLK_INFRA_TRNG_PD, CLK_TOP_HD_FAXI, 2),
|
||||
GATE_INFRA(CLK_INFRA_DEVAPC_PD, CLK_TOP_HD_FAXI, 4),
|
||||
GATE_INFRA(CLK_INFRA_APXGPT_PD, CLK_TOP_10M_INFRAO, 18),
|
||||
GATE_INFRA(CLK_INFRA_SEJ_PD, CLK_TOP_10M_INFRAO, 19),
|
||||
};
|
||||
|
||||
/* pericfg */
|
||||
static const struct mtk_gate_regs peri0_cg_regs = {
|
||||
.set_ofs = 0x8,
|
||||
.clr_ofs = 0x10,
|
||||
.sta_ofs = 0x18,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs peri1_cg_regs = {
|
||||
.set_ofs = 0xC,
|
||||
.clr_ofs = 0x14,
|
||||
.sta_ofs = 0x1C,
|
||||
};
|
||||
|
||||
#define GATE_PERI0(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &peri0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
#define GATE_PERI1(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &peri1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate peri_cgs[] = {
|
||||
GATE_PERI0(CLK_PERI_PWM1_PD, CLK_TOP_PWM_QTR_26M, 2),
|
||||
GATE_PERI0(CLK_PERI_PWM2_PD, CLK_TOP_PWM_QTR_26M, 3),
|
||||
GATE_PERI0(CLK_PERI_PWM3_PD, CLK_TOP_PWM_QTR_26M, 4),
|
||||
GATE_PERI0(CLK_PERI_PWM4_PD, CLK_TOP_PWM_QTR_26M, 5),
|
||||
GATE_PERI0(CLK_PERI_PWM5_PD, CLK_TOP_PWM_QTR_26M, 6),
|
||||
GATE_PERI0(CLK_PERI_PWM6_PD, CLK_TOP_PWM_QTR_26M, 7),
|
||||
GATE_PERI0(CLK_PERI_PWM7_PD, CLK_TOP_PWM_QTR_26M, 8),
|
||||
GATE_PERI0(CLK_PERI_PWM_PD, CLK_TOP_PWM_QTR_26M, 9),
|
||||
GATE_PERI0(CLK_PERI_AP_DMA_PD, CLK_TOP_FAXI, 12),
|
||||
GATE_PERI0(CLK_PERI_MSDC30_1_PD, CLK_TOP_MSDC30_1, 14),
|
||||
GATE_PERI0(CLK_PERI_UART0_PD, CLK_TOP_FAXI, 17),
|
||||
GATE_PERI0(CLK_PERI_UART1_PD, CLK_TOP_FAXI, 18),
|
||||
GATE_PERI0(CLK_PERI_UART2_PD, CLK_TOP_FAXI, 19),
|
||||
GATE_PERI0(CLK_PERI_UART3_PD, CLK_TOP_FAXI, 20),
|
||||
GATE_PERI0(CLK_PERI_BTIF_PD, CLK_TOP_FAXI, 22),
|
||||
GATE_PERI0(CLK_PERI_I2C0_PD, CLK_TOP_FAXI, 23),
|
||||
GATE_PERI0(CLK_PERI_SPI0_PD, CLK_TOP_SPI, 28),
|
||||
GATE_PERI0(CLK_PERI_SNFI_PD, CLK_TOP_SF, 29),
|
||||
GATE_PERI0(CLK_PERI_NFI_PD, CLK_TOP_FAXI, 30),
|
||||
GATE_PERI0(CLK_PERI_NFIECC_PD, CLK_TOP_FAXI, 31),
|
||||
GATE_PERI1(CLK_PERI_FLASH_PD, CLK_TOP_FLASH, 1),
|
||||
};
|
||||
|
||||
/* ethsys */
|
||||
static const struct mtk_gate_regs eth_cg_regs = {
|
||||
.sta_ofs = 0x30,
|
||||
};
|
||||
|
||||
#define GATE_ETH(_id, _parent, _shift, _flag) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = ð_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_NO_SETCLR_INV | (_flag), \
|
||||
}
|
||||
|
||||
#define GATE_ETH0(_id, _parent, _shift) \
|
||||
GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
|
||||
|
||||
#define GATE_ETH1(_id, _parent, _shift) \
|
||||
GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
|
||||
|
||||
static const struct mtk_gate eth_cgs[] = {
|
||||
GATE_ETH0(CLK_ETH_FE_EN, CLK_APMIXED_ETH2PLL, 6),
|
||||
GATE_ETH1(CLK_ETH_GP2_EN, CLK_TOP_TXCLK_SRC_PRE, 7),
|
||||
GATE_ETH1(CLK_ETH_GP1_EN, CLK_TOP_TXCLK_SRC_PRE, 8),
|
||||
GATE_ETH1(CLK_ETH_GP0_EN, CLK_TOP_TXCLK_SRC_PRE, 9),
|
||||
GATE_ETH1(CLK_ETH_ESW_EN, CLK_TOP_ETH_500M, 16),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs sgmii_cg_regs = {
|
||||
.set_ofs = 0xE4,
|
||||
.clr_ofs = 0xE4,
|
||||
.sta_ofs = 0xE4,
|
||||
};
|
||||
|
||||
#define GATE_SGMII(_id, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.regs = &sgmii_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate sgmii_cgs[] = {
|
||||
GATE_SGMII(CLK_SGMII_TX_EN, CLK_TOP_SSUSB_TX250M, 2),
|
||||
GATE_SGMII(CLK_SGMII_RX_EN, CLK_TOP_SSUSB_EQ_RX250M, 3),
|
||||
GATE_SGMII(CLK_SGMII_CDR_REF, CLK_TOP_SSUSB_CDR_REF, 4),
|
||||
GATE_SGMII(CLK_SGMII_CDR_FB, CLK_TOP_SSUSB_CDR_FB, 5),
|
||||
};
|
||||
|
||||
static const struct mtk_clk_tree mt7629_clk_tree = {
|
||||
.xtal_rate = 40 * MHZ,
|
||||
.xtal2_rate = 20 * MHZ,
|
||||
.fdivs_offs = CLK_TOP_TO_USB3_SYS,
|
||||
.muxes_offs = CLK_TOP_AXI_SEL,
|
||||
.plls = apmixed_plls,
|
||||
.fclks = top_fixed_clks,
|
||||
.fdivs = top_fixed_divs,
|
||||
.muxes = top_muxes,
|
||||
};
|
||||
|
||||
static int mt7629_mcucfg_probe(struct udevice *dev)
|
||||
{
|
||||
void __iomem *base;
|
||||
|
||||
base = dev_read_addr_ptr(dev);
|
||||
if (!base)
|
||||
return -ENOENT;
|
||||
|
||||
clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
|
||||
AXI_DIV_SEL(0x12));
|
||||
clrsetbits_le32(base + MCU_BUS_MUX, MCU_BUS_MSK,
|
||||
MCU_BUS_SEL(0x1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7629_apmixedsys_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = mtk_common_clk_init(dev, &mt7629_clk_tree);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* reduce clock square disable time */
|
||||
writel(0x501, priv->base + MT7629_CLKSQ_STB_CON0);
|
||||
/* extend pwr/iso control timing to 1us */
|
||||
writel(0x80008, priv->base + MT7629_PLL_ISO_CON0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7629_topckgen_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_init(dev, &mt7629_clk_tree);
|
||||
}
|
||||
|
||||
static int mt7629_infracfg_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, infra_cgs);
|
||||
}
|
||||
|
||||
static int mt7629_pericfg_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, peri_cgs);
|
||||
}
|
||||
|
||||
static int mt7629_ethsys_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs);
|
||||
}
|
||||
|
||||
static int mt7629_sgmiisys_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs);
|
||||
}
|
||||
|
||||
static const struct udevice_id mt7629_apmixed_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-apmixedsys" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_topckgen_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-topckgen" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_infracfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-infracfg", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_pericfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-pericfg", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_ethsys_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-ethsys", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_sgmiisys_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-sgmiisys", },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7629_mcucfg_compat[] = {
|
||||
{ .compatible = "mediatek,mt7629-mcucfg" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_mcucfg) = {
|
||||
.name = "mt7629-mcucfg",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = mt7629_mcucfg_compat,
|
||||
.probe = mt7629_mcucfg_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
|
||||
.name = "mt7629-clock-apmixedsys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_apmixed_compat,
|
||||
.probe = mt7629_apmixedsys_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
|
||||
.ops = &mtk_clk_apmixedsys_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_topckgen) = {
|
||||
.name = "mt7629-clock-topckgen",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_topckgen_compat,
|
||||
.probe = mt7629_topckgen_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
|
||||
.ops = &mtk_clk_topckgen_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_infracfg) = {
|
||||
.name = "mt7629-clock-infracfg",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_infracfg_compat,
|
||||
.probe = mt7629_infracfg_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_pericfg) = {
|
||||
.name = "mt7629-clock-pericfg",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_pericfg_compat,
|
||||
.probe = mt7629_pericfg_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_ethsys) = {
|
||||
.name = "mt7629-clock-ethsys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_ethsys_compat,
|
||||
.probe = mt7629_ethsys_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_clk_sgmiisys) = {
|
||||
.name = "mt7629-clock-sgmiisys",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7629_sgmiisys_compat,
|
||||
.probe = mt7629_sgmiisys_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||
.ops = &mtk_clk_gate_ops,
|
||||
};
|
493
drivers/clk/mediatek/clk-mtk.c
Normal file
493
drivers/clk/mediatek/clk-mtk.c
Normal file
@ -0,0 +1,493 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek common clock driver
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
|
||||
#define REG_CON0 0
|
||||
#define REG_CON1 4
|
||||
|
||||
#define CON0_BASE_EN BIT(0)
|
||||
#define CON0_PWR_ON BIT(0)
|
||||
#define CON0_ISO_EN BIT(1)
|
||||
#define CON1_PCW_CHG BIT(31)
|
||||
|
||||
#define POSTDIV_MASK 0x7
|
||||
#define INTEGER_BITS 7
|
||||
|
||||
/* scpsys clock off control */
|
||||
#define CLK_SCP_CFG0 0x200
|
||||
#define CLK_SCP_CFG1 0x204
|
||||
#define SCP_ARMCK_OFF_EN GENMASK(9, 0)
|
||||
#define SCP_AXICK_DCM_DIS_EN BIT(0)
|
||||
#define SCP_AXICK_26M_SEL_EN BIT(4)
|
||||
|
||||
/* shared functions */
|
||||
|
||||
/*
|
||||
* In case the rate change propagation to parent clocks is undesirable,
|
||||
* this function is recursively called to find the parent to calculate
|
||||
* the accurate frequency.
|
||||
*/
|
||||
static int mtk_clk_find_parent_rate(struct clk *clk, int id,
|
||||
const struct driver *drv)
|
||||
{
|
||||
struct clk parent = { .id = id, };
|
||||
|
||||
if (drv) {
|
||||
struct udevice *dev;
|
||||
|
||||
if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
|
||||
return -ENODEV;
|
||||
|
||||
parent.dev = dev;
|
||||
} else {
|
||||
parent.dev = clk->dev;
|
||||
}
|
||||
|
||||
return clk_get_rate(&parent);
|
||||
}
|
||||
|
||||
static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
|
||||
const struct mtk_composite *mux)
|
||||
{
|
||||
u32 val, index = 0;
|
||||
|
||||
while (mux->parent[index] != parent)
|
||||
if (++index == mux->num_parents)
|
||||
return -EINVAL;
|
||||
|
||||
/* switch mux to a select parent */
|
||||
val = readl(base + mux->mux_reg);
|
||||
val &= ~(mux->mux_mask << mux->mux_shift);
|
||||
|
||||
val |= index << mux->mux_shift;
|
||||
writel(val, base + mux->mux_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* apmixedsys functions */
|
||||
|
||||
static unsigned long __mtk_pll_recalc_rate(const struct mtk_pll_data *pll,
|
||||
u32 fin, u32 pcw, int postdiv)
|
||||
{
|
||||
int pcwbits = pll->pcwbits;
|
||||
int pcwfbits;
|
||||
u64 vco;
|
||||
u8 c = 0;
|
||||
|
||||
/* The fractional part of the PLL divider. */
|
||||
pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
|
||||
|
||||
vco = (u64)fin * pcw;
|
||||
|
||||
if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
|
||||
c = 1;
|
||||
|
||||
vco >>= pcwfbits;
|
||||
|
||||
if (c)
|
||||
vco++;
|
||||
|
||||
return ((unsigned long)vco + postdiv - 1) / postdiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaTek PLLs are configured through their pcw value. The pcw value
|
||||
* describes a divider in the PLL feedback loop which consists of 7 bits
|
||||
* for the integer part and the remaining bits (if present) for the
|
||||
* fractional part. Also they have a 3 bit power-of-two post divider.
|
||||
*/
|
||||
static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
|
||||
u32 val;
|
||||
|
||||
/* set postdiv */
|
||||
val = readl(priv->base + pll->pd_reg);
|
||||
val &= ~(POSTDIV_MASK << pll->pd_shift);
|
||||
val |= (ffs(postdiv) - 1) << pll->pd_shift;
|
||||
|
||||
/* postdiv and pcw need to set at the same time if on same register */
|
||||
if (pll->pd_reg != pll->pcw_reg) {
|
||||
writel(val, priv->base + pll->pd_reg);
|
||||
val = readl(priv->base + pll->pcw_reg);
|
||||
}
|
||||
|
||||
/* set pcw */
|
||||
val &= ~GENMASK(pll->pcw_shift + pll->pcwbits - 1, pll->pcw_shift);
|
||||
val |= pcw << pll->pcw_shift;
|
||||
val &= ~CON1_PCW_CHG;
|
||||
writel(val, priv->base + pll->pcw_reg);
|
||||
|
||||
val |= CON1_PCW_CHG;
|
||||
writel(val, priv->base + pll->pcw_reg);
|
||||
|
||||
udelay(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* mtk_pll_calc_values - calculate good values for a given input frequency.
|
||||
* @clk: The clk
|
||||
* @pcw: The pcw value (output)
|
||||
* @postdiv: The post divider (output)
|
||||
* @freq: The desired target frequency
|
||||
*/
|
||||
static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
|
||||
u32 freq)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
|
||||
unsigned long fmin = 1000 * MHZ;
|
||||
u64 _pcw;
|
||||
u32 val;
|
||||
|
||||
if (freq > pll->fmax)
|
||||
freq = pll->fmax;
|
||||
|
||||
for (val = 0; val < 5; val++) {
|
||||
*postdiv = 1 << val;
|
||||
if ((u64)freq * *postdiv >= fmin)
|
||||
break;
|
||||
}
|
||||
|
||||
/* _pcw = freq * postdiv / xtal_rate * 2^pcwfbits */
|
||||
_pcw = ((u64)freq << val) << (pll->pcwbits - INTEGER_BITS);
|
||||
do_div(_pcw, priv->tree->xtal2_rate);
|
||||
|
||||
*pcw = (u32)_pcw;
|
||||
}
|
||||
|
||||
static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
u32 pcw = 0;
|
||||
u32 postdiv;
|
||||
|
||||
mtk_pll_calc_values(clk, &pcw, &postdiv, rate);
|
||||
mtk_pll_set_rate_regs(clk, pcw, postdiv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong mtk_apmixedsys_get_rate(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
|
||||
u32 postdiv;
|
||||
u32 pcw;
|
||||
|
||||
postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
|
||||
POSTDIV_MASK;
|
||||
postdiv = 1 << postdiv;
|
||||
|
||||
pcw = readl(priv->base + pll->pcw_reg) >> pll->pcw_shift;
|
||||
pcw &= GENMASK(pll->pcwbits - 1, 0);
|
||||
|
||||
return __mtk_pll_recalc_rate(pll, priv->tree->xtal2_rate,
|
||||
pcw, postdiv);
|
||||
}
|
||||
|
||||
static int mtk_apmixedsys_enable(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
|
||||
u32 r;
|
||||
|
||||
r = readl(priv->base + pll->pwr_reg) | CON0_PWR_ON;
|
||||
writel(r, priv->base + pll->pwr_reg);
|
||||
udelay(1);
|
||||
|
||||
r = readl(priv->base + pll->pwr_reg) & ~CON0_ISO_EN;
|
||||
writel(r, priv->base + pll->pwr_reg);
|
||||
udelay(1);
|
||||
|
||||
r = readl(priv->base + pll->reg + REG_CON0);
|
||||
r |= pll->en_mask;
|
||||
writel(r, priv->base + pll->reg + REG_CON0);
|
||||
|
||||
udelay(20);
|
||||
|
||||
if (pll->flags & HAVE_RST_BAR) {
|
||||
r = readl(priv->base + pll->reg + REG_CON0);
|
||||
r |= pll->rst_bar_mask;
|
||||
writel(r, priv->base + pll->reg + REG_CON0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_apmixedsys_disable(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
|
||||
u32 r;
|
||||
|
||||
if (pll->flags & HAVE_RST_BAR) {
|
||||
r = readl(priv->base + pll->reg + REG_CON0);
|
||||
r &= ~pll->rst_bar_mask;
|
||||
writel(r, priv->base + pll->reg + REG_CON0);
|
||||
}
|
||||
|
||||
r = readl(priv->base + pll->reg + REG_CON0);
|
||||
r &= ~CON0_BASE_EN;
|
||||
writel(r, priv->base + pll->reg + REG_CON0);
|
||||
|
||||
r = readl(priv->base + pll->pwr_reg) | CON0_ISO_EN;
|
||||
writel(r, priv->base + pll->pwr_reg);
|
||||
|
||||
r = readl(priv->base + pll->pwr_reg) & ~CON0_PWR_ON;
|
||||
writel(r, priv->base + pll->pwr_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* topckgen functions */
|
||||
|
||||
static ulong mtk_factor_recalc_rate(const struct mtk_fixed_factor *fdiv,
|
||||
ulong parent_rate)
|
||||
{
|
||||
u64 rate = parent_rate * fdiv->mult;
|
||||
|
||||
do_div(rate, fdiv->div);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int mtk_topckgen_get_factor_rate(struct clk *clk, u32 off)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
|
||||
ulong rate;
|
||||
|
||||
switch (fdiv->flags & CLK_PARENT_MASK) {
|
||||
case CLK_PARENT_APMIXED:
|
||||
rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
|
||||
DM_GET_DRIVER(mtk_clk_apmixedsys));
|
||||
break;
|
||||
case CLK_PARENT_TOPCKGEN:
|
||||
rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
rate = priv->tree->xtal_rate;
|
||||
}
|
||||
|
||||
return mtk_factor_recalc_rate(fdiv, rate);
|
||||
}
|
||||
|
||||
static int mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_composite *mux = &priv->tree->muxes[off];
|
||||
u32 index;
|
||||
|
||||
index = readl(priv->base + mux->mux_reg);
|
||||
index &= mux->mux_mask << mux->mux_shift;
|
||||
index = index >> mux->mux_shift;
|
||||
|
||||
if (mux->parent[index])
|
||||
return mtk_clk_find_parent_rate(clk, mux->parent[index],
|
||||
NULL);
|
||||
|
||||
return priv->tree->xtal_rate;
|
||||
}
|
||||
|
||||
static ulong mtk_topckgen_get_rate(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
if (clk->id < priv->tree->fdivs_offs)
|
||||
return priv->tree->fclks[clk->id].rate;
|
||||
else if (clk->id < priv->tree->muxes_offs)
|
||||
return mtk_topckgen_get_factor_rate(clk, clk->id -
|
||||
priv->tree->fdivs_offs);
|
||||
else
|
||||
return mtk_topckgen_get_mux_rate(clk, clk->id -
|
||||
priv->tree->muxes_offs);
|
||||
}
|
||||
|
||||
static int mtk_topckgen_enable(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_composite *mux;
|
||||
u32 val;
|
||||
|
||||
if (clk->id < priv->tree->muxes_offs)
|
||||
return 0;
|
||||
|
||||
mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
|
||||
if (mux->gate_shift < 0)
|
||||
return 0;
|
||||
|
||||
/* enable clock gate */
|
||||
val = readl(priv->base + mux->gate_reg);
|
||||
val &= ~BIT(mux->gate_shift);
|
||||
writel(val, priv->base + mux->gate_reg);
|
||||
|
||||
if (mux->flags & CLK_DOMAIN_SCPSYS) {
|
||||
/* enable scpsys clock off control */
|
||||
writel(SCP_ARMCK_OFF_EN, priv->base + CLK_SCP_CFG0);
|
||||
writel(SCP_AXICK_DCM_DIS_EN | SCP_AXICK_26M_SEL_EN,
|
||||
priv->base + CLK_SCP_CFG1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_topckgen_disable(struct clk *clk)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_composite *mux;
|
||||
u32 val;
|
||||
|
||||
if (clk->id < priv->tree->muxes_offs)
|
||||
return 0;
|
||||
|
||||
mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
|
||||
if (mux->gate_shift < 0)
|
||||
return 0;
|
||||
|
||||
/* disable clock gate */
|
||||
val = readl(priv->base + mux->gate_reg);
|
||||
val |= BIT(mux->gate_shift);
|
||||
writel(val, priv->base + mux->gate_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
if (clk->id < priv->tree->muxes_offs)
|
||||
return 0;
|
||||
|
||||
return mtk_clk_mux_set_parent(priv->base, parent->id,
|
||||
&priv->tree->muxes[clk->id - priv->tree->muxes_offs]);
|
||||
}
|
||||
|
||||
/* CG functions */
|
||||
|
||||
static int mtk_clk_gate_enable(struct clk *clk)
|
||||
{
|
||||
struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_gate *gate = &priv->gates[clk->id];
|
||||
u32 bit = BIT(gate->shift);
|
||||
|
||||
switch (gate->flags & CLK_GATE_MASK) {
|
||||
case CLK_GATE_SETCLR:
|
||||
writel(bit, priv->base + gate->regs->clr_ofs);
|
||||
break;
|
||||
case CLK_GATE_NO_SETCLR_INV:
|
||||
clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_clk_gate_disable(struct clk *clk)
|
||||
{
|
||||
struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_gate *gate = &priv->gates[clk->id];
|
||||
u32 bit = BIT(gate->shift);
|
||||
|
||||
switch (gate->flags & CLK_GATE_MASK) {
|
||||
case CLK_GATE_SETCLR:
|
||||
writel(bit, priv->base + gate->regs->set_ofs);
|
||||
break;
|
||||
case CLK_GATE_NO_SETCLR_INV:
|
||||
clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong mtk_clk_gate_get_rate(struct clk *clk)
|
||||
{
|
||||
struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct mtk_gate *gate = &priv->gates[clk->id];
|
||||
|
||||
switch (gate->flags & CLK_PARENT_MASK) {
|
||||
case CLK_PARENT_APMIXED:
|
||||
return mtk_clk_find_parent_rate(clk, gate->parent,
|
||||
DM_GET_DRIVER(mtk_clk_apmixedsys));
|
||||
break;
|
||||
case CLK_PARENT_TOPCKGEN:
|
||||
return mtk_clk_find_parent_rate(clk, gate->parent,
|
||||
DM_GET_DRIVER(mtk_clk_topckgen));
|
||||
break;
|
||||
|
||||
default:
|
||||
return priv->tree->xtal_rate;
|
||||
}
|
||||
}
|
||||
|
||||
const struct clk_ops mtk_clk_apmixedsys_ops = {
|
||||
.enable = mtk_apmixedsys_enable,
|
||||
.disable = mtk_apmixedsys_disable,
|
||||
.set_rate = mtk_apmixedsys_set_rate,
|
||||
.get_rate = mtk_apmixedsys_get_rate,
|
||||
};
|
||||
|
||||
const struct clk_ops mtk_clk_topckgen_ops = {
|
||||
.enable = mtk_topckgen_enable,
|
||||
.disable = mtk_topckgen_disable,
|
||||
.get_rate = mtk_topckgen_get_rate,
|
||||
.set_parent = mtk_topckgen_set_parent,
|
||||
};
|
||||
|
||||
const struct clk_ops mtk_clk_gate_ops = {
|
||||
.enable = mtk_clk_gate_enable,
|
||||
.disable = mtk_clk_gate_disable,
|
||||
.get_rate = mtk_clk_gate_get_rate,
|
||||
};
|
||||
|
||||
int mtk_common_clk_init(struct udevice *dev,
|
||||
const struct mtk_clk_tree *tree)
|
||||
{
|
||||
struct mtk_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
priv->tree = tree;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_common_clk_gate_init(struct udevice *dev,
|
||||
const struct mtk_clk_tree *tree,
|
||||
const struct mtk_gate *gates)
|
||||
{
|
||||
struct mtk_cg_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
priv->tree = tree;
|
||||
priv->gates = gates;
|
||||
|
||||
return 0;
|
||||
}
|
194
drivers/clk/mediatek/clk-mtk.h
Normal file
194
drivers/clk/mediatek/clk-mtk.h
Normal file
@ -0,0 +1,194 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef __DRV_CLK_MTK_H
|
||||
#define __DRV_CLK_MTK_H
|
||||
|
||||
#define CLK_XTAL 0
|
||||
#define MHZ (1000 * 1000)
|
||||
|
||||
#define HAVE_RST_BAR BIT(0)
|
||||
#define CLK_DOMAIN_SCPSYS BIT(0)
|
||||
|
||||
#define CLK_GATE_SETCLR BIT(0)
|
||||
#define CLK_GATE_SETCLR_INV BIT(1)
|
||||
#define CLK_GATE_NO_SETCLR BIT(2)
|
||||
#define CLK_GATE_NO_SETCLR_INV BIT(3)
|
||||
#define CLK_GATE_MASK GENMASK(3, 0)
|
||||
|
||||
#define CLK_PARENT_APMIXED BIT(4)
|
||||
#define CLK_PARENT_TOPCKGEN BIT(5)
|
||||
#define CLK_PARENT_MASK GENMASK(5, 4)
|
||||
|
||||
/* struct mtk_pll_data - hardware-specific PLLs data */
|
||||
struct mtk_pll_data {
|
||||
const int id;
|
||||
u32 reg;
|
||||
u32 pwr_reg;
|
||||
u32 en_mask;
|
||||
u32 pd_reg;
|
||||
int pd_shift;
|
||||
u32 flags;
|
||||
u32 rst_bar_mask;
|
||||
u64 fmax;
|
||||
int pcwbits;
|
||||
u32 pcw_reg;
|
||||
int pcw_shift;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_fixed_clk - fixed clocks
|
||||
*
|
||||
* @id: index of clocks
|
||||
* @parent: index of parnet clocks
|
||||
* @rate: fixed rate
|
||||
*/
|
||||
struct mtk_fixed_clk {
|
||||
const int id;
|
||||
const int parent;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
#define FIXED_CLK(_id, _parent, _rate) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.rate = _rate, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct mtk_fixed_factor - fixed multiplier and divider clocks
|
||||
*
|
||||
* @id: index of clocks
|
||||
* @parent: index of parnet clocks
|
||||
* @mult: multiplier
|
||||
* @div: divider
|
||||
* @flag: hardware-specific flags
|
||||
*/
|
||||
struct mtk_fixed_factor {
|
||||
const int id;
|
||||
const int parent;
|
||||
u32 mult;
|
||||
u32 div;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
#define FACTOR(_id, _parent, _mult, _div, _flags) { \
|
||||
.id = _id, \
|
||||
.parent = _parent, \
|
||||
.mult = _mult, \
|
||||
.div = _div, \
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct mtk_composite - aggregate clock of mux, divider and gate clocks
|
||||
*
|
||||
* @id: index of clocks
|
||||
* @parent: index of parnet clocks
|
||||
* @mux_reg: hardware-specific mux register
|
||||
* @gate_reg: hardware-specific gate register
|
||||
* @mux_mask: mask to the mux bit field
|
||||
* @mux_shift: shift to the mux bit field
|
||||
* @gate_shift: shift to the gate bit field
|
||||
* @num_parents: number of parent clocks
|
||||
* @flags: hardware-specific flags
|
||||
*/
|
||||
struct mtk_composite {
|
||||
const int id;
|
||||
const int *parent;
|
||||
u32 mux_reg;
|
||||
u32 gate_reg;
|
||||
u32 mux_mask;
|
||||
signed char mux_shift;
|
||||
signed char gate_shift;
|
||||
signed char num_parents;
|
||||
u16 flags;
|
||||
};
|
||||
|
||||
#define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, \
|
||||
_flags) { \
|
||||
.id = _id, \
|
||||
.mux_reg = _reg, \
|
||||
.mux_shift = _shift, \
|
||||
.mux_mask = BIT(_width) - 1, \
|
||||
.gate_reg = _reg, \
|
||||
.gate_shift = _gate, \
|
||||
.parent = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
#define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate) \
|
||||
MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
|
||||
|
||||
#define MUX(_id, _parents, _reg, _shift, _width) { \
|
||||
.id = _id, \
|
||||
.mux_reg = _reg, \
|
||||
.mux_shift = _shift, \
|
||||
.mux_mask = BIT(_width) - 1, \
|
||||
.gate_shift = -1, \
|
||||
.parent = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.flags = 0, \
|
||||
}
|
||||
|
||||
struct mtk_gate_regs {
|
||||
u32 sta_ofs;
|
||||
u32 clr_ofs;
|
||||
u32 set_ofs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_gate - gate clocks
|
||||
*
|
||||
* @id: index of gate clocks
|
||||
* @parent: index of parnet clocks
|
||||
* @regs: hardware-specific mux register
|
||||
* @shift: shift to the gate bit field
|
||||
* @flags: hardware-specific flags
|
||||
*/
|
||||
struct mtk_gate {
|
||||
const int id;
|
||||
const int parent;
|
||||
const struct mtk_gate_regs *regs;
|
||||
int shift;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/* struct mtk_clk_tree - clock tree */
|
||||
struct mtk_clk_tree {
|
||||
unsigned long xtal_rate;
|
||||
unsigned long xtal2_rate;
|
||||
const int fdivs_offs;
|
||||
const int muxes_offs;
|
||||
const struct mtk_pll_data *plls;
|
||||
const struct mtk_fixed_clk *fclks;
|
||||
const struct mtk_fixed_factor *fdivs;
|
||||
const struct mtk_composite *muxes;
|
||||
};
|
||||
|
||||
struct mtk_clk_priv {
|
||||
void __iomem *base;
|
||||
const struct mtk_clk_tree *tree;
|
||||
};
|
||||
|
||||
struct mtk_cg_priv {
|
||||
void __iomem *base;
|
||||
const struct mtk_clk_tree *tree;
|
||||
const struct mtk_gate *gates;
|
||||
};
|
||||
|
||||
extern const struct clk_ops mtk_clk_apmixedsys_ops;
|
||||
extern const struct clk_ops mtk_clk_topckgen_ops;
|
||||
extern const struct clk_ops mtk_clk_gate_ops;
|
||||
|
||||
int mtk_common_clk_init(struct udevice *dev,
|
||||
const struct mtk_clk_tree *tree);
|
||||
int mtk_common_clk_gate_init(struct udevice *dev,
|
||||
const struct mtk_clk_tree *tree,
|
||||
const struct mtk_gate *gates);
|
||||
|
||||
#endif /* __DRV_CLK_MTK_H */
|
@ -602,6 +602,17 @@ config FTSDC010_SDIO
|
||||
help
|
||||
This can enable ftsdc010 sdio function.
|
||||
|
||||
config MMC_MTK
|
||||
bool "MediaTek SD/MMC Card Interface support"
|
||||
depends on ARCH_MEDIATEK
|
||||
depends on BLK && DM_MMC
|
||||
depends on OF_CONTROL
|
||||
help
|
||||
This selects the MediaTek(R) Secure digital and Multimedia card Interface.
|
||||
If you have a machine with a integrated SD/MMC card reader, say Y or M here.
|
||||
This is needed if support for any SD/SDIO/MMC devices is required.
|
||||
If unsure, say N.
|
||||
|
||||
endif
|
||||
|
||||
config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
|
||||
|
@ -65,3 +65,4 @@ obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o
|
||||
obj-$(CONFIG_MMC_UNIPHIER) += tmio-common.o uniphier-sd.o
|
||||
obj-$(CONFIG_RENESAS_SDHI) += tmio-common.o renesas-sdhi.o
|
||||
obj-$(CONFIG_MMC_BCM2835) += bcm2835_sdhost.o
|
||||
obj-$(CONFIG_MMC_MTK) += mtk-sd.o
|
||||
|
1394
drivers/mmc/mtk-sd.c
Normal file
1394
drivers/mmc/mtk-sd.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -301,6 +301,7 @@ config ASPEED_AST2500_PINCTRL
|
||||
endif
|
||||
|
||||
source "drivers/pinctrl/meson/Kconfig"
|
||||
source "drivers/pinctrl/mediatek/Kconfig"
|
||||
source "drivers/pinctrl/nxp/Kconfig"
|
||||
source "drivers/pinctrl/renesas/Kconfig"
|
||||
source "drivers/pinctrl/uniphier/Kconfig"
|
||||
|
@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
|
||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
|
||||
obj-$(CONFIG_PINCTRL_MESON) += meson/
|
||||
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
|
||||
|
15
drivers/pinctrl/mediatek/Kconfig
Normal file
15
drivers/pinctrl/mediatek/Kconfig
Normal file
@ -0,0 +1,15 @@
|
||||
if ARCH_MEDIATEK
|
||||
|
||||
config PINCTRL_MTK
|
||||
depends on PINCTRL_GENERIC
|
||||
bool
|
||||
|
||||
config PINCTRL_MT7623
|
||||
bool "MT7623 SoC pinctrl driver"
|
||||
select PINCTRL_MTK
|
||||
|
||||
config PINCTRL_MT7629
|
||||
bool "MT7629 SoC pinctrl driver"
|
||||
select PINCTRL_MTK
|
||||
|
||||
endif
|
7
drivers/pinctrl/mediatek/Makefile
Normal file
7
drivers/pinctrl/mediatek/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Core
|
||||
obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
|
||||
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
|
||||
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
|
1284
drivers/pinctrl/mediatek/pinctrl-mt7623.c
Normal file
1284
drivers/pinctrl/mediatek/pinctrl-mt7623.c
Normal file
File diff suppressed because it is too large
Load Diff
409
drivers/pinctrl/mediatek/pinctrl-mt7629.c
Normal file
409
drivers/pinctrl/mediatek/pinctrl-mt7629.c
Normal file
@ -0,0 +1,409 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
|
||||
#include "pinctrl-mtk-common.h"
|
||||
|
||||
#define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
|
||||
PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, 32, false)
|
||||
|
||||
#define MT7629_PIN(_number, _name) MTK_PIN(_number, _name, DRV_GRP1)
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_mode_range[] = {
|
||||
PIN_FIELD(0, 78, 0x300, 0x10, 0, 4),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_dir_range[] = {
|
||||
PIN_FIELD(0, 78, 0x0, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_di_range[] = {
|
||||
PIN_FIELD(0, 78, 0x200, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_do_range[] = {
|
||||
PIN_FIELD(0, 78, 0x100, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_ies_range[] = {
|
||||
PIN_FIELD(0, 10, 0x1000, 0x10, 0, 1),
|
||||
PIN_FIELD(11, 18, 0x2000, 0x10, 0, 1),
|
||||
PIN_FIELD(19, 32, 0x3000, 0x10, 0, 1),
|
||||
PIN_FIELD(33, 48, 0x4000, 0x10, 0, 1),
|
||||
PIN_FIELD(49, 50, 0x5000, 0x10, 0, 1),
|
||||
PIN_FIELD(51, 69, 0x6000, 0x10, 0, 1),
|
||||
PIN_FIELD(70, 78, 0x7000, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_smt_range[] = {
|
||||
PIN_FIELD(0, 10, 0x1100, 0x10, 0, 1),
|
||||
PIN_FIELD(11, 18, 0x2100, 0x10, 0, 1),
|
||||
PIN_FIELD(19, 32, 0x3100, 0x10, 0, 1),
|
||||
PIN_FIELD(33, 48, 0x4100, 0x10, 0, 1),
|
||||
PIN_FIELD(49, 50, 0x5100, 0x10, 0, 1),
|
||||
PIN_FIELD(51, 69, 0x6100, 0x10, 0, 1),
|
||||
PIN_FIELD(70, 78, 0x7100, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_pullen_range[] = {
|
||||
PIN_FIELD(0, 10, 0x1400, 0x10, 0, 1),
|
||||
PIN_FIELD(11, 18, 0x2400, 0x10, 0, 1),
|
||||
PIN_FIELD(19, 32, 0x3400, 0x10, 0, 1),
|
||||
PIN_FIELD(33, 48, 0x4400, 0x10, 0, 1),
|
||||
PIN_FIELD(49, 50, 0x5400, 0x10, 0, 1),
|
||||
PIN_FIELD(51, 69, 0x6400, 0x10, 0, 1),
|
||||
PIN_FIELD(70, 78, 0x7400, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_pullsel_range[] = {
|
||||
PIN_FIELD(0, 10, 0x1500, 0x10, 0, 1),
|
||||
PIN_FIELD(11, 18, 0x2500, 0x10, 0, 1),
|
||||
PIN_FIELD(19, 32, 0x3500, 0x10, 0, 1),
|
||||
PIN_FIELD(33, 48, 0x4500, 0x10, 0, 1),
|
||||
PIN_FIELD(49, 50, 0x5500, 0x10, 0, 1),
|
||||
PIN_FIELD(51, 69, 0x6500, 0x10, 0, 1),
|
||||
PIN_FIELD(70, 78, 0x7500, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7629_pin_drv_range[] = {
|
||||
PIN_FIELD(0, 10, 0x1600, 0x10, 0, 4),
|
||||
PIN_FIELD(11, 18, 0x2600, 0x10, 0, 4),
|
||||
PIN_FIELD(19, 32, 0x3600, 0x10, 0, 4),
|
||||
PIN_FIELD(33, 48, 0x4600, 0x10, 0, 4),
|
||||
PIN_FIELD(49, 50, 0x5600, 0x10, 0, 4),
|
||||
PIN_FIELD(51, 69, 0x6600, 0x10, 0, 4),
|
||||
PIN_FIELD(70, 78, 0x7600, 0x10, 0, 4),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_reg_calc mt7629_reg_cals[] = {
|
||||
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7629_pin_mode_range),
|
||||
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7629_pin_dir_range),
|
||||
[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7629_pin_di_range),
|
||||
[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7629_pin_do_range),
|
||||
[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7629_pin_ies_range),
|
||||
[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7629_pin_smt_range),
|
||||
[PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7629_pin_pullsel_range),
|
||||
[PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7629_pin_pullen_range),
|
||||
[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7629_pin_drv_range),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_desc mt7629_pins[] = {
|
||||
MT7629_PIN(0, "TOP_5G_CLK"),
|
||||
MT7629_PIN(1, "TOP_5G_DATA"),
|
||||
MT7629_PIN(2, "WF0_5G_HB0"),
|
||||
MT7629_PIN(3, "WF0_5G_HB1"),
|
||||
MT7629_PIN(4, "WF0_5G_HB2"),
|
||||
MT7629_PIN(5, "WF0_5G_HB3"),
|
||||
MT7629_PIN(6, "WF0_5G_HB4"),
|
||||
MT7629_PIN(7, "WF0_5G_HB5"),
|
||||
MT7629_PIN(8, "WF0_5G_HB6"),
|
||||
MT7629_PIN(9, "XO_REQ"),
|
||||
MT7629_PIN(10, "TOP_RST_N"),
|
||||
MT7629_PIN(11, "SYS_WATCHDOG"),
|
||||
MT7629_PIN(12, "EPHY_LED0_N_JTDO"),
|
||||
MT7629_PIN(13, "EPHY_LED1_N_JTDI"),
|
||||
MT7629_PIN(14, "EPHY_LED2_N_JTMS"),
|
||||
MT7629_PIN(15, "EPHY_LED3_N_JTCLK"),
|
||||
MT7629_PIN(16, "EPHY_LED4_N_JTRST_N"),
|
||||
MT7629_PIN(17, "WF2G_LED_N"),
|
||||
MT7629_PIN(18, "WF5G_LED_N"),
|
||||
MT7629_PIN(19, "I2C_SDA"),
|
||||
MT7629_PIN(20, "I2C_SCL"),
|
||||
MT7629_PIN(21, "GPIO_9"),
|
||||
MT7629_PIN(22, "GPIO_10"),
|
||||
MT7629_PIN(23, "GPIO_11"),
|
||||
MT7629_PIN(24, "GPIO_12"),
|
||||
MT7629_PIN(25, "UART1_TXD"),
|
||||
MT7629_PIN(26, "UART1_RXD"),
|
||||
MT7629_PIN(27, "UART1_CTS"),
|
||||
MT7629_PIN(28, "UART1_RTS"),
|
||||
MT7629_PIN(29, "UART2_TXD"),
|
||||
MT7629_PIN(30, "UART2_RXD"),
|
||||
MT7629_PIN(31, "UART2_CTS"),
|
||||
MT7629_PIN(32, "UART2_RTS"),
|
||||
MT7629_PIN(33, "MDI_TP_P1"),
|
||||
MT7629_PIN(34, "MDI_TN_P1"),
|
||||
MT7629_PIN(35, "MDI_RP_P1"),
|
||||
MT7629_PIN(36, "MDI_RN_P1"),
|
||||
MT7629_PIN(37, "MDI_RP_P2"),
|
||||
MT7629_PIN(38, "MDI_RN_P2"),
|
||||
MT7629_PIN(39, "MDI_TP_P2"),
|
||||
MT7629_PIN(40, "MDI_TN_P2"),
|
||||
MT7629_PIN(41, "MDI_TP_P3"),
|
||||
MT7629_PIN(42, "MDI_TN_P3"),
|
||||
MT7629_PIN(43, "MDI_RP_P3"),
|
||||
MT7629_PIN(44, "MDI_RN_P3"),
|
||||
MT7629_PIN(45, "MDI_RP_P4"),
|
||||
MT7629_PIN(46, "MDI_RN_P4"),
|
||||
MT7629_PIN(47, "MDI_TP_P4"),
|
||||
MT7629_PIN(48, "MDI_TN_P4"),
|
||||
MT7629_PIN(49, "SMI_MDC"),
|
||||
MT7629_PIN(50, "SMI_MDIO"),
|
||||
MT7629_PIN(51, "PCIE_PERESET_N"),
|
||||
MT7629_PIN(52, "PWM_0"),
|
||||
MT7629_PIN(53, "GPIO_0"),
|
||||
MT7629_PIN(54, "GPIO_1"),
|
||||
MT7629_PIN(55, "GPIO_2"),
|
||||
MT7629_PIN(56, "GPIO_3"),
|
||||
MT7629_PIN(57, "GPIO_4"),
|
||||
MT7629_PIN(58, "GPIO_5"),
|
||||
MT7629_PIN(59, "GPIO_6"),
|
||||
MT7629_PIN(60, "GPIO_7"),
|
||||
MT7629_PIN(61, "GPIO_8"),
|
||||
MT7629_PIN(62, "SPI_CLK"),
|
||||
MT7629_PIN(63, "SPI_CS"),
|
||||
MT7629_PIN(64, "SPI_MOSI"),
|
||||
MT7629_PIN(65, "SPI_MISO"),
|
||||
MT7629_PIN(66, "SPI_WP"),
|
||||
MT7629_PIN(67, "SPI_HOLD"),
|
||||
MT7629_PIN(68, "UART0_TXD"),
|
||||
MT7629_PIN(69, "UART0_RXD"),
|
||||
MT7629_PIN(70, "TOP_2G_CLK"),
|
||||
MT7629_PIN(71, "TOP_2G_DATA"),
|
||||
MT7629_PIN(72, "WF0_2G_HB0"),
|
||||
MT7629_PIN(73, "WF0_2G_HB1"),
|
||||
MT7629_PIN(74, "WF0_2G_HB2"),
|
||||
MT7629_PIN(75, "WF0_2G_HB3"),
|
||||
MT7629_PIN(76, "WF0_2G_HB4"),
|
||||
MT7629_PIN(77, "WF0_2G_HB5"),
|
||||
MT7629_PIN(78, "WF0_2G_HB6"),
|
||||
};
|
||||
|
||||
/* List all groups consisting of these pins dedicated to the enablement of
|
||||
* certain hardware block and the corresponding mode for all of the pins.
|
||||
* The hardware probably has multiple combinations of these pinouts.
|
||||
*/
|
||||
|
||||
/* WF 5G */
|
||||
static int mt7629_wf0_5g_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
|
||||
static int mt7629_wf0_5g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
|
||||
|
||||
/* LED for EPHY */
|
||||
static int mt7629_ephy_leds_pins[] = { 12, 13, 14, 15, 16, 17, 18, };
|
||||
static int mt7629_ephy_leds_funcs[] = { 1, 1, 1, 1, 1, 1, 1, };
|
||||
static int mt7629_ephy_led0_pins[] = { 12, };
|
||||
static int mt7629_ephy_led0_funcs[] = { 1, };
|
||||
static int mt7629_ephy_led1_pins[] = { 13, };
|
||||
static int mt7629_ephy_led1_funcs[] = { 1, };
|
||||
static int mt7629_ephy_led2_pins[] = { 14, };
|
||||
static int mt7629_ephy_led2_funcs[] = { 1, };
|
||||
static int mt7629_ephy_led3_pins[] = { 15, };
|
||||
static int mt7629_ephy_led3_funcs[] = { 1, };
|
||||
static int mt7629_ephy_led4_pins[] = { 16, };
|
||||
static int mt7629_ephy_led4_funcs[] = { 1, };
|
||||
static int mt7629_wf2g_led_pins[] = { 17, };
|
||||
static int mt7629_wf2g_led_funcs[] = { 1, };
|
||||
static int mt7629_wf5g_led_pins[] = { 18, };
|
||||
static int mt7629_wf5g_led_funcs[] = { 1, };
|
||||
|
||||
/* Watchdog */
|
||||
static int mt7629_watchdog_pins[] = { 11, };
|
||||
static int mt7629_watchdog_funcs[] = { 1, };
|
||||
|
||||
/* LED for GPHY */
|
||||
static int mt7629_gphy_leds_0_pins[] = { 21, 22, 23, };
|
||||
static int mt7629_gphy_leds_0_funcs[] = { 2, 2, 2, };
|
||||
static int mt7629_gphy_led1_0_pins[] = { 21, };
|
||||
static int mt7629_gphy_led1_0_funcs[] = { 2, };
|
||||
static int mt7629_gphy_led2_0_pins[] = { 22, };
|
||||
static int mt7629_gphy_led2_0_funcs[] = { 2, };
|
||||
static int mt7629_gphy_led3_0_pins[] = { 23, };
|
||||
static int mt7629_gphy_led3_0_funcs[] = { 2, };
|
||||
static int mt7629_gphy_leds_1_pins[] = { 57, 58, 59, };
|
||||
static int mt7629_gphy_leds_1_funcs[] = { 1, 1, 1, };
|
||||
static int mt7629_gphy_led1_1_pins[] = { 57, };
|
||||
static int mt7629_gphy_led1_1_funcs[] = { 1, };
|
||||
static int mt7629_gphy_led2_1_pins[] = { 58, };
|
||||
static int mt7629_gphy_led2_1_funcs[] = { 1, };
|
||||
static int mt7629_gphy_led3_1_pins[] = { 59, };
|
||||
static int mt7629_gphy_led3_1_funcs[] = { 1, };
|
||||
|
||||
/* I2C */
|
||||
static int mt7629_i2c_0_pins[] = { 19, 20, };
|
||||
static int mt7629_i2c_0_funcs[] = { 1, 1, };
|
||||
static int mt7629_i2c_1_pins[] = { 53, 54, };
|
||||
static int mt7629_i2c_1_funcs[] = { 1, 1, };
|
||||
|
||||
/* SPI */
|
||||
static int mt7629_spi_0_pins[] = { 21, 22, 23, 24, };
|
||||
static int mt7629_spi_0_funcs[] = { 1, 1, 1, 1, };
|
||||
static int mt7629_spi_1_pins[] = { 62, 63, 64, 65, };
|
||||
static int mt7629_spi_1_funcs[] = { 1, 1, 1, 1, };
|
||||
static int mt7629_spi_wp_pins[] = { 66, };
|
||||
static int mt7629_spi_wp_funcs[] = { 1, };
|
||||
static int mt7629_spi_hold_pins[] = { 67, };
|
||||
static int mt7629_spi_hold_funcs[] = { 1, };
|
||||
|
||||
/* UART */
|
||||
static int mt7629_uart1_0_txd_rxd_pins[] = { 25, 26, };
|
||||
static int mt7629_uart1_0_txd_rxd_funcs[] = { 1, 1, };
|
||||
static int mt7629_uart1_1_txd_rxd_pins[] = { 53, 54, };
|
||||
static int mt7629_uart1_1_txd_rxd_funcs[] = { 2, 2, };
|
||||
static int mt7629_uart2_0_txd_rxd_pins[] = { 29, 30, };
|
||||
static int mt7629_uart2_0_txd_rxd_funcs[] = { 1, 1, };
|
||||
static int mt7629_uart2_1_txd_rxd_pins[] = { 57, 58, };
|
||||
static int mt7629_uart2_1_txd_rxd_funcs[] = { 2, 2, };
|
||||
static int mt7629_uart1_0_cts_rts_pins[] = { 27, 28, };
|
||||
static int mt7629_uart1_0_cts_rts_funcs[] = { 1, 1, };
|
||||
static int mt7629_uart1_1_cts_rts_pins[] = { 55, 56, };
|
||||
static int mt7629_uart1_1_cts_rts_funcs[] = { 2, 2, };
|
||||
static int mt7629_uart2_0_cts_rts_pins[] = { 31, 32, };
|
||||
static int mt7629_uart2_0_cts_rts_funcs[] = { 1, 1, };
|
||||
static int mt7629_uart2_1_cts_rts_pins[] = { 59, 60, };
|
||||
static int mt7629_uart2_1_cts_rts_funcs[] = { 2, 2, };
|
||||
static int mt7629_uart0_txd_rxd_pins[] = { 68, 69, };
|
||||
static int mt7629_uart0_txd_rxd_funcs[] = { 1, 1, };
|
||||
|
||||
/* MDC/MDIO */
|
||||
static int mt7629_mdc_mdio_pins[] = { 49, 50, };
|
||||
static int mt7629_mdc_mdio_funcs[] = { 1, 1, };
|
||||
|
||||
/* PCIE */
|
||||
static int mt7629_pcie_pereset_pins[] = { 51, };
|
||||
static int mt7629_pcie_pereset_funcs[] = { 1, };
|
||||
static int mt7629_pcie_wake_pins[] = { 55, };
|
||||
static int mt7629_pcie_wake_funcs[] = { 1, };
|
||||
static int mt7629_pcie_clkreq_pins[] = { 56, };
|
||||
static int mt7629_pcie_clkreq_funcs[] = { 1, };
|
||||
|
||||
/* PWM */
|
||||
static int mt7629_pwm_0_pins[] = { 52, };
|
||||
static int mt7629_pwm_0_funcs[] = { 1, };
|
||||
static int mt7629_pwm_1_pins[] = { 61, };
|
||||
static int mt7629_pwm_1_funcs[] = { 2, };
|
||||
|
||||
/* WF 2G */
|
||||
static int mt7629_wf0_2g_pins[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, };
|
||||
static int mt7629_wf0_2g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
|
||||
|
||||
/* SNFI */
|
||||
static int mt7629_snfi_pins[] = { 62, 63, 64, 65, 66, 67 };
|
||||
static int mt7629_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
|
||||
|
||||
/* SPI NOR */
|
||||
static int mt7629_snor_pins[] = { 62, 63, 64, 65, 66, 67 };
|
||||
static int mt7629_snor_funcs[] = { 1, 1, 1, 1, 1, 1 };
|
||||
|
||||
static const struct mtk_group_desc mt7629_groups[] = {
|
||||
PINCTRL_PIN_GROUP("wf0_5g", mt7629_wf0_5g),
|
||||
PINCTRL_PIN_GROUP("ephy_leds", mt7629_ephy_leds),
|
||||
PINCTRL_PIN_GROUP("ephy_led0", mt7629_ephy_led0),
|
||||
PINCTRL_PIN_GROUP("ephy_led1", mt7629_ephy_led1),
|
||||
PINCTRL_PIN_GROUP("ephy_led2", mt7629_ephy_led2),
|
||||
PINCTRL_PIN_GROUP("ephy_led3", mt7629_ephy_led3),
|
||||
PINCTRL_PIN_GROUP("ephy_led4", mt7629_ephy_led4),
|
||||
PINCTRL_PIN_GROUP("wf2g_led", mt7629_wf2g_led),
|
||||
PINCTRL_PIN_GROUP("wf5g_led", mt7629_wf5g_led),
|
||||
PINCTRL_PIN_GROUP("watchdog", mt7629_watchdog),
|
||||
PINCTRL_PIN_GROUP("gphy_leds_0", mt7629_gphy_leds_0),
|
||||
PINCTRL_PIN_GROUP("gphy_led1_0", mt7629_gphy_led1_0),
|
||||
PINCTRL_PIN_GROUP("gphy_led2_0", mt7629_gphy_led2_0),
|
||||
PINCTRL_PIN_GROUP("gphy_led3_0", mt7629_gphy_led3_0),
|
||||
PINCTRL_PIN_GROUP("gphy_leds_1", mt7629_gphy_leds_1),
|
||||
PINCTRL_PIN_GROUP("gphy_led1_1", mt7629_gphy_led1_1),
|
||||
PINCTRL_PIN_GROUP("gphy_led2_1", mt7629_gphy_led2_1),
|
||||
PINCTRL_PIN_GROUP("gphy_led3_1", mt7629_gphy_led3_1),
|
||||
PINCTRL_PIN_GROUP("i2c_0", mt7629_i2c_0),
|
||||
PINCTRL_PIN_GROUP("i2c_1", mt7629_i2c_1),
|
||||
PINCTRL_PIN_GROUP("spi_0", mt7629_spi_0),
|
||||
PINCTRL_PIN_GROUP("spi_1", mt7629_spi_1),
|
||||
PINCTRL_PIN_GROUP("spi_wp", mt7629_spi_wp),
|
||||
PINCTRL_PIN_GROUP("spi_hold", mt7629_spi_hold),
|
||||
PINCTRL_PIN_GROUP("uart1_0_txd_rxd", mt7629_uart1_0_txd_rxd),
|
||||
PINCTRL_PIN_GROUP("uart1_1_txd_rxd", mt7629_uart1_1_txd_rxd),
|
||||
PINCTRL_PIN_GROUP("uart2_0_txd_rxd", mt7629_uart2_0_txd_rxd),
|
||||
PINCTRL_PIN_GROUP("uart2_1_txd_rxd", mt7629_uart2_1_txd_rxd),
|
||||
PINCTRL_PIN_GROUP("uart1_0_cts_rts", mt7629_uart1_0_cts_rts),
|
||||
PINCTRL_PIN_GROUP("uart1_1_cts_rts", mt7629_uart1_1_cts_rts),
|
||||
PINCTRL_PIN_GROUP("uart2_0_cts_rts", mt7629_uart2_0_cts_rts),
|
||||
PINCTRL_PIN_GROUP("uart2_1_cts_rts", mt7629_uart2_1_cts_rts),
|
||||
PINCTRL_PIN_GROUP("uart0_txd_rxd", mt7629_uart0_txd_rxd),
|
||||
PINCTRL_PIN_GROUP("mdc_mdio", mt7629_mdc_mdio),
|
||||
PINCTRL_PIN_GROUP("pcie_pereset", mt7629_pcie_pereset),
|
||||
PINCTRL_PIN_GROUP("pcie_wake", mt7629_pcie_wake),
|
||||
PINCTRL_PIN_GROUP("pcie_clkreq", mt7629_pcie_clkreq),
|
||||
PINCTRL_PIN_GROUP("pwm_0", mt7629_pwm_0),
|
||||
PINCTRL_PIN_GROUP("pwm_1", mt7629_pwm_1),
|
||||
PINCTRL_PIN_GROUP("wf0_2g", mt7629_wf0_2g),
|
||||
PINCTRL_PIN_GROUP("snfi", mt7629_snfi),
|
||||
PINCTRL_PIN_GROUP("spi_nor", mt7629_snor),
|
||||
};
|
||||
|
||||
/* Joint those groups owning the same capability in user point of view which
|
||||
* allows that people tend to use through the device tree.
|
||||
*/
|
||||
static const char *const mt7629_ethernet_groups[] = { "mdc_mdio", };
|
||||
static const char *const mt7629_i2c_groups[] = { "i2c_0", "i2c_1", };
|
||||
static const char *const mt7629_led_groups[] = { "ephy_leds", "ephy_led0",
|
||||
"ephy_led1", "ephy_led2",
|
||||
"ephy_led3", "ephy_led4",
|
||||
"wf2g_led", "wf5g_led",
|
||||
"gphy_leds_0", "gphy_led1_0",
|
||||
"gphy_led2_0", "gphy_led3_0",
|
||||
"gphy_leds_1", "gphy_led1_1",
|
||||
"gphy_led2_1", "gphy_led3_1",};
|
||||
static const char *const mt7629_pcie_groups[] = { "pcie_pereset", "pcie_wake",
|
||||
"pcie_clkreq", };
|
||||
static const char *const mt7629_pwm_groups[] = { "pwm_0", "pwm_1", };
|
||||
static const char *const mt7629_spi_groups[] = { "spi_0", "spi_1", "spi_wp",
|
||||
"spi_hold", };
|
||||
static const char *const mt7629_uart_groups[] = { "uart1_0_txd_rxd",
|
||||
"uart1_1_txd_rxd",
|
||||
"uart2_0_txd_rxd",
|
||||
"uart2_1_txd_rxd",
|
||||
"uart1_0_cts_rts",
|
||||
"uart1_1_cts_rts",
|
||||
"uart2_0_cts_rts",
|
||||
"uart2_1_cts_rts",
|
||||
"uart0_txd_rxd", };
|
||||
static const char *const mt7629_wdt_groups[] = { "watchdog", };
|
||||
static const char *const mt7629_wifi_groups[] = { "wf0_5g", "wf0_2g", };
|
||||
static const char *const mt7629_flash_groups[] = { "snfi", "spi_nor" };
|
||||
|
||||
static const struct mtk_function_desc mt7629_functions[] = {
|
||||
{"eth", mt7629_ethernet_groups, ARRAY_SIZE(mt7629_ethernet_groups)},
|
||||
{"i2c", mt7629_i2c_groups, ARRAY_SIZE(mt7629_i2c_groups)},
|
||||
{"led", mt7629_led_groups, ARRAY_SIZE(mt7629_led_groups)},
|
||||
{"pcie", mt7629_pcie_groups, ARRAY_SIZE(mt7629_pcie_groups)},
|
||||
{"pwm", mt7629_pwm_groups, ARRAY_SIZE(mt7629_pwm_groups)},
|
||||
{"spi", mt7629_spi_groups, ARRAY_SIZE(mt7629_spi_groups)},
|
||||
{"uart", mt7629_uart_groups, ARRAY_SIZE(mt7629_uart_groups)},
|
||||
{"watchdog", mt7629_wdt_groups, ARRAY_SIZE(mt7629_wdt_groups)},
|
||||
{"wifi", mt7629_wifi_groups, ARRAY_SIZE(mt7629_wifi_groups)},
|
||||
{"flash", mt7629_flash_groups, ARRAY_SIZE(mt7629_flash_groups)},
|
||||
};
|
||||
|
||||
static struct mtk_pinctrl_soc mt7629_data = {
|
||||
.name = "mt7629_pinctrl",
|
||||
.reg_cal = mt7629_reg_cals,
|
||||
.pins = mt7629_pins,
|
||||
.npins = ARRAY_SIZE(mt7629_pins),
|
||||
.grps = mt7629_groups,
|
||||
.ngrps = ARRAY_SIZE(mt7629_groups),
|
||||
.funcs = mt7629_functions,
|
||||
.nfuncs = ARRAY_SIZE(mt7629_functions),
|
||||
};
|
||||
|
||||
static int mtk_pinctrl_mt7629_probe(struct udevice *dev)
|
||||
{
|
||||
return mtk_pinctrl_common_probe(dev, &mt7629_data);
|
||||
}
|
||||
|
||||
static const struct udevice_id mt7629_pctrl_match[] = {
|
||||
{ .compatible = "mediatek,mt7629-pinctrl" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mt7629_pinctrl) = {
|
||||
.name = "mt7629_pinctrl",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = mt7629_pctrl_match,
|
||||
.ops = &mtk_pinctrl_ops,
|
||||
.probe = mtk_pinctrl_mt7629_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_pinctrl_priv),
|
||||
};
|
553
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
Normal file
553
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
Normal file
@ -0,0 +1,553 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#include "pinctrl-mtk-common.h"
|
||||
|
||||
/**
|
||||
* struct mtk_drive_desc - the structure that holds the information
|
||||
* of the driving current
|
||||
* @min: the minimum current of this group
|
||||
* @max: the maximum current of this group
|
||||
* @step: the step current of this group
|
||||
* @scal: the weight factor
|
||||
*
|
||||
* formula: output = ((input) / step - 1) * scal
|
||||
*/
|
||||
struct mtk_drive_desc {
|
||||
u8 min;
|
||||
u8 max;
|
||||
u8 step;
|
||||
u8 scal;
|
||||
};
|
||||
|
||||
/* The groups of drive strength */
|
||||
static const struct mtk_drive_desc mtk_drive[] = {
|
||||
[DRV_GRP0] = { 4, 16, 4, 1 },
|
||||
[DRV_GRP1] = { 4, 16, 4, 2 },
|
||||
[DRV_GRP2] = { 2, 8, 2, 1 },
|
||||
[DRV_GRP3] = { 2, 8, 2, 2 },
|
||||
[DRV_GRP4] = { 2, 16, 2, 1 },
|
||||
};
|
||||
|
||||
static const char *mtk_pinctrl_dummy_name = "_dummy";
|
||||
|
||||
static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
__raw_writel(val, priv->base + reg);
|
||||
}
|
||||
|
||||
static u32 mtk_r32(struct udevice *dev, u32 reg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return __raw_readl(priv->base + reg);
|
||||
}
|
||||
|
||||
static inline int get_count_order(unsigned int count)
|
||||
{
|
||||
int order;
|
||||
|
||||
order = fls(count) - 1;
|
||||
if (count & (count - 1))
|
||||
order++;
|
||||
return order;
|
||||
}
|
||||
|
||||
void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = mtk_r32(dev, reg);
|
||||
val &= ~mask;
|
||||
val |= set;
|
||||
mtk_w32(dev, reg, val);
|
||||
}
|
||||
|
||||
static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
|
||||
const struct mtk_pin_reg_calc *rc,
|
||||
struct mtk_pin_field *pfd)
|
||||
{
|
||||
const struct mtk_pin_field_calc *c, *e;
|
||||
u32 bits;
|
||||
|
||||
c = rc->range;
|
||||
e = c + rc->nranges;
|
||||
|
||||
while (c < e) {
|
||||
if (pin >= c->s_pin && pin <= c->e_pin)
|
||||
break;
|
||||
c++;
|
||||
}
|
||||
|
||||
if (c >= e)
|
||||
return -EINVAL;
|
||||
|
||||
/* Calculated bits as the overall offset the pin is located at,
|
||||
* if c->fixed is held, that determines the all the pins in the
|
||||
* range use the same field with the s_pin.
|
||||
*/
|
||||
bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
|
||||
|
||||
/* Fill pfd from bits. For example 32-bit register applied is assumed
|
||||
* when c->sz_reg is equal to 32.
|
||||
*/
|
||||
pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
|
||||
pfd->bitpos = bits % c->sz_reg;
|
||||
pfd->mask = (1 << c->x_bits) - 1;
|
||||
|
||||
/* pfd->next is used for indicating that bit wrapping-around happens
|
||||
* which requires the manipulation for bit 0 starting in the next
|
||||
* register to form the complete field read/write.
|
||||
*/
|
||||
pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
|
||||
int field, struct mtk_pin_field *pfd)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtk_pin_reg_calc *rc;
|
||||
|
||||
if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
|
||||
rc = &priv->soc->reg_cal[field];
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
|
||||
}
|
||||
|
||||
static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
|
||||
{
|
||||
*l = 32 - pf->bitpos;
|
||||
*h = get_count_order(pf->mask) - *l;
|
||||
}
|
||||
|
||||
static void mtk_hw_write_cross_field(struct udevice *dev,
|
||||
struct mtk_pin_field *pf, int value)
|
||||
{
|
||||
int nbits_l, nbits_h;
|
||||
|
||||
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
|
||||
|
||||
mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
|
||||
(value & pf->mask) << pf->bitpos);
|
||||
|
||||
mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
|
||||
(value & pf->mask) >> nbits_l);
|
||||
}
|
||||
|
||||
static void mtk_hw_read_cross_field(struct udevice *dev,
|
||||
struct mtk_pin_field *pf, int *value)
|
||||
{
|
||||
int nbits_l, nbits_h, h, l;
|
||||
|
||||
mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
|
||||
|
||||
l = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
|
||||
h = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
|
||||
|
||||
*value = (h << nbits_l) | l;
|
||||
}
|
||||
|
||||
static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
|
||||
int value)
|
||||
{
|
||||
struct mtk_pin_field pf;
|
||||
int err;
|
||||
|
||||
err = mtk_hw_pin_field_get(dev, pin, field, &pf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!pf.next)
|
||||
mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
|
||||
(value & pf.mask) << pf.bitpos);
|
||||
else
|
||||
mtk_hw_write_cross_field(dev, &pf, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
|
||||
int *value)
|
||||
{
|
||||
struct mtk_pin_field pf;
|
||||
int err;
|
||||
|
||||
err = mtk_hw_pin_field_get(dev, pin, field, &pf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!pf.next)
|
||||
*value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
|
||||
else
|
||||
mtk_hw_read_cross_field(dev, &pf, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->soc->ngrps;
|
||||
}
|
||||
|
||||
static const char *mtk_get_pin_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (!priv->soc->grps[selector].name)
|
||||
return mtk_pinctrl_dummy_name;
|
||||
|
||||
return priv->soc->pins[selector].name;
|
||||
}
|
||||
|
||||
static int mtk_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->soc->npins;
|
||||
}
|
||||
|
||||
static const char *mtk_get_group_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (!priv->soc->grps[selector].name)
|
||||
return mtk_pinctrl_dummy_name;
|
||||
|
||||
return priv->soc->grps[selector].name;
|
||||
}
|
||||
|
||||
static int mtk_get_functions_count(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->soc->nfuncs;
|
||||
}
|
||||
|
||||
static const char *mtk_get_function_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (!priv->soc->funcs[selector].name)
|
||||
return mtk_pinctrl_dummy_name;
|
||||
|
||||
return priv->soc->funcs[selector].name;
|
||||
}
|
||||
|
||||
static int mtk_pinmux_group_set(struct udevice *dev,
|
||||
unsigned int group_selector,
|
||||
unsigned int func_selector)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtk_group_desc *grp =
|
||||
&priv->soc->grps[group_selector];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < grp->num_pins; i++) {
|
||||
int *pin_modes = grp->data;
|
||||
|
||||
mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
|
||||
pin_modes[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
static const struct pinconf_param mtk_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 },
|
||||
{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
|
||||
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
|
||||
{ "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
|
||||
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
|
||||
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
|
||||
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
|
||||
};
|
||||
|
||||
int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
|
||||
const struct mtk_drive_desc *tb;
|
||||
int err = -ENOTSUPP;
|
||||
|
||||
tb = &mtk_drive[desc->drv_n];
|
||||
/* 4mA when (e8, e4) = (0, 0)
|
||||
* 8mA when (e8, e4) = (0, 1)
|
||||
* 12mA when (e8, e4) = (1, 0)
|
||||
* 16mA when (e8, e4) = (1, 1)
|
||||
*/
|
||||
if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
|
||||
arg = (arg / tb->step - 1) * tb->scal;
|
||||
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
|
||||
unsigned int param, unsigned int arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
|
||||
(param == PIN_CONFIG_BIAS_PULL_UP) ? 3 : 2;
|
||||
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
|
||||
arg & 1);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN,
|
||||
!!(arg & 2));
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
|
||||
if (err)
|
||||
goto err;
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
/* arg = 1: Input mode & SMT enable ;
|
||||
* arg = 0: Output mode & SMT disable
|
||||
*/
|
||||
arg = arg ? 2 : 1;
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
|
||||
arg & 1);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
|
||||
!!(arg & 2));
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
err = mtk_pinconf_drive_set(dev, pin, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = -ENOTSUPP;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mtk_pinconf_group_set(struct udevice *dev,
|
||||
unsigned int group_selector,
|
||||
unsigned int param, unsigned int arg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtk_group_desc *grp =
|
||||
&priv->soc->grps[group_selector];
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < grp->num_pins; i++) {
|
||||
ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct pinctrl_ops mtk_pinctrl_ops = {
|
||||
.get_pins_count = mtk_get_pins_count,
|
||||
.get_pin_name = mtk_get_pin_name,
|
||||
.get_groups_count = mtk_get_groups_count,
|
||||
.get_group_name = mtk_get_group_name,
|
||||
.get_functions_count = mtk_get_functions_count,
|
||||
.get_function_name = mtk_get_function_name,
|
||||
.pinmux_group_set = mtk_pinmux_group_set,
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
.pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
|
||||
.pinconf_params = mtk_conf_params,
|
||||
.pinconf_set = mtk_pinconf_set,
|
||||
.pinconf_group_set = mtk_pinconf_group_set,
|
||||
#endif
|
||||
.set_state = pinctrl_generic_set_state,
|
||||
};
|
||||
|
||||
static int mtk_gpio_get(struct udevice *dev, unsigned int off)
|
||||
{
|
||||
int val, err;
|
||||
|
||||
err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return !!val;
|
||||
}
|
||||
|
||||
static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
|
||||
{
|
||||
return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
|
||||
}
|
||||
|
||||
static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
|
||||
{
|
||||
int val, err;
|
||||
|
||||
err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return val ? GPIOF_OUTPUT : GPIOF_INPUT;
|
||||
}
|
||||
|
||||
static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
|
||||
{
|
||||
return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
|
||||
}
|
||||
|
||||
static int mtk_gpio_direction_output(struct udevice *dev,
|
||||
unsigned int off, int val)
|
||||
{
|
||||
mtk_gpio_set(dev, off, val);
|
||||
|
||||
/* And set the requested value */
|
||||
return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
|
||||
}
|
||||
|
||||
static int mtk_gpio_request(struct udevice *dev, unsigned int off,
|
||||
const char *label)
|
||||
{
|
||||
return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE, 0);
|
||||
}
|
||||
|
||||
static int mtk_gpio_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
|
||||
struct gpio_dev_priv *uc_priv;
|
||||
|
||||
uc_priv = dev_get_uclass_priv(dev);
|
||||
uc_priv->bank_name = priv->soc->name;
|
||||
uc_priv->gpio_count = priv->soc->npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_gpio_ops mtk_gpio_ops = {
|
||||
.request = mtk_gpio_request,
|
||||
.set_value = mtk_gpio_set,
|
||||
.get_value = mtk_gpio_get,
|
||||
.get_function = mtk_gpio_get_direction,
|
||||
.direction_input = mtk_gpio_direction_input,
|
||||
.direction_output = mtk_gpio_direction_output,
|
||||
};
|
||||
|
||||
static struct driver mtk_gpio_driver = {
|
||||
.name = "mediatek_gpio",
|
||||
.id = UCLASS_GPIO,
|
||||
.probe = mtk_gpio_probe,
|
||||
.ops = &mtk_gpio_ops,
|
||||
};
|
||||
|
||||
static int mtk_gpiochip_register(struct udevice *parent)
|
||||
{
|
||||
struct uclass_driver *drv;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
ofnode node;
|
||||
|
||||
drv = lists_uclass_lookup(UCLASS_GPIO);
|
||||
if (!drv)
|
||||
return -ENOENT;
|
||||
|
||||
dev_for_each_subnode(node, parent)
|
||||
if (ofnode_read_bool(node, "gpio-controller")) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
|
||||
"mediatek_gpio", 0, node,
|
||||
&dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinctrl_common_probe(struct udevice *dev,
|
||||
struct mtk_pinctrl_soc *soc)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (priv->base == (void *)FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->soc = soc;
|
||||
|
||||
ret = mtk_gpiochip_register(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
184
drivers/pinctrl/mediatek/pinctrl-mtk-common.h
Normal file
184
drivers/pinctrl/mediatek/pinctrl-mtk-common.h
Normal file
@ -0,0 +1,184 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_MEDIATEK_H__
|
||||
#define __PINCTRL_MEDIATEK_H__
|
||||
|
||||
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
|
||||
#define MTK_PIN(_number, _name, _drv_n) { \
|
||||
.number = _number, \
|
||||
.name = _name, \
|
||||
.drv_n = _drv_n, \
|
||||
}
|
||||
|
||||
#define PINCTRL_PIN_GROUP(name, id) \
|
||||
{ \
|
||||
name, \
|
||||
id##_pins, \
|
||||
ARRAY_SIZE(id##_pins), \
|
||||
id##_funcs, \
|
||||
}
|
||||
|
||||
#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, _sz_reg, _fixed) { \
|
||||
.s_pin = _s_pin, \
|
||||
.e_pin = _e_pin, \
|
||||
.s_addr = _s_addr, \
|
||||
.x_addrs = _x_addrs, \
|
||||
.s_bit = _s_bit, \
|
||||
.x_bits = _x_bits, \
|
||||
.sz_reg = _sz_reg, \
|
||||
.fixed = _fixed, \
|
||||
}
|
||||
|
||||
/* List these attributes which could be modified for the pin */
|
||||
enum {
|
||||
PINCTRL_PIN_REG_MODE,
|
||||
PINCTRL_PIN_REG_DIR,
|
||||
PINCTRL_PIN_REG_DI,
|
||||
PINCTRL_PIN_REG_DO,
|
||||
PINCTRL_PIN_REG_IES,
|
||||
PINCTRL_PIN_REG_SMT,
|
||||
PINCTRL_PIN_REG_PULLEN,
|
||||
PINCTRL_PIN_REG_PULLSEL,
|
||||
PINCTRL_PIN_REG_DRV,
|
||||
PINCTRL_PIN_REG_MAX,
|
||||
};
|
||||
|
||||
/* Group the pins by the driving current */
|
||||
enum {
|
||||
DRV_FIXED,
|
||||
DRV_GRP0,
|
||||
DRV_GRP1,
|
||||
DRV_GRP2,
|
||||
DRV_GRP3,
|
||||
DRV_GRP4,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_field - the structure that holds the information of the field
|
||||
* used to describe the attribute for the pin
|
||||
* @offset: the register offset relative to the base address
|
||||
* @mask: the mask used to filter out the field from the register
|
||||
* @bitpos: the start bit relative to the register
|
||||
* @next: the indication that the field would be extended to the
|
||||
next register
|
||||
*/
|
||||
struct mtk_pin_field {
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u8 bitpos;
|
||||
u8 next;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_field_calc - the structure that holds the range providing
|
||||
* the guide used to look up the relevant field
|
||||
* @s_pin: the start pin within the range
|
||||
* @e_pin: the end pin within the range
|
||||
* @s_addr: the start address for the range
|
||||
* @x_addrs: the address distance between two consecutive registers
|
||||
* within the range
|
||||
* @s_bit: the start bit for the first register within the range
|
||||
* @x_bits: the bit distance between two consecutive pins within
|
||||
* the range
|
||||
* @sz_reg: the size of bits in a register
|
||||
* @fixed: the consecutive pins share the same bits with the 1st
|
||||
* pin
|
||||
*/
|
||||
struct mtk_pin_field_calc {
|
||||
u16 s_pin;
|
||||
u16 e_pin;
|
||||
u32 s_addr;
|
||||
u8 x_addrs;
|
||||
u8 s_bit;
|
||||
u8 x_bits;
|
||||
u8 sz_reg;
|
||||
u8 fixed;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_reg_calc - the structure that holds all ranges used to
|
||||
* determine which register the pin would make use of
|
||||
* for certain pin attribute.
|
||||
* @range: the start address for the range
|
||||
* @nranges: the number of items in the range
|
||||
*/
|
||||
struct mtk_pin_reg_calc {
|
||||
const struct mtk_pin_field_calc *range;
|
||||
unsigned int nranges;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_desc - the structure that providing information
|
||||
* for each pin of chips
|
||||
* @number: unique pin number from the global pin number space
|
||||
* @name: name for this pin
|
||||
* @drv_n: the index with the driving group
|
||||
*/
|
||||
struct mtk_pin_desc {
|
||||
unsigned int number;
|
||||
const char *name;
|
||||
u8 drv_n;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_group_desc - generic pin group descriptor
|
||||
* @name: name of the pin group
|
||||
* @pins: array of pins that belong to the group
|
||||
* @num_pins: number of pins in the group
|
||||
* @data: pin controller driver specific data
|
||||
*/
|
||||
struct mtk_group_desc {
|
||||
const char *name;
|
||||
int *pins;
|
||||
int num_pins;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_function_desc - generic function descriptor
|
||||
* @name: name of the function
|
||||
* @group_names: array of pin group names
|
||||
* @num_group_names: number of pin group names
|
||||
*/
|
||||
struct mtk_function_desc {
|
||||
const char *name;
|
||||
const char * const *group_names;
|
||||
int num_group_names;
|
||||
};
|
||||
|
||||
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
|
||||
struct mtk_pinctrl_soc {
|
||||
const char *name;
|
||||
const struct mtk_pin_reg_calc *reg_cal;
|
||||
const struct mtk_pin_desc *pins;
|
||||
int npins;
|
||||
const struct mtk_group_desc *grps;
|
||||
int ngrps;
|
||||
const struct mtk_function_desc *funcs;
|
||||
int nfuncs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pinctrl_priv - private data for MTK pinctrl driver
|
||||
*
|
||||
* @base: base address of the pinctrl device
|
||||
* @soc: SoC specific data
|
||||
*/
|
||||
struct mtk_pinctrl_priv {
|
||||
void __iomem *base;
|
||||
struct mtk_pinctrl_soc *soc;
|
||||
};
|
||||
|
||||
extern const struct pinctrl_ops mtk_pinctrl_ops;
|
||||
|
||||
/* A common read-modify-write helper for MediaTek chips */
|
||||
void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set);
|
||||
int mtk_pinctrl_common_probe(struct udevice *dev,
|
||||
struct mtk_pinctrl_soc *soc);
|
||||
|
||||
#endif /* __PINCTRL_MEDIATEK_H__ */
|
@ -23,6 +23,13 @@ config IMX8_POWER_DOMAIN
|
||||
Enable support for manipulating NXP i.MX8 on-SoC power domains via IPC
|
||||
requests to the SCU.
|
||||
|
||||
config MTK_POWER_DOMAIN
|
||||
bool "Enable the MediaTek power domain driver"
|
||||
depends on POWER_DOMAIN && ARCH_MEDIATEK
|
||||
help
|
||||
Enable support for manipulating MediaTek power domains via MMIO
|
||||
mapped registers.
|
||||
|
||||
config MESON_GX_VPU_POWER_DOMAIN
|
||||
bool "Enable Amlogic Meson GX VPU power domain driver"
|
||||
depends on ARCH_MESON
|
||||
|
@ -6,6 +6,7 @@
|
||||
obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
|
||||
obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
|
||||
obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain.o
|
||||
obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
|
||||
obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
|
||||
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
|
||||
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
|
||||
|
406
drivers/power/domain/mtk-power-domain.c
Normal file
406
drivers/power/domain/mtk-power-domain.c
Normal file
@ -0,0 +1,406 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <power-domain-uclass.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include <dt-bindings/power/mt7623-power.h>
|
||||
#include <dt-bindings/power/mt7629-power.h>
|
||||
|
||||
#define SPM_EN (0xb16 << 16 | 0x1)
|
||||
#define SPM_VDE_PWR_CON 0x0210
|
||||
#define SPM_MFG_PWR_CON 0x0214
|
||||
#define SPM_ISP_PWR_CON 0x0238
|
||||
#define SPM_DIS_PWR_CON 0x023c
|
||||
#define SPM_CONN_PWR_CON 0x0280
|
||||
#define SPM_BDP_PWR_CON 0x029c
|
||||
#define SPM_ETH_PWR_CON 0x02a0
|
||||
#define SPM_HIF_PWR_CON 0x02a4
|
||||
#define SPM_IFR_MSC_PWR_CON 0x02a8
|
||||
#define SPM_ETHSYS_PWR_CON 0x2e0
|
||||
#define SPM_HIF0_PWR_CON 0x2e4
|
||||
#define SPM_HIF1_PWR_CON 0x2e8
|
||||
#define SPM_PWR_STATUS 0x60c
|
||||
#define SPM_PWR_STATUS_2ND 0x610
|
||||
|
||||
#define PWR_RST_B_BIT BIT(0)
|
||||
#define PWR_ISO_BIT BIT(1)
|
||||
#define PWR_ON_BIT BIT(2)
|
||||
#define PWR_ON_2ND_BIT BIT(3)
|
||||
#define PWR_CLK_DIS_BIT BIT(4)
|
||||
|
||||
#define PWR_STATUS_CONN BIT(1)
|
||||
#define PWR_STATUS_DISP BIT(3)
|
||||
#define PWR_STATUS_MFG BIT(4)
|
||||
#define PWR_STATUS_ISP BIT(5)
|
||||
#define PWR_STATUS_VDEC BIT(7)
|
||||
#define PWR_STATUS_BDP BIT(14)
|
||||
#define PWR_STATUS_ETH BIT(15)
|
||||
#define PWR_STATUS_HIF BIT(16)
|
||||
#define PWR_STATUS_IFR_MSC BIT(17)
|
||||
#define PWR_STATUS_ETHSYS BIT(24)
|
||||
#define PWR_STATUS_HIF0 BIT(25)
|
||||
#define PWR_STATUS_HIF1 BIT(26)
|
||||
|
||||
/* Infrasys configuration */
|
||||
#define INFRA_TOPDCM_CTRL 0x10
|
||||
#define INFRA_TOPAXI_PROT_EN 0x220
|
||||
#define INFRA_TOPAXI_PROT_STA1 0x228
|
||||
|
||||
#define DCM_TOP_EN BIT(0)
|
||||
|
||||
enum scp_domain_type {
|
||||
SCPSYS_MT7623,
|
||||
SCPSYS_MT7629,
|
||||
};
|
||||
|
||||
struct scp_domain;
|
||||
|
||||
struct scp_domain_data {
|
||||
struct scp_domain *scpd;
|
||||
u32 sta_mask;
|
||||
int ctl_offs;
|
||||
u32 sram_pdn_bits;
|
||||
u32 sram_pdn_ack_bits;
|
||||
u32 bus_prot_mask;
|
||||
};
|
||||
|
||||
struct scp_domain {
|
||||
void __iomem *base;
|
||||
void __iomem *infracfg;
|
||||
enum scp_domain_type type;
|
||||
struct scp_domain_data *data;
|
||||
};
|
||||
|
||||
static struct scp_domain_data scp_domain_mt7623[] = {
|
||||
[MT7623_POWER_DOMAIN_CONN] = {
|
||||
.sta_mask = PWR_STATUS_CONN,
|
||||
.ctl_offs = SPM_CONN_PWR_CON,
|
||||
.bus_prot_mask = BIT(8) | BIT(2),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_DISP] = {
|
||||
.sta_mask = PWR_STATUS_DISP,
|
||||
.ctl_offs = SPM_DIS_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.bus_prot_mask = BIT(2),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_MFG] = {
|
||||
.sta_mask = PWR_STATUS_MFG,
|
||||
.ctl_offs = SPM_MFG_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_VDEC] = {
|
||||
.sta_mask = PWR_STATUS_VDEC,
|
||||
.ctl_offs = SPM_VDE_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_ISP] = {
|
||||
.sta_mask = PWR_STATUS_ISP,
|
||||
.ctl_offs = SPM_ISP_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_BDP] = {
|
||||
.sta_mask = PWR_STATUS_BDP,
|
||||
.ctl_offs = SPM_BDP_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_ETH] = {
|
||||
.sta_mask = PWR_STATUS_ETH,
|
||||
.ctl_offs = SPM_ETH_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_HIF] = {
|
||||
.sta_mask = PWR_STATUS_HIF,
|
||||
.ctl_offs = SPM_HIF_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT7623_POWER_DOMAIN_IFR_MSC] = {
|
||||
.sta_mask = PWR_STATUS_IFR_MSC,
|
||||
.ctl_offs = SPM_IFR_MSC_PWR_CON,
|
||||
},
|
||||
};
|
||||
|
||||
static struct scp_domain_data scp_domain_mt7629[] = {
|
||||
[MT7629_POWER_DOMAIN_ETHSYS] = {
|
||||
.sta_mask = PWR_STATUS_ETHSYS,
|
||||
.ctl_offs = SPM_ETHSYS_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.bus_prot_mask = (BIT(3) | BIT(17)),
|
||||
},
|
||||
[MT7629_POWER_DOMAIN_HIF0] = {
|
||||
.sta_mask = PWR_STATUS_HIF0,
|
||||
.ctl_offs = SPM_HIF0_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.bus_prot_mask = GENMASK(25, 24),
|
||||
},
|
||||
[MT7629_POWER_DOMAIN_HIF1] = {
|
||||
.sta_mask = PWR_STATUS_HIF1,
|
||||
.ctl_offs = SPM_HIF1_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.bus_prot_mask = GENMASK(28, 26),
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* This function enables the bus protection bits for disabled power
|
||||
* domains so that the system does not hang when some unit accesses the
|
||||
* bus while in power down.
|
||||
*/
|
||||
static int mtk_infracfg_set_bus_protection(void __iomem *infracfg,
|
||||
u32 mask)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
clrsetbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask, mask);
|
||||
|
||||
return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
|
||||
(val & mask) == mask, 100);
|
||||
}
|
||||
|
||||
static int mtk_infracfg_clear_bus_protection(void __iomem *infracfg,
|
||||
u32 mask)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
clrbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask);
|
||||
|
||||
return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
|
||||
!(val & mask), 100);
|
||||
}
|
||||
|
||||
static int scpsys_domain_is_on(struct scp_domain_data *data)
|
||||
{
|
||||
struct scp_domain *scpd = data->scpd;
|
||||
u32 sta = readl(scpd->base + SPM_PWR_STATUS) &
|
||||
data->sta_mask;
|
||||
u32 sta2 = readl(scpd->base + SPM_PWR_STATUS_2ND) &
|
||||
data->sta_mask;
|
||||
|
||||
/*
|
||||
* A domain is on when both status bits are set. If only one is set
|
||||
* return an error. This happens while powering up a domain
|
||||
*/
|
||||
if (sta && sta2)
|
||||
return true;
|
||||
if (!sta && !sta2)
|
||||
return false;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int scpsys_power_on(struct power_domain *power_domain)
|
||||
{
|
||||
struct scp_domain *scpd = dev_get_priv(power_domain->dev);
|
||||
struct scp_domain_data *data = &scpd->data[power_domain->id];
|
||||
void __iomem *ctl_addr = scpd->base + data->ctl_offs;
|
||||
u32 pdn_ack = data->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret, tmp;
|
||||
|
||||
writel(SPM_EN, scpd->base);
|
||||
|
||||
val = readl(ctl_addr);
|
||||
val |= PWR_ON_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val |= PWR_ON_2ND_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, tmp > 0,
|
||||
100);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val &= ~PWR_CLK_DIS_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~PWR_ISO_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val |= PWR_RST_B_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
ret = readl_poll_timeout(ctl_addr, tmp, !(tmp & pdn_ack), 100);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (data->bus_prot_mask) {
|
||||
ret = mtk_infracfg_clear_bus_protection(scpd->infracfg,
|
||||
data->bus_prot_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_power_off(struct power_domain *power_domain)
|
||||
{
|
||||
struct scp_domain *scpd = dev_get_priv(power_domain->dev);
|
||||
struct scp_domain_data *data = &scpd->data[power_domain->id];
|
||||
void __iomem *ctl_addr = scpd->base + data->ctl_offs;
|
||||
u32 pdn_ack = data->sram_pdn_ack_bits;
|
||||
u32 val;
|
||||
int ret, tmp;
|
||||
|
||||
if (data->bus_prot_mask) {
|
||||
ret = mtk_infracfg_set_bus_protection(scpd->infracfg,
|
||||
data->bus_prot_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl(ctl_addr);
|
||||
val |= data->sram_pdn_bits;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
|
||||
100);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val |= PWR_ISO_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~PWR_RST_B_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val |= PWR_CLK_DIS_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~PWR_ON_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
val &= ~PWR_ON_2ND_BIT;
|
||||
writel(val, ctl_addr);
|
||||
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, !tmp, 100);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_power_request(struct power_domain *power_domain)
|
||||
{
|
||||
struct scp_domain *scpd = dev_get_priv(power_domain->dev);
|
||||
struct scp_domain_data *data;
|
||||
|
||||
data = &scpd->data[power_domain->id];
|
||||
data->scpd = scpd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_power_free(struct power_domain *power_domain)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_power_domain_hook(struct udevice *dev)
|
||||
{
|
||||
struct scp_domain *scpd = dev_get_priv(dev);
|
||||
|
||||
scpd->type = (enum scp_domain_type)dev_get_driver_data(dev);
|
||||
|
||||
switch (scpd->type) {
|
||||
case SCPSYS_MT7623:
|
||||
scpd->data = scp_domain_mt7623;
|
||||
break;
|
||||
case SCPSYS_MT7629:
|
||||
scpd->data = scp_domain_mt7629;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_power_domain_probe(struct udevice *dev)
|
||||
{
|
||||
struct ofnode_phandle_args args;
|
||||
struct scp_domain *scpd = dev_get_priv(dev);
|
||||
struct regmap *regmap;
|
||||
struct clk_bulk bulk;
|
||||
int err;
|
||||
|
||||
scpd->base = dev_read_addr_ptr(dev);
|
||||
if (!scpd->base)
|
||||
return -ENOENT;
|
||||
|
||||
err = mtk_power_domain_hook(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* get corresponding syscon phandle */
|
||||
err = dev_read_phandle_with_args(dev, "infracfg", NULL, 0, 0, &args);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
regmap = syscon_node_to_regmap(args.node);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
scpd->infracfg = regmap_get_range(regmap, 0);
|
||||
if (!scpd->infracfg)
|
||||
return -ENOENT;
|
||||
|
||||
/* enable Infra DCM */
|
||||
setbits_le32(scpd->infracfg + INFRA_TOPDCM_CTRL, DCM_TOP_EN);
|
||||
|
||||
err = clk_get_bulk(dev, &bulk);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return clk_enable_bulk(&bulk);
|
||||
}
|
||||
|
||||
static const struct udevice_id mtk_power_domain_ids[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7623-scpsys",
|
||||
.data = SCPSYS_MT7623,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt7629-scpsys",
|
||||
.data = SCPSYS_MT7629,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
struct power_domain_ops mtk_power_domain_ops = {
|
||||
.free = scpsys_power_free,
|
||||
.off = scpsys_power_off,
|
||||
.on = scpsys_power_on,
|
||||
.request = scpsys_power_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_power_domain) = {
|
||||
.name = "mtk_power_domain",
|
||||
.id = UCLASS_POWER_DOMAIN,
|
||||
.ops = &mtk_power_domain_ops,
|
||||
.probe = mtk_power_domain_probe,
|
||||
.of_match = mtk_power_domain_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct scp_domain),
|
||||
};
|
@ -13,3 +13,4 @@ obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
|
||||
obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
|
7
drivers/ram/mediatek/Makefile
Normal file
7
drivers/ram/mediatek/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# Copyright (c) 2018 MediaTek Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
|
||||
obj-$(CONFIG_TARGET_MT7629) = ddr3-mt7629.o
|
766
drivers/ram/mediatek/ddr3-mt7629.c
Normal file
766
drivers/ram/mediatek/ddr3-mt7629.c
Normal file
@ -0,0 +1,766 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek DDR3 driver for MT7629 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Wu Zou <wu.zou@mediatek.com>
|
||||
* Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* EMI */
|
||||
#define EMI_CONA 0x000
|
||||
#define EMI_CONF 0x028
|
||||
#define EMI_CONM 0x060
|
||||
|
||||
/* DDR PHY */
|
||||
#define DDRPHY_PLL1 0x0000
|
||||
#define DDRPHY_PLL2 0x0004
|
||||
#define DDRPHY_PLL3 0x0008
|
||||
#define DDRPHY_PLL4 0x000c
|
||||
#define DDRPHY_PLL5 0x0010
|
||||
#define DDRPHY_PLL7 0x0018
|
||||
#define DDRPHY_B0_DLL_ARPI0 0x0080
|
||||
#define DDRPHY_B0_DLL_ARPI1 0x0084
|
||||
#define DDRPHY_B0_DLL_ARPI2 0x0088
|
||||
#define DDRPHY_B0_DLL_ARPI3 0x008c
|
||||
#define DDRPHY_B0_DLL_ARPI4 0x0090
|
||||
#define DDRPHY_B0_DLL_ARPI5 0x0094
|
||||
#define DDRPHY_B0_DQ2 0x00a0
|
||||
#define DDRPHY_B0_DQ3 0x00a4
|
||||
#define DDRPHY_B0_DQ4 0x00a8
|
||||
#define DDRPHY_B0_DQ5 0x00ac
|
||||
#define DDRPHY_B0_DQ6 0x00b0
|
||||
#define DDRPHY_B0_DQ7 0x00b4
|
||||
#define DDRPHY_B0_DQ8 0x00b8
|
||||
#define DDRPHY_B1_DLL_ARPI0 0x0100
|
||||
#define DDRPHY_B1_DLL_ARPI1 0x0104
|
||||
#define DDRPHY_B1_DLL_ARPI2 0x0108
|
||||
#define DDRPHY_B1_DLL_ARPI3 0x010c
|
||||
#define DDRPHY_B1_DLL_ARPI4 0x0110
|
||||
#define DDRPHY_B1_DLL_ARPI5 0x0114
|
||||
#define DDRPHY_B1_DQ2 0x0120
|
||||
#define DDRPHY_B1_DQ3 0x0124
|
||||
#define DDRPHY_B1_DQ4 0x0128
|
||||
#define DDRPHY_B1_DQ5 0x012c
|
||||
#define DDRPHY_B1_DQ6 0x0130
|
||||
#define DDRPHY_B1_DQ7 0x0134
|
||||
#define DDRPHY_B1_DQ8 0x0138
|
||||
#define DDRPHY_CA_DLL_ARPI0 0x0180
|
||||
#define DDRPHY_CA_DLL_ARPI1 0x0184
|
||||
#define DDRPHY_CA_DLL_ARPI2 0x0188
|
||||
#define DDRPHY_CA_DLL_ARPI3 0x018c
|
||||
#define DDRPHY_CA_DLL_ARPI4 0x0190
|
||||
#define DDRPHY_CA_DLL_ARPI5 0x0194
|
||||
#define DDRPHY_CA_CMD2 0x01a0
|
||||
#define DDRPHY_CA_CMD3 0x01a4
|
||||
#define DDRPHY_CA_CMD5 0x01ac
|
||||
#define DDRPHY_CA_CMD6 0x01b0
|
||||
#define DDRPHY_CA_CMD7 0x01b4
|
||||
#define DDRPHY_CA_CMD8 0x01b8
|
||||
#define DDRPHY_MISC_VREF_CTRL 0x0264
|
||||
#define DDRPHY_MISC_IMP_CTRL0 0x0268
|
||||
#define DDRPHY_MISC_IMP_CTRL1 0x026c
|
||||
#define DDRPHY_MISC_SHU_OPT 0x0270
|
||||
#define DDRPHY_MISC_SPM_CTRL0 0x0274
|
||||
#define DDRPHY_MISC_SPM_CTRL1 0x0278
|
||||
#define DDRPHY_MISC_SPM_CTRL2 0x027c
|
||||
#define DDRPHY_MISC_CG_CTRL0 0x0284
|
||||
#define DDRPHY_MISC_CG_CTRL1 0x0288
|
||||
#define DDRPHY_MISC_CG_CTRL2 0x028c
|
||||
#define DDRPHY_MISC_CG_CTRL4 0x0294
|
||||
#define DDRPHY_MISC_CTRL0 0x029c
|
||||
#define DDRPHY_MISC_CTRL1 0x02a0
|
||||
#define DDRPHY_MISC_CTRL3 0x02a8
|
||||
#define DDRPHY_MISC_RXDVS1 0x05e4
|
||||
#define DDRPHY_SHU1_B0_DQ4 0x0c10
|
||||
#define DDRPHY_SHU1_B0_DQ5 0x0c14
|
||||
#define DDRPHY_SHU1_B0_DQ6 0x0c18
|
||||
#define DDRPHY_SHU1_B0_DQ7 0x0c1c
|
||||
#define DDRPHY_SHU1_B1_DQ4 0x0c90
|
||||
#define DDRPHY_SHU1_B1_DQ5 0x0c94
|
||||
#define DDRPHY_SHU1_B1_DQ6 0x0c98
|
||||
#define DDRPHY_SHU1_B1_DQ7 0x0c9c
|
||||
#define DDRPHY_SHU1_CA_CMD2 0x0d08
|
||||
#define DDRPHY_SHU1_CA_CMD4 0x0d10
|
||||
#define DDRPHY_SHU1_CA_CMD5 0x0d14
|
||||
#define DDRPHY_SHU1_CA_CMD6 0x0d18
|
||||
#define DDRPHY_SHU1_CA_CMD7 0x0d1c
|
||||
#define DDRPHY_SHU1_PLL0 0x0d80
|
||||
#define DDRPHY_SHU1_PLL1 0x0d84
|
||||
#define DDRPHY_SHU1_PLL4 0x0d90
|
||||
#define DDRPHY_SHU1_PLL5 0x0d94
|
||||
#define DDRPHY_SHU1_PLL6 0x0d98
|
||||
#define DDRPHY_SHU1_PLL7 0x0d9C
|
||||
#define DDRPHY_SHU1_PLL8 0x0da0
|
||||
#define DDRPHY_SHU1_PLL9 0x0da4
|
||||
#define DDRPHY_SHU1_PLL10 0x0da8
|
||||
#define DDRPHY_SHU1_PLL11 0x0dac
|
||||
#define DDRPHY_SHU1_R0_B0_DQ2 0x0e08
|
||||
#define DDRPHY_SHU1_R0_B0_DQ3 0x0e0c
|
||||
#define DDRPHY_SHU1_R0_B0_DQ4 0x0e10
|
||||
#define DDRPHY_SHU1_R0_B0_DQ5 0x0e14
|
||||
#define DDRPHY_SHU1_R0_B0_DQ6 0x0e18
|
||||
#define DDRPHY_SHU1_R0_B0_DQ7 0x0e1c
|
||||
#define DDRPHY_SHU1_R0_B1_DQ2 0x0e58
|
||||
#define DDRPHY_SHU1_R0_B1_DQ3 0x0e5c
|
||||
#define DDRPHY_SHU1_R0_B1_DQ4 0x0e60
|
||||
#define DDRPHY_SHU1_R0_B1_DQ5 0x0e64
|
||||
#define DDRPHY_SHU1_R0_B1_DQ6 0x0e68
|
||||
#define DDRPHY_SHU1_R0_B1_DQ7 0x0e6c
|
||||
#define DDRPHY_SHU1_R0_CA_CMD9 0x0ec4
|
||||
#define DDRPHY_SHU1_R1_B0_DQ2 0x0f08
|
||||
#define DDRPHY_SHU1_R1_B0_DQ3 0x0f0c
|
||||
#define DDRPHY_SHU1_R1_B0_DQ4 0x0f10
|
||||
#define DDRPHY_SHU1_R1_B0_DQ5 0x0f14
|
||||
#define DDRPHY_SHU1_R1_B0_DQ6 0x0f18
|
||||
#define DDRPHY_SHU1_R1_B0_DQ7 0x0f1c
|
||||
#define DDRPHY_SHU1_R1_B1_DQ2 0x0f58
|
||||
#define DDRPHY_SHU1_R1_B1_DQ3 0x0f5c
|
||||
#define DDRPHY_SHU1_R1_B1_DQ4 0x0f60
|
||||
#define DDRPHY_SHU1_R1_B1_DQ5 0x0f64
|
||||
#define DDRPHY_SHU1_R1_B1_DQ6 0x0f68
|
||||
#define DDRPHY_SHU1_R1_B1_DQ7 0x0f6c
|
||||
#define DDRPHY_SHU1_R1_CA_CMD9 0x0fc4
|
||||
|
||||
/* DRAMC */
|
||||
#define DRAMC_DDRCONF0 0x0000
|
||||
#define DRAMC_DRAMCTRL 0x0004
|
||||
#define DRAMC_MISCTL0 0x0008
|
||||
#define DRAMC_PERFCTL0 0x000c
|
||||
#define DRAMC_ARBCTL 0x0010
|
||||
#define DRAMC_RSTMASK 0x001c
|
||||
#define DRAMC_PADCTRL 0x0020
|
||||
#define DRAMC_CKECTRL 0x0024
|
||||
#define DRAMC_RKCFG 0x0034
|
||||
#define DRAMC_DRAMC_PD_CTRL 0x0038
|
||||
#define DRAMC_CLKAR 0x003c
|
||||
#define DRAMC_CLKCTRL 0x0040
|
||||
#define DRAMC_SREFCTRL 0x0048
|
||||
#define DRAMC_REFCTRL0 0x004c
|
||||
#define DRAMC_REFCTRL1 0x0050
|
||||
#define DRAMC_REFRATRE_FILTER 0x0054
|
||||
#define DRAMC_ZQCS 0x0058
|
||||
#define DRAMC_MRS 0x005c
|
||||
#define DRAMC_SPCMD 0x0060
|
||||
#define DRAMC_SPCMDCTRL 0x0064
|
||||
#define DRAMC_HW_MRR_FUN 0x0074
|
||||
#define DRAMC_TEST2_1 0x0094
|
||||
#define DRAMC_TEST2_2 0x0098
|
||||
#define DRAMC_TEST2_3 0x009c
|
||||
#define DRAMC_TEST2_4 0x00a0
|
||||
#define DRAMC_CATRAINING1 0x00b0
|
||||
#define DRAMC_DUMMY_RD 0x00d0
|
||||
#define DRAMC_SHUCTRL 0x00d4
|
||||
#define DRAMC_SHUCTRL2 0x00dc
|
||||
#define DRAMC_STBCAL 0x0200
|
||||
#define DRAMC_STBCAL1 0x0204
|
||||
#define DRAMC_EYESCAN 0x020c
|
||||
#define DRAMC_DVFSDLL 0x0210
|
||||
#define DRAMC_SHU_ACTIM0 0x0800
|
||||
#define DRAMC_SHU_ACTIM1 0x0804
|
||||
#define DRAMC_SHU_ACTIM2 0x0808
|
||||
#define DRAMC_SHU_ACTIM3 0x080c
|
||||
#define DRAMC_SHU_ACTIM4 0x0810
|
||||
#define DRAMC_SHU_ACTIM5 0x0814
|
||||
#define DRAMC_SHU_ACTIM_XRT 0x081c
|
||||
#define DRAMC_SHU_AC_TIME_05T 0x0820
|
||||
#define DRAMC_SHU_CONF0 0x0840
|
||||
#define DRAMC_SHU_CONF1 0x0844
|
||||
#define DRAMC_SHU_CONF2 0x0848
|
||||
#define DRAMC_SHU_CONF3 0x084c
|
||||
#define DRAMC_SHU_RANKCTL 0x0858
|
||||
#define DRAMC_SHU_CKECTRL 0x085c
|
||||
#define DRAMC_SHU_ODTCTRL 0x0860
|
||||
#define DRAMC_SHU_PIPE 0x0878
|
||||
#define DRAMC_SHU_SELPH_CA1 0x0880
|
||||
#define DRAMC_SHU_SELPH_CA2 0x0884
|
||||
#define DRAMC_SHU_SELPH_CA3 0x0888
|
||||
#define DRAMC_SHU_SELPH_CA4 0x088c
|
||||
#define DRAMC_SHU_SELPH_CA5 0x0890
|
||||
#define DRAMC_SHU_SELPH_CA6 0x0894
|
||||
#define DRAMC_SHU_SELPH_CA7 0x0898
|
||||
#define DRAMC_SHU_SELPH_CA8 0x089c
|
||||
#define DRAMC_SHU_SELPH_DQS0 0x08a0
|
||||
#define DRAMC_SHU_SELPH_DQS1 0x08a4
|
||||
#define DRAMC_SHU1_DRVING1 0x08a8
|
||||
#define DRAMC_SHU1_DRVING2 0x08ac
|
||||
#define DRAMC_SHU1_WODT 0x08c0
|
||||
#define DRAMC_SHU_SCINTV 0x08c8
|
||||
#define DRAMC_SHURK0_DQSCTL 0x0a00
|
||||
#define DRAMC_SHURK0_DQSIEN 0x0a04
|
||||
#define DRAMC_SHURK0_SELPH_ODTEN0 0x0a1c
|
||||
#define DRAMC_SHURK0_SELPH_ODTEN1 0x0a20
|
||||
#define DRAMC_SHURK0_SELPH_DQSG0 0x0a24
|
||||
#define DRAMC_SHURK0_SELPH_DQSG1 0x0a28
|
||||
#define DRAMC_SHURK0_SELPH_DQ0 0x0a2c
|
||||
#define DRAMC_SHURK0_SELPH_DQ1 0x0a30
|
||||
#define DRAMC_SHURK0_SELPH_DQ2 0x0a34
|
||||
#define DRAMC_SHURK0_SELPH_DQ3 0x0a38
|
||||
#define DRAMC_SHURK1_DQSCTL 0x0b00
|
||||
#define DRAMC_SHURK1_SELPH_ODTEN0 0x0b1c
|
||||
#define DRAMC_SHURK1_SELPH_ODTEN1 0x0b20
|
||||
#define DRAMC_SHURK1_SELPH_DQSG0 0x0b24
|
||||
#define DRAMC_SHURK1_SELPH_DQSG1 0x0b28
|
||||
#define DRAMC_SHURK1_SELPH_DQ0 0x0b2c
|
||||
#define DRAMC_SHURK1_SELPH_DQ1 0x0b30
|
||||
#define DRAMC_SHURK1_SELPH_DQ2 0x0b34
|
||||
#define DRAMC_SHURK1_SELPH_DQ3 0x0b38
|
||||
#define DRAMC_SHURK2_SELPH_ODTEN0 0x0c1c
|
||||
#define DRAMC_SHURK2_SELPH_ODTEN1 0x0c20
|
||||
#define DRAMC_SHU_DQSG_RETRY 0x0c54
|
||||
|
||||
#define EMI_COL_ADDR_MASK GENMASK(13, 12)
|
||||
#define EMI_COL_ADDR_SHIFT 12
|
||||
#define WALKING_PATTERN 0x12345678
|
||||
#define WALKING_STEP 0x4000000
|
||||
|
||||
struct mtk_ddr3_priv {
|
||||
fdt_addr_t emi;
|
||||
fdt_addr_t ddrphy;
|
||||
fdt_addr_t dramc_ao;
|
||||
struct clk phy;
|
||||
struct clk phy_mux;
|
||||
struct clk mem;
|
||||
struct clk mem_mux;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
static int mtk_ddr3_rank_size_detect(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
int step;
|
||||
u32 start, test;
|
||||
|
||||
/* To detect size, we have to make sure it's single rank
|
||||
* and it has maximum addressing region
|
||||
*/
|
||||
|
||||
writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE);
|
||||
|
||||
if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN)
|
||||
return -EINVAL;
|
||||
|
||||
for (step = 0; step < 5; step++) {
|
||||
writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE +
|
||||
(WALKING_STEP << step));
|
||||
|
||||
start = readl(CONFIG_SYS_SDRAM_BASE);
|
||||
test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step));
|
||||
if ((test != ~WALKING_PATTERN) || test == start)
|
||||
break;
|
||||
}
|
||||
|
||||
step = step ? step - 1 : 3;
|
||||
clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK,
|
||||
step << EMI_COL_ADDR_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ddr3_init(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_set_parent(&priv->phy, &priv->phy_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* EMI Setting */
|
||||
writel(0x00003010, priv->emi + EMI_CONA);
|
||||
writel(0x00000000, priv->emi + EMI_CONF);
|
||||
writel(0x000006b8, priv->emi + EMI_CONM);
|
||||
/* DQS */
|
||||
writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1);
|
||||
/* Clock */
|
||||
writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2);
|
||||
|
||||
/* DDRPHY setting */
|
||||
writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
|
||||
writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5);
|
||||
writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2);
|
||||
writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2);
|
||||
writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
|
||||
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7);
|
||||
writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
|
||||
writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1);
|
||||
writel(0x10, priv->ddrphy + DDRPHY_PLL3);
|
||||
writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL);
|
||||
writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0);
|
||||
writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
|
||||
writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
|
||||
udelay(1);
|
||||
|
||||
writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1);
|
||||
writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4);
|
||||
writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4);
|
||||
writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3);
|
||||
writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6);
|
||||
writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2);
|
||||
writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1);
|
||||
writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
|
||||
writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT);
|
||||
writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
|
||||
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_PLL4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_PLL1);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_PLL2);
|
||||
writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
|
||||
writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
|
||||
writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11);
|
||||
writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10);
|
||||
writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4);
|
||||
writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6);
|
||||
|
||||
writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5);
|
||||
writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7);
|
||||
|
||||
writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5);
|
||||
writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7);
|
||||
writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8);
|
||||
writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10);
|
||||
writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1);
|
||||
writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4);
|
||||
writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1);
|
||||
writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1);
|
||||
writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1);
|
||||
writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3);
|
||||
writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3);
|
||||
writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4);
|
||||
writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
writel(0x80010000, priv->ddrphy + DDRPHY_PLL1);
|
||||
writel(0x80000000, priv->ddrphy + DDRPHY_PLL2);
|
||||
udelay(100);
|
||||
|
||||
writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0xd0000, priv->ddrphy + DDRPHY_PLL4);
|
||||
udelay(1);
|
||||
|
||||
writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
udelay(1);
|
||||
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
|
||||
writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x80000000, priv->ddrphy + DDRPHY_PLL1);
|
||||
udelay(1);
|
||||
|
||||
writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
ret = clk_set_parent(&priv->mem, &priv->mem_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* DDR PHY PLL setting */
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8);
|
||||
writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7);
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
|
||||
/* Update initial setting */
|
||||
writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6);
|
||||
writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6);
|
||||
writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6);
|
||||
writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8);
|
||||
writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
|
||||
writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
|
||||
writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR);
|
||||
writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
|
||||
/* Dramc setting PC3 */
|
||||
writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
|
||||
writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
|
||||
writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY);
|
||||
writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2);
|
||||
writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL);
|
||||
writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0);
|
||||
writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0);
|
||||
writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL);
|
||||
writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL);
|
||||
writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE);
|
||||
writel(0x731004, priv->dramc_ao + DRAMC_RKCFG);
|
||||
writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2);
|
||||
writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL);
|
||||
writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1);
|
||||
writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER);
|
||||
|
||||
/* Update PCDDR3 default setting */
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4);
|
||||
writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5);
|
||||
writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0);
|
||||
writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1);
|
||||
writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
|
||||
writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
|
||||
writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0);
|
||||
writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6);
|
||||
writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL);
|
||||
writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0);
|
||||
writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1);
|
||||
writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2);
|
||||
writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3);
|
||||
writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4);
|
||||
writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5);
|
||||
writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT);
|
||||
writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T);
|
||||
writel(0x80010000, priv->ddrphy + DDRPHY_PLL2);
|
||||
udelay(500);
|
||||
|
||||
writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0);
|
||||
writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0x80, priv->dramc_ao + DRAMC_ARBCTL);
|
||||
writel(0x9, priv->dramc_ao + DRAMC_PADCTRL);
|
||||
writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
|
||||
writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x731414, priv->dramc_ao + DRAMC_RKCFG);
|
||||
writel(0x733414, priv->dramc_ao + DRAMC_RKCFG);
|
||||
udelay(20);
|
||||
|
||||
writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL);
|
||||
udelay(100);
|
||||
|
||||
writel(0x400000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x401800, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x601800, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x600000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x200000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x200400, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x400, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1d7000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x10, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x20, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN);
|
||||
writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
|
||||
writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3);
|
||||
writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL);
|
||||
writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
|
||||
writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1);
|
||||
writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1);
|
||||
writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2);
|
||||
writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3);
|
||||
writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2);
|
||||
writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL);
|
||||
writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD);
|
||||
writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4);
|
||||
writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_RSTMASK);
|
||||
writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL);
|
||||
writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
|
||||
/* Apply config before calibration */
|
||||
writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
|
||||
writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3);
|
||||
writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
|
||||
writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT);
|
||||
writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
|
||||
writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
|
||||
/* Write leveling */
|
||||
writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
|
||||
|
||||
/* RX dqs gating cal */
|
||||
writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
|
||||
writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
|
||||
writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN);
|
||||
|
||||
/* RX window per-bit cal */
|
||||
writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
|
||||
writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
|
||||
writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
|
||||
writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
|
||||
writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
|
||||
writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
|
||||
writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
|
||||
writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
|
||||
|
||||
/* RX datlat cal */
|
||||
writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
|
||||
/* TX window per-byte with 2UI cal */
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
|
||||
writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
|
||||
writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
|
||||
writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
|
||||
return mtk_ddr3_rank_size_detect(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mtk_ddr3_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->emi = dev_read_addr_index(dev, 0);
|
||||
if (priv->emi == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->ddrphy = dev_read_addr_index(dev, 1);
|
||||
if (priv->ddrphy == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->dramc_ao = dev_read_addr_index(dev, 2);
|
||||
if (priv->dramc_ao == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
int ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 1, &priv->phy_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 2, &priv->mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 3, &priv->mem_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mtk_ddr3_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
u32 val = readl(priv->emi + EMI_CONA);
|
||||
|
||||
info->base = CONFIG_SYS_SDRAM_BASE;
|
||||
|
||||
switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) {
|
||||
case 0:
|
||||
info->size = SZ_128M;
|
||||
break;
|
||||
case 1:
|
||||
info->size = SZ_256M;
|
||||
break;
|
||||
case 2:
|
||||
info->size = SZ_512M;
|
||||
break;
|
||||
case 3:
|
||||
info->size = SZ_1G;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops mtk_ddr3_ops = {
|
||||
.get_info = mtk_ddr3_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id mtk_ddr3_ids[] = {
|
||||
{ .compatible = "mediatek,mt7629-dramc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mediatek_ddr3) = {
|
||||
.name = "mediatek_ddr3",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = mtk_ddr3_ids,
|
||||
.ops = &mtk_ddr3_ops,
|
||||
.probe = mtk_ddr3_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_ddr3_priv),
|
||||
};
|
@ -368,6 +368,16 @@ config DEBUG_UART_OMAP
|
||||
You will need to provide parameters to make this work. The driver
|
||||
will be available until the real driver model serial is running.
|
||||
|
||||
config DEBUG_UART_MTK
|
||||
bool "MediaTek High-speed UART"
|
||||
depends on MTK_SERIAL
|
||||
help
|
||||
Select this to enable a debug UART using the MediaTek High-speed
|
||||
UART driver.
|
||||
You will need to provide parameters to make this work. The
|
||||
driver will be available until the real driver model serial is
|
||||
running.
|
||||
|
||||
endchoice
|
||||
|
||||
config DEBUG_UART_BASE
|
||||
@ -698,6 +708,16 @@ config ZYNQ_SERIAL
|
||||
This driver supports the Cadence UART. It is found e.g. in Xilinx
|
||||
Zynq/ZynqMP.
|
||||
|
||||
config MTK_SERIAL
|
||||
bool "MediaTek High-speed UART support"
|
||||
depends on DM_SERIAL
|
||||
help
|
||||
Select this to enable UART support for MediaTek High-speed UART
|
||||
devices. This driver uses driver model and requires a device
|
||||
tree binding to operate.
|
||||
The High-speed UART is compatible with the ns16550a UART and have
|
||||
its own high-speed registers.
|
||||
|
||||
config MPC8XX_CONS
|
||||
bool "Console driver for MPC8XX"
|
||||
depends on MPC8xx
|
||||
|
@ -67,6 +67,7 @@ obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
|
||||
obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
|
||||
obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
|
||||
obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
|
||||
obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_USB_TTY) += usbtty.o
|
||||
|
268
drivers/serial/serial_mtk.c
Normal file
268
drivers/serial/serial_mtk.c
Normal file
@ -0,0 +1,268 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek High-speed UART driver
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <serial.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
struct mtk_serial_regs {
|
||||
u32 rbr;
|
||||
u32 ier;
|
||||
u32 fcr;
|
||||
u32 lcr;
|
||||
u32 mcr;
|
||||
u32 lsr;
|
||||
u32 msr;
|
||||
u32 spr;
|
||||
u32 mdr1;
|
||||
u32 highspeed;
|
||||
u32 sample_count;
|
||||
u32 sample_point;
|
||||
u32 fracdiv_l;
|
||||
u32 fracdiv_m;
|
||||
u32 escape_en;
|
||||
u32 guard;
|
||||
u32 rx_sel;
|
||||
};
|
||||
|
||||
#define thr rbr
|
||||
#define iir fcr
|
||||
#define dll rbr
|
||||
#define dlm ier
|
||||
|
||||
#define UART_LCR_WLS_8 0x03 /* 8 bit character length */
|
||||
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
|
||||
|
||||
#define UART_LSR_DR 0x01 /* Data ready */
|
||||
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
|
||||
|
||||
/* the data is correct if the real baud is within 3%. */
|
||||
#define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100)
|
||||
#define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100)
|
||||
|
||||
struct mtk_serial_priv {
|
||||
struct mtk_serial_regs __iomem *regs;
|
||||
u32 clock;
|
||||
};
|
||||
|
||||
static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
|
||||
{
|
||||
bool support_clk12m_baud115200;
|
||||
u32 quot, samplecount, realbaud;
|
||||
|
||||
if ((baud <= 115200) && (priv->clock == 12000000))
|
||||
support_clk12m_baud115200 = true;
|
||||
else
|
||||
support_clk12m_baud115200 = false;
|
||||
|
||||
if (baud <= 115200) {
|
||||
writel(0, &priv->regs->highspeed);
|
||||
quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
|
||||
|
||||
if (support_clk12m_baud115200) {
|
||||
writel(3, &priv->regs->highspeed);
|
||||
quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
|
||||
if (quot == 0)
|
||||
quot = 1;
|
||||
|
||||
samplecount = DIV_ROUND_CLOSEST(priv->clock,
|
||||
quot * baud);
|
||||
if (samplecount != 0) {
|
||||
realbaud = priv->clock / samplecount / quot;
|
||||
if ((realbaud > BAUD_ALLOW_MAX(baud)) ||
|
||||
(realbaud < BAUD_ALLOW_MIX(baud))) {
|
||||
pr_info("baud %d can't be handled\n",
|
||||
baud);
|
||||
}
|
||||
} else {
|
||||
pr_info("samplecount is 0\n");
|
||||
}
|
||||
}
|
||||
} else if (baud <= 576000) {
|
||||
writel(2, &priv->regs->highspeed);
|
||||
|
||||
/* Set to next lower baudrate supported */
|
||||
if ((baud == 500000) || (baud == 576000))
|
||||
baud = 460800;
|
||||
quot = DIV_ROUND_UP(priv->clock, 4 * baud);
|
||||
} else {
|
||||
writel(3, &priv->regs->highspeed);
|
||||
quot = DIV_ROUND_UP(priv->clock, 256 * baud);
|
||||
}
|
||||
|
||||
/* set divisor */
|
||||
writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr);
|
||||
writel(quot & 0xff, &priv->regs->dll);
|
||||
writel((quot >> 8) & 0xff, &priv->regs->dlm);
|
||||
writel(UART_LCR_WLS_8, &priv->regs->lcr);
|
||||
|
||||
if (baud > 460800) {
|
||||
u32 tmp;
|
||||
|
||||
tmp = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
|
||||
writel(tmp - 1, &priv->regs->sample_count);
|
||||
writel((tmp - 2) >> 1, &priv->regs->sample_point);
|
||||
} else {
|
||||
writel(0, &priv->regs->sample_count);
|
||||
writel(0xff, &priv->regs->sample_point);
|
||||
}
|
||||
|
||||
if (support_clk12m_baud115200) {
|
||||
writel(samplecount - 1, &priv->regs->sample_count);
|
||||
writel((samplecount - 2) >> 1, &priv->regs->sample_point);
|
||||
}
|
||||
}
|
||||
|
||||
static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
struct mtk_serial_priv *priv = dev_get_priv(dev);
|
||||
|
||||
_mtk_serial_setbrg(priv, baudrate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int mtk_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_serial_priv *priv = dev_get_priv(dev);
|
||||
|
||||
/* Disable interrupt */
|
||||
writel(0, &priv->regs->ier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct mtk_serial_priv *priv = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
struct clk clk;
|
||||
int err;
|
||||
|
||||
addr = dev_read_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
|
||||
|
||||
err = clk_get_by_index(dev, 0, &clk);
|
||||
if (!err) {
|
||||
err = clk_get_rate(&clk);
|
||||
if (!IS_ERR_VALUE(err))
|
||||
priv->clock = err;
|
||||
} else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
|
||||
debug("mtk_serial: failed to get clock\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!priv->clock)
|
||||
priv->clock = dev_read_u32_default(dev, "clock-frequency", 0);
|
||||
|
||||
if (!priv->clock) {
|
||||
debug("mtk_serial: clock not defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_serial_ops mtk_serial_ops = {
|
||||
.putc = mtk_serial_putc,
|
||||
.pending = mtk_serial_pending,
|
||||
.getc = mtk_serial_getc,
|
||||
.setbrg = mtk_serial_setbrg,
|
||||
};
|
||||
|
||||
static const struct udevice_id mtk_serial_ids[] = {
|
||||
{ .compatible = "mediatek,hsuart" },
|
||||
{ .compatible = "mediatek,mt6577-uart" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_mtk) = {
|
||||
.name = "serial_mtk",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = mtk_serial_ids,
|
||||
.ofdata_to_platdata = mtk_serial_ofdata_to_platdata,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_serial_priv),
|
||||
.probe = mtk_serial_probe,
|
||||
.ops = &mtk_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART_MTK
|
||||
|
||||
#include <debug_uart.h>
|
||||
|
||||
static inline void _debug_uart_init(void)
|
||||
{
|
||||
struct mtk_serial_priv priv;
|
||||
|
||||
priv.regs = (void *) CONFIG_DEBUG_UART_BASE;
|
||||
priv.clock = CONFIG_DEBUG_UART_CLOCK;
|
||||
|
||||
writel(0, &priv.regs->ier);
|
||||
|
||||
_mtk_serial_setbrg(&priv, CONFIG_BAUDRATE);
|
||||
}
|
||||
|
||||
static inline void _debug_uart_putc(int ch)
|
||||
{
|
||||
struct mtk_serial_regs __iomem *regs =
|
||||
(void *) CONFIG_DEBUG_UART_BASE;
|
||||
|
||||
while (!(readl(®s->lsr) & UART_LSR_THRE))
|
||||
;
|
||||
|
||||
writel(ch, ®s->thr);
|
||||
}
|
||||
|
||||
DEBUG_UART_FUNCS
|
||||
|
||||
#endif
|
@ -160,4 +160,11 @@ config X86_TSC_TIMER
|
||||
help
|
||||
Select this to enable Time-Stamp Counter (TSC) timer for x86.
|
||||
|
||||
config MTK_TIMER
|
||||
bool "MediaTek timer support"
|
||||
depends on TIMER
|
||||
help
|
||||
Select this to enable support for the timer found on
|
||||
MediaTek devices.
|
||||
|
||||
endmenu
|
||||
|
@ -18,3 +18,4 @@ obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
|
||||
obj-$(CONFIG_STI_TIMER) += sti-timer.o
|
||||
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
|
||||
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
|
||||
obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
|
||||
|
85
drivers/timer/mtk_timer.c
Normal file
85
drivers/timer/mtk_timer.c
Normal file
@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek timer driver
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <timer.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define MTK_GPT4_CTRL 0x40
|
||||
#define MTK_GPT4_CLK 0x44
|
||||
#define MTK_GPT4_CNT 0x48
|
||||
|
||||
#define GPT4_ENABLE BIT(0)
|
||||
#define GPT4_CLEAR BIT(1)
|
||||
#define GPT4_FREERUN GENMASK(5, 4)
|
||||
#define GPT4_CLK_SYS 0x0
|
||||
#define GPT4_CLK_DIV1 0x0
|
||||
|
||||
struct mtk_timer_priv {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int mtk_timer_get_count(struct udevice *dev, u64 *count)
|
||||
{
|
||||
struct mtk_timer_priv *priv = dev_get_priv(dev);
|
||||
u32 val = readl(priv->base + MTK_GPT4_CNT);
|
||||
|
||||
*count = timer_conv_64(val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_timer_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct mtk_timer_priv *priv = dev_get_priv(dev);
|
||||
struct clk clk, parent;
|
||||
int ret;
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 1, &parent);
|
||||
if (!ret) {
|
||||
ret = clk_set_parent(&clk, &parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uc_priv->clock_rate = clk_get_rate(&clk);
|
||||
if (!uc_priv->clock_rate)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct timer_ops mtk_timer_ops = {
|
||||
.get_count = mtk_timer_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id mtk_timer_ids[] = {
|
||||
{ .compatible = "mediatek,timer" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_timer) = {
|
||||
.name = "mtk_timer",
|
||||
.id = UCLASS_TIMER,
|
||||
.of_match = mtk_timer_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_timer_priv),
|
||||
.probe = mtk_timer_probe,
|
||||
.ops = &mtk_timer_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
@ -103,6 +103,14 @@ config WDT_CDNS
|
||||
Select this to enable Cadence watchdog timer, which can be found on some
|
||||
Xilinx Microzed Platform.
|
||||
|
||||
config WDT_MTK
|
||||
bool "MediaTek watchdog timer support"
|
||||
depends on WDT && ARCH_MEDIATEK
|
||||
help
|
||||
Select this to enable watchdog timer for MediaTek SoCs.
|
||||
The watchdog timer is stopped when initialized.
|
||||
It performs full SoC reset.
|
||||
|
||||
config XILINX_TB_WATCHDOG
|
||||
bool "Xilinx Axi watchdog timer support"
|
||||
depends on WDT
|
||||
|
@ -24,3 +24,4 @@ obj-$(CONFIG_WDT_ORION) += orion_wdt.o
|
||||
obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
|
||||
obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o
|
||||
obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
|
||||
obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
|
||||
|
135
drivers/watchdog/mtk_wdt.c
Normal file
135
drivers/watchdog/mtk_wdt.c
Normal file
@ -0,0 +1,135 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Watchdog driver for MediaTek SoCs
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <wdt.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define MTK_WDT_MODE 0x00
|
||||
#define MTK_WDT_LENGTH 0x04
|
||||
#define MTK_WDT_RESTART 0x08
|
||||
#define MTK_WDT_STATUS 0x0c
|
||||
#define MTK_WDT_INTERVAL 0x10
|
||||
#define MTK_WDT_SWRST 0x14
|
||||
#define MTK_WDT_REQ_MODE 0x30
|
||||
#define MTK_WDT_DEBUG_CTL 0x40
|
||||
|
||||
#define WDT_MODE_KEY (0x22 << 24)
|
||||
#define WDT_MODE_EN BIT(0)
|
||||
#define WDT_MODE_EXTPOL BIT(1)
|
||||
#define WDT_MODE_EXTEN BIT(2)
|
||||
#define WDT_MODE_IRQ_EN BIT(3)
|
||||
#define WDT_MODE_DUAL_EN BIT(6)
|
||||
|
||||
#define WDT_LENGTH_KEY 0x8
|
||||
#define WDT_LENGTH_TIMEOUT(n) ((n) << 5)
|
||||
|
||||
#define WDT_RESTART_KEY 0x1971
|
||||
#define WDT_SWRST_KEY 0x1209
|
||||
|
||||
struct mtk_wdt_priv {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int mtk_wdt_reset(struct udevice *dev)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
/* Reload watchdog duration */
|
||||
writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_wdt_stop(struct udevice *dev)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
clrsetbits_le32(priv->base + MTK_WDT_MODE, WDT_MODE_EN, WDT_MODE_KEY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_wdt_expire_now(struct udevice *dev, ulong flags)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
/* Kick watchdog to prevent counter == 0 */
|
||||
writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
|
||||
|
||||
/* Reset */
|
||||
writel(WDT_SWRST_KEY, priv->base + MTK_WDT_SWRST);
|
||||
hang();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_wdt_set_timeout(struct udevice *dev, unsigned int timeout)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
/*
|
||||
* One bit is the value of 512 ticks
|
||||
* The clock has 32 KHz
|
||||
*/
|
||||
timeout = WDT_LENGTH_TIMEOUT(timeout << 6) | WDT_LENGTH_KEY;
|
||||
writel(timeout, priv->base + MTK_WDT_LENGTH);
|
||||
|
||||
mtk_wdt_reset(dev);
|
||||
}
|
||||
|
||||
static int mtk_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
mtk_wdt_set_timeout(dev, timeout);
|
||||
|
||||
/* Enable watchdog reset signal */
|
||||
setbits_le32(priv->base + MTK_WDT_MODE,
|
||||
WDT_MODE_EN | WDT_MODE_KEY | WDT_MODE_EXTEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_wdt_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_wdt_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
/* Clear status */
|
||||
clrsetbits_le32(priv->base + MTK_WDT_MODE,
|
||||
WDT_MODE_IRQ_EN | WDT_MODE_EXTPOL, WDT_MODE_KEY);
|
||||
|
||||
return mtk_wdt_stop(dev);
|
||||
}
|
||||
|
||||
static const struct wdt_ops mtk_wdt_ops = {
|
||||
.start = mtk_wdt_start,
|
||||
.reset = mtk_wdt_reset,
|
||||
.stop = mtk_wdt_stop,
|
||||
.expire_now = mtk_wdt_expire_now,
|
||||
};
|
||||
|
||||
static const struct udevice_id mtk_wdt_ids[] = {
|
||||
{ .compatible = "mediatek,wdt"},
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mtk_wdt) = {
|
||||
.name = "mtk_wdt",
|
||||
.id = UCLASS_WDT,
|
||||
.of_match = mtk_wdt_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_wdt_priv),
|
||||
.probe = mtk_wdt_probe,
|
||||
.ops = &mtk_wdt_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
56
include/configs/mt7623.h
Normal file
56
include/configs/mt7623.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Configuration for MediaTek MT7623 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef __MT7623_H
|
||||
#define __MT7623_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SETUP_MEMORY_TAGS
|
||||
#define CONFIG_INITRD_TAG
|
||||
#define CONFIG_CMDLINE_TAG
|
||||
|
||||
#define CONFIG_SYS_MAXARGS 8
|
||||
#define CONFIG_SYS_BOOTM_LEN SZ_64M
|
||||
#define CONFIG_SYS_CBSIZE SZ_1K
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN SZ_4M
|
||||
|
||||
/* Environment */
|
||||
#define CONFIG_ENV_SIZE SZ_4K
|
||||
/* Allow to overwrite serial and ethaddr */
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
|
||||
/* Preloader -> Uboot */
|
||||
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
|
||||
GENERATED_GBL_DATA_SIZE)
|
||||
|
||||
/* UBoot -> Kernel */
|
||||
#define CONFIG_LOADADDR 0x84000000
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
|
||||
/* MMC */
|
||||
#define MMC_SUPPORTS_TUNING
|
||||
#define CONFIG_SUPPORT_EMMC_BOOT
|
||||
|
||||
/* DRAM */
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x80000000
|
||||
|
||||
/* This is neede for kernel booting */
|
||||
#define FDT_HIGH "fdt_high=0xac000000\0"
|
||||
|
||||
/* Extra environment variables */
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
FDT_HIGH
|
||||
|
||||
#endif
|
57
include/configs/mt7629.h
Normal file
57
include/configs/mt7629.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Configuration for MediaTek MT7629 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef __MT7629_H
|
||||
#define __MT7629_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SETUP_MEMORY_TAGS
|
||||
#define CONFIG_INITRD_TAG
|
||||
#define CONFIG_CMDLINE_TAG
|
||||
|
||||
#define CONFIG_SYS_MAXARGS 8
|
||||
#define CONFIG_SYS_BOOTM_LEN SZ_64M
|
||||
#define CONFIG_SYS_CBSIZE SZ_1K
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN SZ_4M
|
||||
|
||||
/* Environment */
|
||||
#define CONFIG_ENV_SIZE SZ_4K
|
||||
/* Allow to overwrite serial and ethaddr */
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
|
||||
/* Defines for SPL */
|
||||
#define CONFIG_SPL_STACK 0x106000
|
||||
#define CONFIG_SPL_TEXT_BASE 0x201000
|
||||
#define CONFIG_SPL_MAX_SIZE SZ_64K
|
||||
#define CONFIG_SPL_MAX_FOOTPRINT SZ_64K
|
||||
#define CONFIG_SPL_PAD_TO 0x10000
|
||||
|
||||
#define CONFIG_SPI_ADDR 0x30000000
|
||||
#define CONFIG_SYS_SPI_U_BOOT_OFFS CONFIG_SPL_PAD_TO
|
||||
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
|
||||
|
||||
/* SPL -> Uboot */
|
||||
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
|
||||
GENERATED_GBL_DATA_SIZE)
|
||||
|
||||
/* UBoot -> Kernel */
|
||||
#define CONFIG_SYS_SPL_ARGS_ADDR 0x40000000
|
||||
#define CONFIG_LOADADDR 0x42007f1c
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
|
||||
/* DRAM */
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||
|
||||
#endif
|
413
include/dt-bindings/clock/mt7623-clk.h
Normal file
413
include/dt-bindings/clock/mt7623-clk.h
Normal file
@ -0,0 +1,413 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT2701_H
|
||||
#define _DT_BINDINGS_CLK_MT2701_H
|
||||
|
||||
/* TOPCKGEN */
|
||||
#define CLK_TOP_FCLKS_OFF 0
|
||||
|
||||
#define CLK_TOP_DPI 0
|
||||
#define CLK_TOP_DMPLL 1
|
||||
#define CLK_TOP_VENCPLL 2
|
||||
#define CLK_TOP_HDMI_0_PIX340M 3
|
||||
#define CLK_TOP_HDMI_0_DEEP340M 4
|
||||
#define CLK_TOP_HDMI_0_PLL340M 5
|
||||
#define CLK_TOP_HADDS2_FB 6
|
||||
#define CLK_TOP_WBG_DIG_416M 7
|
||||
#define CLK_TOP_DSI0_LNTC_DSI 8
|
||||
#define CLK_TOP_HDMI_SCL_RX 9
|
||||
#define CLK_TOP_32K_EXTERNAL 10
|
||||
#define CLK_TOP_HDMITX_CLKDIG_CTS 11
|
||||
#define CLK_TOP_AUD_EXT1 12
|
||||
#define CLK_TOP_AUD_EXT2 13
|
||||
#define CLK_TOP_NFI1X_PAD 14
|
||||
|
||||
#define CLK_TOP_SYSPLL 15
|
||||
#define CLK_TOP_SYSPLL_D2 16
|
||||
#define CLK_TOP_SYSPLL_D3 17
|
||||
#define CLK_TOP_SYSPLL_D5 18
|
||||
#define CLK_TOP_SYSPLL_D7 19
|
||||
#define CLK_TOP_SYSPLL1_D2 20
|
||||
#define CLK_TOP_SYSPLL1_D4 21
|
||||
#define CLK_TOP_SYSPLL1_D8 22
|
||||
#define CLK_TOP_SYSPLL1_D16 23
|
||||
#define CLK_TOP_SYSPLL2_D2 24
|
||||
#define CLK_TOP_SYSPLL2_D4 25
|
||||
#define CLK_TOP_SYSPLL2_D8 26
|
||||
#define CLK_TOP_SYSPLL3_D2 27
|
||||
#define CLK_TOP_SYSPLL3_D4 28
|
||||
#define CLK_TOP_SYSPLL4_D2 29
|
||||
#define CLK_TOP_SYSPLL4_D4 30
|
||||
#define CLK_TOP_UNIVPLL 31
|
||||
#define CLK_TOP_UNIVPLL_D2 32
|
||||
#define CLK_TOP_UNIVPLL_D3 33
|
||||
#define CLK_TOP_UNIVPLL_D5 34
|
||||
#define CLK_TOP_UNIVPLL_D7 35
|
||||
#define CLK_TOP_UNIVPLL_D26 36
|
||||
#define CLK_TOP_UNIVPLL_D52 37
|
||||
#define CLK_TOP_UNIVPLL_D108 38
|
||||
#define CLK_TOP_USB_PHY48M 39
|
||||
#define CLK_TOP_UNIVPLL1_D2 40
|
||||
#define CLK_TOP_UNIVPLL1_D4 41
|
||||
#define CLK_TOP_UNIVPLL1_D8 42
|
||||
#define CLK_TOP_UNIVPLL2_D2 43
|
||||
#define CLK_TOP_UNIVPLL2_D4 44
|
||||
#define CLK_TOP_UNIVPLL2_D8 45
|
||||
#define CLK_TOP_UNIVPLL2_D16 46
|
||||
#define CLK_TOP_UNIVPLL2_D32 47
|
||||
#define CLK_TOP_UNIVPLL3_D2 48
|
||||
#define CLK_TOP_UNIVPLL3_D4 49
|
||||
#define CLK_TOP_UNIVPLL3_D8 50
|
||||
#define CLK_TOP_MSDCPLL 51
|
||||
#define CLK_TOP_MSDCPLL_D2 52
|
||||
#define CLK_TOP_MSDCPLL_D4 53
|
||||
#define CLK_TOP_MSDCPLL_D8 54
|
||||
#define CLK_TOP_MMPLL 55
|
||||
#define CLK_TOP_MMPLL_D2 56
|
||||
#define CLK_TOP_DMPLL_D2 57
|
||||
#define CLK_TOP_DMPLL_D4 58
|
||||
#define CLK_TOP_DMPLL_X2 59
|
||||
#define CLK_TOP_TVDPLL 60
|
||||
#define CLK_TOP_TVDPLL_D2 61
|
||||
#define CLK_TOP_TVDPLL_D4 62
|
||||
#define CLK_TOP_VDECPLL 63
|
||||
#define CLK_TOP_TVD2PLL 64
|
||||
#define CLK_TOP_TVD2PLL_D2 65
|
||||
#define CLK_TOP_MIPIPLL 66
|
||||
#define CLK_TOP_MIPIPLL_D2 67
|
||||
#define CLK_TOP_MIPIPLL_D4 68
|
||||
#define CLK_TOP_HDMIPLL 69
|
||||
#define CLK_TOP_HDMIPLL_D2 70
|
||||
#define CLK_TOP_HDMIPLL_D3 71
|
||||
#define CLK_TOP_ARMPLL_1P3G 72
|
||||
#define CLK_TOP_AUDPLL 73
|
||||
#define CLK_TOP_AUDPLL_D4 74
|
||||
#define CLK_TOP_AUDPLL_D8 75
|
||||
#define CLK_TOP_AUDPLL_D16 76
|
||||
#define CLK_TOP_AUDPLL_D24 77
|
||||
#define CLK_TOP_AUD1PLL_98M 78
|
||||
#define CLK_TOP_AUD2PLL_90M 79
|
||||
#define CLK_TOP_HADDS2PLL_98M 80
|
||||
#define CLK_TOP_HADDS2PLL_294M 81
|
||||
#define CLK_TOP_ETHPLL_500M 82
|
||||
#define CLK_TOP_CLK26M_D8 83
|
||||
#define CLK_TOP_32K_INTERNAL 84
|
||||
#define CLK_TOP_AXISEL_D4 85
|
||||
#define CLK_TOP_8BDAC 86
|
||||
|
||||
#define CLK_TOP_AXI_SEL 87
|
||||
#define CLK_TOP_MEM_SEL 88
|
||||
#define CLK_TOP_DDRPHYCFG_SEL 89
|
||||
#define CLK_TOP_MM_SEL 90
|
||||
#define CLK_TOP_PWM_SEL 91
|
||||
#define CLK_TOP_VDEC_SEL 92
|
||||
#define CLK_TOP_MFG_SEL 93
|
||||
#define CLK_TOP_CAMTG_SEL 94
|
||||
#define CLK_TOP_UART_SEL 95
|
||||
#define CLK_TOP_SPI0_SEL 96
|
||||
#define CLK_TOP_USB20_SEL 97
|
||||
#define CLK_TOP_MSDC30_0_SEL 98
|
||||
#define CLK_TOP_MSDC30_1_SEL 99
|
||||
#define CLK_TOP_MSDC30_2_SEL 100
|
||||
#define CLK_TOP_AUDIO_SEL 101
|
||||
#define CLK_TOP_AUDINTBUS_SEL 102
|
||||
#define CLK_TOP_PMICSPI_SEL 103
|
||||
#define CLK_TOP_SCP_SEL 104
|
||||
#define CLK_TOP_DPI0_SEL 105
|
||||
#define CLK_TOP_DPI1_SEL 106
|
||||
#define CLK_TOP_TVE_SEL 107
|
||||
#define CLK_TOP_HDMI_SEL 108
|
||||
#define CLK_TOP_APLL_SEL 109
|
||||
#define CLK_TOP_RTC_SEL 110
|
||||
#define CLK_TOP_NFI2X_SEL 111
|
||||
#define CLK_TOP_EMMC_HCLK_SEL 112
|
||||
#define CLK_TOP_FLASH_SEL 113
|
||||
#define CLK_TOP_DI_SEL 114
|
||||
#define CLK_TOP_NR_SEL 115
|
||||
#define CLK_TOP_OSD_SEL 116
|
||||
#define CLK_TOP_HDMIRX_BIST_SEL 117
|
||||
#define CLK_TOP_INTDIR_SEL 118
|
||||
#define CLK_TOP_ASM_I_SEL 119
|
||||
#define CLK_TOP_ASM_M_SEL 120
|
||||
#define CLK_TOP_ASM_H_SEL 121
|
||||
#define CLK_TOP_MS_CARD_SEL 122
|
||||
#define CLK_TOP_ETHIF_SEL 123
|
||||
#define CLK_TOP_HDMIRX26_24_SEL 124
|
||||
#define CLK_TOP_MSDC30_3_SEL 125
|
||||
#define CLK_TOP_CMSYS_SEL 126
|
||||
#define CLK_TOP_SPI1_SEL 127
|
||||
#define CLK_TOP_SPI2_SEL 128
|
||||
#define CLK_TOP_8BDAC_SEL 129
|
||||
#define CLK_TOP_AUD2DVD_SEL 130
|
||||
#define CLK_TOP_PADMCLK_SEL 131
|
||||
#define CLK_TOP_AUD_MUX1_SEL 132
|
||||
#define CLK_TOP_AUD_MUX2_SEL 133
|
||||
#define CLK_TOP_AUDPLL_MUX_SEL 134
|
||||
#define CLK_TOP_AUD_K1_SRC_SEL 135
|
||||
#define CLK_TOP_AUD_K2_SRC_SEL 136
|
||||
#define CLK_TOP_AUD_K3_SRC_SEL 137
|
||||
#define CLK_TOP_AUD_K4_SRC_SEL 138
|
||||
#define CLK_TOP_AUD_K5_SRC_SEL 139
|
||||
#define CLK_TOP_AUD_K6_SRC_SEL 140
|
||||
|
||||
#define CLK_TOP_AUD_EXTCK1_DIV 141
|
||||
#define CLK_TOP_AUD_EXTCK2_DIV 142
|
||||
#define CLK_TOP_AUD_MUX1_DIV 143
|
||||
#define CLK_TOP_AUD_MUX2_DIV 144
|
||||
#define CLK_TOP_AUD_K1_SRC_DIV 145
|
||||
#define CLK_TOP_AUD_K2_SRC_DIV 146
|
||||
#define CLK_TOP_AUD_K3_SRC_DIV 147
|
||||
#define CLK_TOP_AUD_K4_SRC_DIV 148
|
||||
#define CLK_TOP_AUD_K5_SRC_DIV 149
|
||||
#define CLK_TOP_AUD_K6_SRC_DIV 150
|
||||
#define CLK_TOP_AUD_48K_TIMING 151
|
||||
#define CLK_TOP_AUD_44K_TIMING 152
|
||||
#define CLK_TOP_AUD_I2S1_MCLK 153
|
||||
#define CLK_TOP_AUD_I2S2_MCLK 154
|
||||
#define CLK_TOP_AUD_I2S3_MCLK 155
|
||||
#define CLK_TOP_AUD_I2S4_MCLK 156
|
||||
#define CLK_TOP_AUD_I2S5_MCLK 157
|
||||
#define CLK_TOP_AUD_I2S6_MCLK 158
|
||||
#define CLK_TOP_NR 159
|
||||
|
||||
/* APMIXEDSYS */
|
||||
#define CLK_APMIXED_ARMPLL 0
|
||||
#define CLK_APMIXED_MAINPLL 1
|
||||
#define CLK_APMIXED_UNIVPLL 2
|
||||
#define CLK_APMIXED_MMPLL 3
|
||||
#define CLK_APMIXED_MSDCPLL 4
|
||||
#define CLK_APMIXED_TVDPLL 5
|
||||
#define CLK_APMIXED_AUD1PLL 6
|
||||
#define CLK_APMIXED_TRGPLL 7
|
||||
#define CLK_APMIXED_ETHPLL 8
|
||||
#define CLK_APMIXED_VDECPLL 9
|
||||
#define CLK_APMIXED_HADDS2PLL 10
|
||||
#define CLK_APMIXED_AUD2PLL 11
|
||||
#define CLK_APMIXED_TVD2PLL 12
|
||||
#define CLK_APMIXED_NR 13
|
||||
|
||||
/* INFRACFG */
|
||||
#define CLK_INFRA_DBG 0
|
||||
#define CLK_INFRA_SMI 1
|
||||
#define CLK_INFRA_QAXI_CM4 2
|
||||
#define CLK_INFRA_AUD_SPLIN_B 3
|
||||
#define CLK_INFRA_AUDIO 4
|
||||
#define CLK_INFRA_EFUSE 5
|
||||
#define CLK_INFRA_L2C_SRAM 6
|
||||
#define CLK_INFRA_M4U 7
|
||||
#define CLK_INFRA_CONNMCU 8
|
||||
#define CLK_INFRA_TRNG 9
|
||||
#define CLK_INFRA_RAMBUFIF 10
|
||||
#define CLK_INFRA_CPUM 11
|
||||
#define CLK_INFRA_KP 12
|
||||
#define CLK_INFRA_CEC 13
|
||||
#define CLK_INFRA_IRRX 14
|
||||
#define CLK_INFRA_PMICSPI 15
|
||||
#define CLK_INFRA_PMICWRAP 16
|
||||
#define CLK_INFRA_DDCCI 17
|
||||
#define CLK_INFRA_CPUSEL 18
|
||||
#define CLK_INFRA_NR 19
|
||||
|
||||
/* PERICFG */
|
||||
#define CLK_PERI_NFI 0
|
||||
#define CLK_PERI_THERM 1
|
||||
#define CLK_PERI_PWM1 2
|
||||
#define CLK_PERI_PWM2 3
|
||||
#define CLK_PERI_PWM3 4
|
||||
#define CLK_PERI_PWM4 5
|
||||
#define CLK_PERI_PWM5 6
|
||||
#define CLK_PERI_PWM6 7
|
||||
#define CLK_PERI_PWM7 8
|
||||
#define CLK_PERI_PWM 9
|
||||
#define CLK_PERI_USB0 10
|
||||
#define CLK_PERI_USB1 11
|
||||
#define CLK_PERI_AP_DMA 12
|
||||
#define CLK_PERI_MSDC30_0 13
|
||||
#define CLK_PERI_MSDC30_1 14
|
||||
#define CLK_PERI_MSDC30_2 15
|
||||
#define CLK_PERI_MSDC30_3 16
|
||||
#define CLK_PERI_MSDC50_3 17
|
||||
#define CLK_PERI_NLI 18
|
||||
#define CLK_PERI_UART0 19
|
||||
#define CLK_PERI_UART1 20
|
||||
#define CLK_PERI_UART2 21
|
||||
#define CLK_PERI_UART3 22
|
||||
#define CLK_PERI_BTIF 23
|
||||
#define CLK_PERI_I2C0 24
|
||||
#define CLK_PERI_I2C1 25
|
||||
#define CLK_PERI_I2C2 26
|
||||
#define CLK_PERI_I2C3 27
|
||||
#define CLK_PERI_AUXADC 28
|
||||
#define CLK_PERI_SPI0 39
|
||||
#define CLK_PERI_ETH 30
|
||||
#define CLK_PERI_USB0_MCU 31
|
||||
|
||||
#define CLK_PERI_USB1_MCU 32
|
||||
#define CLK_PERI_USB_SLV 33
|
||||
#define CLK_PERI_GCPU 34
|
||||
#define CLK_PERI_NFI_ECC 35
|
||||
#define CLK_PERI_NFI_PAD 36
|
||||
#define CLK_PERI_FLASH 37
|
||||
#define CLK_PERI_HOST89_INT 38
|
||||
#define CLK_PERI_HOST89_SPI 39
|
||||
#define CLK_PERI_HOST89_DVD 40
|
||||
#define CLK_PERI_SPI1 41
|
||||
#define CLK_PERI_SPI2 42
|
||||
#define CLK_PERI_FCI 43
|
||||
#define CLK_PERI_NR 44
|
||||
|
||||
/* AUDIO */
|
||||
#define CLK_AUD_AFE 0
|
||||
#define CLK_AUD_LRCK_DETECT 1
|
||||
#define CLK_AUD_I2S 2
|
||||
#define CLK_AUD_APLL_TUNER 3
|
||||
#define CLK_AUD_HDMI 4
|
||||
#define CLK_AUD_SPDF 5
|
||||
#define CLK_AUD_SPDF2 6
|
||||
#define CLK_AUD_APLL 7
|
||||
#define CLK_AUD_TML 8
|
||||
#define CLK_AUD_AHB_IDLE_EXT 9
|
||||
#define CLK_AUD_AHB_IDLE_INT 10
|
||||
|
||||
#define CLK_AUD_I2SIN1 11
|
||||
#define CLK_AUD_I2SIN2 12
|
||||
#define CLK_AUD_I2SIN3 13
|
||||
#define CLK_AUD_I2SIN4 14
|
||||
#define CLK_AUD_I2SIN5 15
|
||||
#define CLK_AUD_I2SIN6 16
|
||||
#define CLK_AUD_I2SO1 17
|
||||
#define CLK_AUD_I2SO2 18
|
||||
#define CLK_AUD_I2SO3 19
|
||||
#define CLK_AUD_I2SO4 20
|
||||
#define CLK_AUD_I2SO5 21
|
||||
#define CLK_AUD_I2SO6 22
|
||||
#define CLK_AUD_ASRCI1 23
|
||||
#define CLK_AUD_ASRCI2 24
|
||||
#define CLK_AUD_ASRCO1 25
|
||||
#define CLK_AUD_ASRCO2 26
|
||||
#define CLK_AUD_ASRC11 27
|
||||
#define CLK_AUD_ASRC12 28
|
||||
#define CLK_AUD_HDMIRX 29
|
||||
#define CLK_AUD_INTDIR 30
|
||||
#define CLK_AUD_A1SYS 31
|
||||
#define CLK_AUD_A2SYS 32
|
||||
#define CLK_AUD_AFE_CONN 33
|
||||
#define CLK_AUD_AFE_PCMIF 34
|
||||
#define CLK_AUD_AFE_MRGIF 35
|
||||
|
||||
#define CLK_AUD_MMIF_UL1 36
|
||||
#define CLK_AUD_MMIF_UL2 37
|
||||
#define CLK_AUD_MMIF_UL3 38
|
||||
#define CLK_AUD_MMIF_UL4 39
|
||||
#define CLK_AUD_MMIF_UL5 40
|
||||
#define CLK_AUD_MMIF_UL6 41
|
||||
#define CLK_AUD_MMIF_DL1 42
|
||||
#define CLK_AUD_MMIF_DL2 43
|
||||
#define CLK_AUD_MMIF_DL3 44
|
||||
#define CLK_AUD_MMIF_DL4 45
|
||||
#define CLK_AUD_MMIF_DL5 46
|
||||
#define CLK_AUD_MMIF_DL6 47
|
||||
#define CLK_AUD_MMIF_DLMCH 48
|
||||
#define CLK_AUD_MMIF_ARB1 49
|
||||
#define CLK_AUD_MMIF_AWB1 50
|
||||
#define CLK_AUD_MMIF_AWB2 51
|
||||
#define CLK_AUD_MMIF_DAI 52
|
||||
|
||||
#define CLK_AUD_DMIC1 53
|
||||
#define CLK_AUD_DMIC2 54
|
||||
#define CLK_AUD_ASRCI3 55
|
||||
#define CLK_AUD_ASRCI4 56
|
||||
#define CLK_AUD_ASRCI5 57
|
||||
#define CLK_AUD_ASRCI6 58
|
||||
#define CLK_AUD_ASRCO3 59
|
||||
#define CLK_AUD_ASRCO4 60
|
||||
#define CLK_AUD_ASRCO5 61
|
||||
#define CLK_AUD_ASRCO6 62
|
||||
#define CLK_AUD_MEM_ASRC1 63
|
||||
#define CLK_AUD_MEM_ASRC2 64
|
||||
#define CLK_AUD_MEM_ASRC3 65
|
||||
#define CLK_AUD_MEM_ASRC4 66
|
||||
#define CLK_AUD_MEM_ASRC5 67
|
||||
#define CLK_AUD_DSD_ENC 68
|
||||
#define CLK_AUD_ASRC_BRG 60
|
||||
#define CLK_AUD_NR 70
|
||||
|
||||
/* MMSYS */
|
||||
#define CLK_MM_SMI_COMMON 0
|
||||
#define CLK_MM_SMI_LARB0 1
|
||||
#define CLK_MM_CMDQ 2
|
||||
#define CLK_MM_MUTEX 3
|
||||
#define CLK_MM_DISP_COLOR 4
|
||||
#define CLK_MM_DISP_BLS 5
|
||||
#define CLK_MM_DISP_WDMA 6
|
||||
#define CLK_MM_DISP_RDMA 7
|
||||
#define CLK_MM_DISP_OVL 8
|
||||
#define CLK_MM_MDP_TDSHP 9
|
||||
#define CLK_MM_MDP_WROT 10
|
||||
#define CLK_MM_MDP_WDMA 11
|
||||
#define CLK_MM_MDP_RSZ1 12
|
||||
#define CLK_MM_MDP_RSZ0 13
|
||||
#define CLK_MM_MDP_RDMA 14
|
||||
#define CLK_MM_MDP_BLS_26M 15
|
||||
#define CLK_MM_CAM_MDP 16
|
||||
#define CLK_MM_FAKE_ENG 17
|
||||
#define CLK_MM_MUTEX_32K 18
|
||||
#define CLK_MM_DISP_RDMA1 19
|
||||
#define CLK_MM_DISP_UFOE 20
|
||||
|
||||
#define CLK_MM_DSI_ENGINE 21
|
||||
#define CLK_MM_DSI_DIG 22
|
||||
#define CLK_MM_DPI_DIGL 23
|
||||
#define CLK_MM_DPI_ENGINE 24
|
||||
#define CLK_MM_DPI1_DIGL 25
|
||||
#define CLK_MM_DPI1_ENGINE 26
|
||||
#define CLK_MM_TVE_OUTPUT 27
|
||||
#define CLK_MM_TVE_INPUT 28
|
||||
#define CLK_MM_HDMI_PIXEL 29
|
||||
#define CLK_MM_HDMI_PLL 30
|
||||
#define CLK_MM_HDMI_AUDIO 31
|
||||
#define CLK_MM_HDMI_SPDIF 32
|
||||
#define CLK_MM_TVE_FMM 33
|
||||
#define CLK_MM_NR 34
|
||||
|
||||
/* IMGSYS */
|
||||
#define CLK_IMG_SMI_COMM 0
|
||||
#define CLK_IMG_RESZ 1
|
||||
#define CLK_IMG_JPGDEC_SMI 2
|
||||
#define CLK_IMG_JPGDEC 3
|
||||
#define CLK_IMG_VENC_LT 4
|
||||
#define CLK_IMG_VENC 5
|
||||
#define CLK_IMG_NR 6
|
||||
|
||||
/* VDEC */
|
||||
#define CLK_VDEC_CKGEN 0
|
||||
#define CLK_VDEC_LARB 1
|
||||
#define CLK_VDEC_NR 2
|
||||
|
||||
/* HIFSYS */
|
||||
#define CLK_HIFSYS_USB0PHY 0
|
||||
#define CLK_HIFSYS_USB1PHY 1
|
||||
#define CLK_HIFSYS_PCIE0 2
|
||||
#define CLK_HIFSYS_PCIE1 3
|
||||
#define CLK_HIFSYS_PCIE2 4
|
||||
#define CLK_HIFSYS_NR 5
|
||||
|
||||
/* ETHSYS */
|
||||
#define CLK_ETHSYS_HSDMA 0
|
||||
#define CLK_ETHSYS_ESW 1
|
||||
#define CLK_ETHSYS_GP2 2
|
||||
#define CLK_ETHSYS_GP1 3
|
||||
#define CLK_ETHSYS_PCM 4
|
||||
#define CLK_ETHSYS_GDMA 5
|
||||
#define CLK_ETHSYS_I2S 6
|
||||
#define CLK_ETHSYS_CRYPTO 7
|
||||
#define CLK_ETHSYS_NR 8
|
||||
|
||||
/* G3DSYS */
|
||||
#define CLK_G3DSYS_CORE 0
|
||||
#define CLK_G3DSYS_NR 1
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT2701_H */
|
206
include/dt-bindings/clock/mt7629-clk.h
Normal file
206
include/dt-bindings/clock/mt7629-clk.h
Normal file
@ -0,0 +1,206 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT7629_H
|
||||
#define _DT_BINDINGS_CLK_MT7629_H
|
||||
|
||||
/* TOPCKGEN */
|
||||
#define CLK_TOP_FCLKS_OFF 0
|
||||
|
||||
#define CLK_TOP_TO_U2_PHY 0
|
||||
#define CLK_TOP_TO_U2_PHY_1P 1
|
||||
#define CLK_TOP_PCIE0_PIPE_EN 2
|
||||
#define CLK_TOP_PCIE1_PIPE_EN 3
|
||||
#define CLK_TOP_SSUSB_TX250M 4
|
||||
#define CLK_TOP_SSUSB_EQ_RX250M 5
|
||||
#define CLK_TOP_SSUSB_CDR_REF 6
|
||||
#define CLK_TOP_SSUSB_CDR_FB 7
|
||||
#define CLK_TOP_SATA_ASIC 8
|
||||
#define CLK_TOP_SATA_RBC 9
|
||||
|
||||
#define CLK_TOP_TO_USB3_SYS 10
|
||||
#define CLK_TOP_P1_1MHZ 11
|
||||
#define CLK_TOP_4MHZ 12
|
||||
#define CLK_TOP_P0_1MHZ 13
|
||||
#define CLK_TOP_ETH_500M 14
|
||||
#define CLK_TOP_TXCLK_SRC_PRE 15
|
||||
#define CLK_TOP_RTC 16
|
||||
#define CLK_TOP_PWM_QTR_26M 17
|
||||
#define CLK_TOP_CPUM_TCK_IN 18
|
||||
#define CLK_TOP_TO_USB3_DA_TOP 19
|
||||
#define CLK_TOP_MEMPLL 20
|
||||
#define CLK_TOP_DMPLL 21
|
||||
#define CLK_TOP_DMPLL_D4 22
|
||||
#define CLK_TOP_DMPLL_D8 23
|
||||
#define CLK_TOP_SYSPLL_D2 24
|
||||
#define CLK_TOP_SYSPLL1_D2 25
|
||||
#define CLK_TOP_SYSPLL1_D4 26
|
||||
#define CLK_TOP_SYSPLL1_D8 27
|
||||
#define CLK_TOP_SYSPLL1_D16 28
|
||||
#define CLK_TOP_SYSPLL2_D2 29
|
||||
#define CLK_TOP_SYSPLL2_D4 30
|
||||
#define CLK_TOP_SYSPLL2_D8 31
|
||||
#define CLK_TOP_SYSPLL_D5 32
|
||||
#define CLK_TOP_SYSPLL3_D2 33
|
||||
#define CLK_TOP_SYSPLL3_D4 34
|
||||
#define CLK_TOP_SYSPLL_D7 35
|
||||
#define CLK_TOP_SYSPLL4_D2 36
|
||||
#define CLK_TOP_SYSPLL4_D4 37
|
||||
#define CLK_TOP_SYSPLL4_D16 38
|
||||
#define CLK_TOP_UNIVPLL 39
|
||||
#define CLK_TOP_UNIVPLL1_D2 40
|
||||
#define CLK_TOP_UNIVPLL1_D4 41
|
||||
#define CLK_TOP_UNIVPLL1_D8 42
|
||||
#define CLK_TOP_UNIVPLL_D3 43
|
||||
#define CLK_TOP_UNIVPLL2_D2 44
|
||||
#define CLK_TOP_UNIVPLL2_D4 45
|
||||
#define CLK_TOP_UNIVPLL2_D8 46
|
||||
#define CLK_TOP_UNIVPLL2_D16 47
|
||||
#define CLK_TOP_UNIVPLL_D5 48
|
||||
#define CLK_TOP_UNIVPLL3_D2 49
|
||||
#define CLK_TOP_UNIVPLL3_D4 50
|
||||
#define CLK_TOP_UNIVPLL3_D16 51
|
||||
#define CLK_TOP_UNIVPLL_D7 52
|
||||
#define CLK_TOP_UNIVPLL_D80_D4 53
|
||||
#define CLK_TOP_UNIV48M 54
|
||||
#define CLK_TOP_SGMIIPLL_D2 55
|
||||
#define CLK_TOP_CLKXTAL_D4 56
|
||||
#define CLK_TOP_HD_FAXI 57
|
||||
#define CLK_TOP_FAXI 58
|
||||
#define CLK_TOP_F_FAUD_INTBUS 59
|
||||
#define CLK_TOP_AP2WBHIF_HCLK 60
|
||||
#define CLK_TOP_10M_INFRAO 61
|
||||
#define CLK_TOP_MSDC30_1 62
|
||||
#define CLK_TOP_SPI 63
|
||||
#define CLK_TOP_SF 64
|
||||
#define CLK_TOP_FLASH 65
|
||||
#define CLK_TOP_TO_USB3_REF 66
|
||||
#define CLK_TOP_TO_USB3_MCU 67
|
||||
#define CLK_TOP_TO_USB3_DMA 68
|
||||
#define CLK_TOP_FROM_TOP_AHB 69
|
||||
#define CLK_TOP_FROM_TOP_AXI 70
|
||||
#define CLK_TOP_PCIE1_MAC_EN 71
|
||||
#define CLK_TOP_PCIE0_MAC_EN 72
|
||||
|
||||
#define CLK_TOP_AXI_SEL 73
|
||||
#define CLK_TOP_MEM_SEL 74
|
||||
#define CLK_TOP_DDRPHYCFG_SEL 75
|
||||
#define CLK_TOP_ETH_SEL 76
|
||||
#define CLK_TOP_PWM_SEL 77
|
||||
#define CLK_TOP_F10M_REF_SEL 78
|
||||
#define CLK_TOP_NFI_INFRA_SEL 79
|
||||
#define CLK_TOP_FLASH_SEL 80
|
||||
#define CLK_TOP_UART_SEL 81
|
||||
#define CLK_TOP_SPI0_SEL 82
|
||||
#define CLK_TOP_SPI1_SEL 83
|
||||
#define CLK_TOP_MSDC50_0_SEL 84
|
||||
#define CLK_TOP_MSDC30_0_SEL 85
|
||||
#define CLK_TOP_MSDC30_1_SEL 86
|
||||
#define CLK_TOP_AP2WBMCU_SEL 87
|
||||
#define CLK_TOP_AP2WBHIF_SEL 88
|
||||
#define CLK_TOP_AUDIO_SEL 89
|
||||
#define CLK_TOP_AUD_INTBUS_SEL 90
|
||||
#define CLK_TOP_PMICSPI_SEL 91
|
||||
#define CLK_TOP_SCP_SEL 92
|
||||
#define CLK_TOP_ATB_SEL 93
|
||||
#define CLK_TOP_HIF_SEL 94
|
||||
#define CLK_TOP_SATA_SEL 95
|
||||
#define CLK_TOP_U2_SEL 96
|
||||
#define CLK_TOP_AUD1_SEL 97
|
||||
#define CLK_TOP_AUD2_SEL 98
|
||||
#define CLK_TOP_IRRX_SEL 99
|
||||
#define CLK_TOP_IRTX_SEL 100
|
||||
#define CLK_TOP_SATA_MCU_SEL 101
|
||||
#define CLK_TOP_PCIE0_MCU_SEL 102
|
||||
#define CLK_TOP_PCIE1_MCU_SEL 103
|
||||
#define CLK_TOP_SSUSB_MCU_SEL 104
|
||||
#define CLK_TOP_CRYPTO_SEL 105
|
||||
#define CLK_TOP_SGMII_REF_1_SEL 106
|
||||
#define CLK_TOP_10M_SEL 107
|
||||
#define CLK_TOP_NR_CLK 108
|
||||
|
||||
/* INFRACFG */
|
||||
#define CLK_INFRA_MUX1_SEL 0
|
||||
#define CLK_INFRA_DBGCLK_PD 1
|
||||
#define CLK_INFRA_TRNG_PD 2
|
||||
#define CLK_INFRA_DEVAPC_PD 3
|
||||
#define CLK_INFRA_APXGPT_PD 4
|
||||
#define CLK_INFRA_SEJ_PD 5
|
||||
#define CLK_INFRA_NR_CLK 6
|
||||
|
||||
/* PERICFG */
|
||||
#define CLK_PERIBUS_SEL 0
|
||||
#define CLK_PERI_PWM1_PD 1
|
||||
#define CLK_PERI_PWM2_PD 2
|
||||
#define CLK_PERI_PWM3_PD 3
|
||||
#define CLK_PERI_PWM4_PD 4
|
||||
#define CLK_PERI_PWM5_PD 5
|
||||
#define CLK_PERI_PWM6_PD 6
|
||||
#define CLK_PERI_PWM7_PD 7
|
||||
#define CLK_PERI_PWM_PD 8
|
||||
#define CLK_PERI_AP_DMA_PD 9
|
||||
#define CLK_PERI_MSDC30_1_PD 10
|
||||
#define CLK_PERI_UART0_PD 11
|
||||
#define CLK_PERI_UART1_PD 12
|
||||
#define CLK_PERI_UART2_PD 13
|
||||
#define CLK_PERI_UART3_PD 14
|
||||
#define CLK_PERI_BTIF_PD 15
|
||||
#define CLK_PERI_I2C0_PD 16
|
||||
#define CLK_PERI_SPI0_PD 17
|
||||
#define CLK_PERI_SNFI_PD 18
|
||||
#define CLK_PERI_NFI_PD 19
|
||||
#define CLK_PERI_NFIECC_PD 20
|
||||
#define CLK_PERI_FLASH_PD 21
|
||||
#define CLK_PERI_NR_CLK 22
|
||||
|
||||
/* APMIXEDSYS */
|
||||
#define CLK_APMIXED_ARMPLL 0
|
||||
#define CLK_APMIXED_MAINPLL 1
|
||||
#define CLK_APMIXED_UNIV2PLL 2
|
||||
#define CLK_APMIXED_ETH1PLL 3
|
||||
#define CLK_APMIXED_ETH2PLL 4
|
||||
#define CLK_APMIXED_SGMIPLL 5
|
||||
#define CLK_APMIXED_NR_CLK 6
|
||||
|
||||
/* SSUSBSYS */
|
||||
#define CLK_SSUSB_U2_PHY_1P_EN 0
|
||||
#define CLK_SSUSB_U2_PHY_EN 1
|
||||
#define CLK_SSUSB_REF_EN 2
|
||||
#define CLK_SSUSB_SYS_EN 3
|
||||
#define CLK_SSUSB_MCU_EN 4
|
||||
#define CLK_SSUSB_DMA_EN 5
|
||||
#define CLK_SSUSB_NR_CLK 6
|
||||
|
||||
/* PCIESYS */
|
||||
#define CLK_PCIE_P1_AUX_EN 0
|
||||
#define CLK_PCIE_P1_OBFF_EN 1
|
||||
#define CLK_PCIE_P1_AHB_EN 2
|
||||
#define CLK_PCIE_P1_AXI_EN 3
|
||||
#define CLK_PCIE_P1_MAC_EN 4
|
||||
#define CLK_PCIE_P1_PIPE_EN 5
|
||||
#define CLK_PCIE_P0_AUX_EN 6
|
||||
#define CLK_PCIE_P0_OBFF_EN 7
|
||||
#define CLK_PCIE_P0_AHB_EN 8
|
||||
#define CLK_PCIE_P0_AXI_EN 9
|
||||
#define CLK_PCIE_P0_MAC_EN 10
|
||||
#define CLK_PCIE_P0_PIPE_EN 11
|
||||
#define CLK_PCIE_NR_CLK 12
|
||||
|
||||
/* ETHSYS */
|
||||
#define CLK_ETH_FE_EN 0
|
||||
#define CLK_ETH_GP2_EN 1
|
||||
#define CLK_ETH_GP1_EN 2
|
||||
#define CLK_ETH_GP0_EN 3
|
||||
#define CLK_ETH_ESW_EN 4
|
||||
#define CLK_ETH_NR_CLK 5
|
||||
|
||||
/* SGMIISYS */
|
||||
#define CLK_SGMII_TX_EN 0
|
||||
#define CLK_SGMII_RX_EN 1
|
||||
#define CLK_SGMII_CDR_REF 2
|
||||
#define CLK_SGMII_CDR_FB 3
|
||||
#define CLK_SGMII_NR_CLK 4
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT7629_H */
|
19
include/dt-bindings/power/mt7623-power.h
Normal file
19
include/dt-bindings/power/mt7623-power.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_MT7623_POWER_H
|
||||
#define _DT_BINDINGS_MT7623_POWER_H
|
||||
|
||||
#define MT7623_POWER_DOMAIN_CONN 0
|
||||
#define MT7623_POWER_DOMAIN_DISP 1
|
||||
#define MT7623_POWER_DOMAIN_MFG 2
|
||||
#define MT7623_POWER_DOMAIN_VDEC 3
|
||||
#define MT7623_POWER_DOMAIN_ISP 4
|
||||
#define MT7623_POWER_DOMAIN_BDP 5
|
||||
#define MT7623_POWER_DOMAIN_ETH 6
|
||||
#define MT7623_POWER_DOMAIN_HIF 7
|
||||
#define MT7623_POWER_DOMAIN_IFR_MSC 8
|
||||
|
||||
#endif /* _DT_BINDINGS_MT7623_POWER_H */
|
13
include/dt-bindings/power/mt7629-power.h
Normal file
13
include/dt-bindings/power/mt7629-power.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_MT7629_POWER_H
|
||||
#define _DT_BINDINGS_MT7629_POWER_H
|
||||
|
||||
#define MT7629_POWER_DOMAIN_ETHSYS 0
|
||||
#define MT7629_POWER_DOMAIN_HIF0 1
|
||||
#define MT7629_POWER_DOMAIN_HIF1 2
|
||||
|
||||
#endif /* _DT_BINDINGS_MT7629_POWER_H */
|
@ -278,6 +278,7 @@ enum {
|
||||
IH_TYPE_PMMC, /* TI Power Management Micro-Controller Firmware */
|
||||
IH_TYPE_STM32IMAGE, /* STMicroelectronics STM32 Image */
|
||||
IH_TYPE_SOCFPGAIMAGE_V1, /* Altera SOCFPGA A10 Preloader */
|
||||
IH_TYPE_MTKIMAGE, /* MediaTek BootROM loadable Image */
|
||||
|
||||
IH_TYPE_COUNT, /* Number of image types */
|
||||
};
|
||||
|
@ -219,6 +219,8 @@ ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-spl.bin
|
||||
ALL-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin
|
||||
ALL-$(CONFIG_ARCH_ZYNQMP) += $(obj)/boot.bin
|
||||
|
||||
ALL-$(CONFIG_ARCH_MEDIATEK) += $(obj)/u-boot-spl-mtk.bin
|
||||
|
||||
all: $(ALL-y)
|
||||
|
||||
quiet_cmd_cat = CAT $@
|
||||
@ -349,6 +351,15 @@ cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \
|
||||
$(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin
|
||||
$(call if_changed,sunxi_spl_image_builder)
|
||||
|
||||
|
||||
# MediaTek's specific SPL build
|
||||
MKIMAGEFLAGS_u-boot-spl-mtk.bin = -T mtk_image \
|
||||
-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
|
||||
-n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
|
||||
|
||||
$(obj)/u-boot-spl-mtk.bin: $(obj)/u-boot-spl.bin FORCE
|
||||
$(call if_changed,mkimage)
|
||||
|
||||
# Rule to link u-boot-spl
|
||||
# May be overridden by arch/$(ARCH)/config.mk
|
||||
quiet_cmd_u-boot-spl ?= LD $@
|
||||
|
@ -116,6 +116,7 @@ dumpimage-mkimage-objs := aisimage.o \
|
||||
$(LIBFDT_OBJS) \
|
||||
gpimage.o \
|
||||
gpimage-common.o \
|
||||
mtk_image.o \
|
||||
$(RSA_OBJS-y)
|
||||
|
||||
dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o
|
||||
|
749
tools/mtk_image.c
Normal file
749
tools/mtk_image.c
Normal file
@ -0,0 +1,749 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Generate MediaTek BootROM header for SPL/U-Boot images
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <image.h>
|
||||
#include <u-boot/sha256.h>
|
||||
#include "imagetool.h"
|
||||
#include "mtk_image.h"
|
||||
|
||||
/* NAND header for SPI-NAND with 2KB page + 64B spare */
|
||||
static const union nand_boot_header snand_hdr_2k_64_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
|
||||
0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
|
||||
0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
|
||||
0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
|
||||
0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
|
||||
static const union nand_boot_header snand_hdr_2k_128_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
|
||||
0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
|
||||
0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
|
||||
0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
|
||||
0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for SPI-NAND with 4KB page + 256B spare */
|
||||
static const union nand_boot_header snand_hdr_4k_256_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
|
||||
0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
|
||||
0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
|
||||
0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
|
||||
0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
|
||||
static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
|
||||
0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
|
||||
0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
|
||||
0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
|
||||
0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
|
||||
static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
|
||||
0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
|
||||
0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
|
||||
0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
|
||||
0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
|
||||
static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
|
||||
0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
|
||||
0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
|
||||
0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
|
||||
0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
|
||||
static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
|
||||
0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
|
||||
0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
|
||||
0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
|
||||
0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
|
||||
static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
|
||||
.data = {
|
||||
0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
|
||||
0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
|
||||
0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
|
||||
0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
|
||||
0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
|
||||
0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
|
||||
0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
static const struct nand_header_type {
|
||||
const char *name;
|
||||
const union nand_boot_header *data;
|
||||
} nand_headers[] = {
|
||||
{
|
||||
.name = "2k+64",
|
||||
.data = &snand_hdr_2k_64_data
|
||||
}, {
|
||||
.name = "2k+120",
|
||||
.data = &snand_hdr_2k_128_data
|
||||
}, {
|
||||
.name = "2k+128",
|
||||
.data = &snand_hdr_2k_128_data
|
||||
}, {
|
||||
.name = "4k+256",
|
||||
.data = &snand_hdr_4k_256_data
|
||||
}, {
|
||||
.name = "1g:2k+64",
|
||||
.data = &nand_hdr_1gb_2k_64_data
|
||||
}, {
|
||||
.name = "2g:2k+64",
|
||||
.data = &nand_hdr_2gb_2k_64_data
|
||||
}, {
|
||||
.name = "4g:2k+64",
|
||||
.data = &nand_hdr_4gb_2k_64_data
|
||||
}, {
|
||||
.name = "2g:2k+128",
|
||||
.data = &nand_hdr_2gb_2k_128_data
|
||||
}, {
|
||||
.name = "4g:2k+128",
|
||||
.data = &nand_hdr_4gb_2k_128_data
|
||||
}
|
||||
};
|
||||
|
||||
static const struct brom_img_type {
|
||||
const char *name;
|
||||
enum brlyt_img_type type;
|
||||
} brom_images[] = {
|
||||
{
|
||||
.name = "nand",
|
||||
.type = BRLYT_TYPE_NAND
|
||||
}, {
|
||||
.name = "emmc",
|
||||
.type = BRLYT_TYPE_EMMC
|
||||
}, {
|
||||
.name = "nor",
|
||||
.type = BRLYT_TYPE_NOR
|
||||
}, {
|
||||
.name = "sdmmc",
|
||||
.type = BRLYT_TYPE_SDMMC
|
||||
}, {
|
||||
.name = "snand",
|
||||
.type = BRLYT_TYPE_SNAND
|
||||
}
|
||||
};
|
||||
|
||||
/* Image type selected by user */
|
||||
static enum brlyt_img_type hdr_media;
|
||||
static int use_lk_hdr;
|
||||
|
||||
/* LK image name */
|
||||
static char lk_name[32] = "U-Boot";
|
||||
|
||||
/* NAND header selected by user */
|
||||
static const union nand_boot_header *hdr_nand;
|
||||
|
||||
/* GFH header + 2 * 4KB pages of NAND */
|
||||
static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
|
||||
|
||||
static int mtk_image_check_image_types(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_MTKIMAGE)
|
||||
return EXIT_SUCCESS;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int mtk_brom_parse_imagename(const char *imagename)
|
||||
{
|
||||
#define is_blank_char(c) \
|
||||
((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
|
||||
|
||||
char *buf = strdup(imagename), *key, *val, *end, *next;
|
||||
int i;
|
||||
|
||||
/* User passed arguments from image name */
|
||||
static const char *media = "";
|
||||
static const char *nandinfo = "";
|
||||
static const char *lk = "";
|
||||
|
||||
key = buf;
|
||||
while (key) {
|
||||
next = strchr(key, ';');
|
||||
if (next)
|
||||
*next = 0;
|
||||
|
||||
val = strchr(key, '=');
|
||||
if (val) {
|
||||
*val++ = 0;
|
||||
|
||||
/* Trim key */
|
||||
while (is_blank_char(*key))
|
||||
key++;
|
||||
|
||||
end = key + strlen(key) - 1;
|
||||
while ((end >= key) && is_blank_char(*end))
|
||||
end--;
|
||||
end++;
|
||||
|
||||
if (is_blank_char(*end))
|
||||
*end = 0;
|
||||
|
||||
/* Trim value */
|
||||
while (is_blank_char(*val))
|
||||
val++;
|
||||
|
||||
end = val + strlen(val) - 1;
|
||||
while ((end >= val) && is_blank_char(*end))
|
||||
end--;
|
||||
end++;
|
||||
|
||||
if (is_blank_char(*end))
|
||||
*end = 0;
|
||||
|
||||
/* record user passed arguments */
|
||||
if (!strcmp(key, "media"))
|
||||
media = val;
|
||||
|
||||
if (!strcmp(key, "nandinfo"))
|
||||
nandinfo = val;
|
||||
|
||||
if (!strcmp(key, "lk"))
|
||||
lk = val;
|
||||
|
||||
if (!strcmp(key, "lkname"))
|
||||
strncpy(lk_name, val, sizeof(lk_name));
|
||||
}
|
||||
|
||||
if (next)
|
||||
key = next + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* if user specified LK image header, skip following checks */
|
||||
if (lk && lk[0] == '1') {
|
||||
use_lk_hdr = 1;
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse media type */
|
||||
for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
|
||||
if (!strcmp(brom_images[i].name, media)) {
|
||||
hdr_media = brom_images[i].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse nand header type */
|
||||
for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
|
||||
if (!strcmp(nand_headers[i].name, nandinfo)) {
|
||||
hdr_nand = nand_headers[i].data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_INVALID) {
|
||||
fprintf(stderr, "Error: media type is invalid or missing.\n");
|
||||
fprintf(stderr, " Please specify -n \"media=<type>\"\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
|
||||
!hdr_nand) {
|
||||
fprintf(stderr, "Error: nand info is invalid or missing.\n");
|
||||
fprintf(stderr, " Please specify -n \"media=%s;"
|
||||
"nandinfo=<info>\"\n", media);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_image_check_params(struct image_tool_params *params)
|
||||
{
|
||||
if (!params->addr) {
|
||||
fprintf(stderr, "Error: Load Address must be set.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!params->imagename) {
|
||||
fprintf(stderr, "Error: Image Name must be set.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mtk_brom_parse_imagename(params->imagename);
|
||||
}
|
||||
|
||||
static int mtk_image_vrec_header(struct image_tool_params *params,
|
||||
struct image_type_params *tparams)
|
||||
{
|
||||
if (use_lk_hdr) {
|
||||
tparams->header_size = sizeof(union lk_hdr);
|
||||
tparams->hdr = &hdr_tmp;
|
||||
memset(&hdr_tmp, 0xff, tparams->header_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
|
||||
tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
|
||||
else
|
||||
tparams->header_size = sizeof(struct gen_device_header);
|
||||
|
||||
tparams->header_size += sizeof(struct gfh_header);
|
||||
tparams->hdr = &hdr_tmp;
|
||||
|
||||
memset(&hdr_tmp, 0xff, tparams->header_size);
|
||||
|
||||
return SHA256_SUM_LEN;
|
||||
}
|
||||
|
||||
static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
|
||||
{
|
||||
union gen_boot_header *gbh = (union gen_boot_header *)ptr;
|
||||
struct brom_layout_header *bh;
|
||||
struct gfh_header *gfh;
|
||||
const char *bootmedia;
|
||||
|
||||
if (!strcmp(gbh->name, SF_BOOT_NAME))
|
||||
bootmedia = "Serial NOR";
|
||||
else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
|
||||
bootmedia = "eMMC";
|
||||
else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
|
||||
bootmedia = "SD/MMC";
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (print)
|
||||
printf("Boot Media: %s\n", bootmedia);
|
||||
|
||||
if (le32_to_cpu(gbh->version) != 1 ||
|
||||
le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
|
||||
return -1;
|
||||
|
||||
bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
|
||||
|
||||
if (strcmp(bh->name, BRLYT_NAME))
|
||||
return -1;
|
||||
|
||||
if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
|
||||
(le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
|
||||
le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
|
||||
le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
|
||||
return -1;
|
||||
|
||||
gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
|
||||
|
||||
if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
|
||||
return -1;
|
||||
|
||||
if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
|
||||
return -1;
|
||||
|
||||
if (print)
|
||||
printf("Load Address: %08x\n",
|
||||
le32_to_cpu(gfh->file_info.load_addr) +
|
||||
le32_to_cpu(gfh->file_info.jump_offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
|
||||
{
|
||||
union nand_boot_header *nh = (union nand_boot_header *)ptr;
|
||||
struct brom_layout_header *bh;
|
||||
struct gfh_header *gfh;
|
||||
const char *bootmedia;
|
||||
|
||||
if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
|
||||
strcmp(nh->id, NAND_BOOT_ID))
|
||||
return -1;
|
||||
|
||||
bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
|
||||
|
||||
if (strcmp(bh->name, BRLYT_NAME))
|
||||
return -1;
|
||||
|
||||
if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
|
||||
return -1;
|
||||
} else {
|
||||
if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
|
||||
bootmedia = "Parallel NAND";
|
||||
else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
|
||||
bootmedia = "Serial NAND";
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
printf("Boot Media: %s\n", bootmedia);
|
||||
|
||||
if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
|
||||
uint64_t capacity =
|
||||
(uint64_t)le16_to_cpu(nh->numblocks) *
|
||||
(uint64_t)le16_to_cpu(nh->pages_of_block) *
|
||||
(uint64_t)le16_to_cpu(nh->pagesize) * 8;
|
||||
printf("Capacity: %dGb\n",
|
||||
(uint32_t)(capacity >> 30));
|
||||
}
|
||||
|
||||
if (le16_to_cpu(nh->pagesize) >= 1024)
|
||||
printf("Page Size: %dKB\n",
|
||||
le16_to_cpu(nh->pagesize) >> 10);
|
||||
else
|
||||
printf("Page Size: %dB\n",
|
||||
le16_to_cpu(nh->pagesize));
|
||||
|
||||
printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
|
||||
}
|
||||
|
||||
gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
|
||||
|
||||
if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
|
||||
return -1;
|
||||
|
||||
if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
|
||||
return -1;
|
||||
|
||||
if (print)
|
||||
printf("Load Address: %08x\n",
|
||||
le32_to_cpu(gfh->file_info.load_addr) +
|
||||
le32_to_cpu(gfh->file_info.jump_offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_image_verify_header(unsigned char *ptr, int image_size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
union lk_hdr *lk = (union lk_hdr *)ptr;
|
||||
|
||||
/* nothing to verify for LK image header */
|
||||
if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
|
||||
return 0;
|
||||
|
||||
if (!strcmp((char *)ptr, NAND_BOOT_NAME))
|
||||
return mtk_image_verify_nand_header(ptr, 0);
|
||||
else
|
||||
return mtk_image_verify_gen_header(ptr, 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void mtk_image_print_header(const void *ptr)
|
||||
{
|
||||
union lk_hdr *lk = (union lk_hdr *)ptr;
|
||||
|
||||
if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
|
||||
printf("Image Type: MediaTek LK Image\n");
|
||||
printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Image Type: MediaTek BootROM Loadable Image\n");
|
||||
|
||||
if (!strcmp((char *)ptr, NAND_BOOT_NAME))
|
||||
mtk_image_verify_nand_header(ptr, 1);
|
||||
else
|
||||
mtk_image_verify_gen_header(ptr, 1);
|
||||
}
|
||||
|
||||
static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
|
||||
{
|
||||
strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
|
||||
hdr->version = cpu_to_le32(1);
|
||||
hdr->magic = cpu_to_le32(BRLYT_MAGIC);
|
||||
hdr->type = cpu_to_le32(type);
|
||||
}
|
||||
|
||||
static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
|
||||
int type, int ver)
|
||||
{
|
||||
memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
|
||||
gfh->version = ver;
|
||||
gfh->size = cpu_to_le16(size);
|
||||
gfh->type = cpu_to_le16(type);
|
||||
}
|
||||
|
||||
static void put_ghf_header(struct gfh_header *gfh, int file_size,
|
||||
int dev_hdr_size, int load_addr, int flash_type)
|
||||
{
|
||||
memset(gfh, 0, sizeof(struct gfh_header));
|
||||
|
||||
/* GFH_FILE_INFO header */
|
||||
put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
|
||||
GFH_TYPE_FILE_INFO, 1);
|
||||
strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
|
||||
sizeof(gfh->file_info.name));
|
||||
gfh->file_info.unused = cpu_to_le32(1);
|
||||
gfh->file_info.file_type = cpu_to_le16(1);
|
||||
gfh->file_info.flash_type = flash_type;
|
||||
gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
|
||||
gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
|
||||
gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
|
||||
gfh->file_info.max_size = cpu_to_le32(file_size);
|
||||
gfh->file_info.hdr_size = sizeof(*gfh);
|
||||
gfh->file_info.sig_size = SHA256_SUM_LEN;
|
||||
gfh->file_info.jump_offset = sizeof(*gfh);
|
||||
gfh->file_info.processed = cpu_to_le32(1);
|
||||
|
||||
/* GFH_BL_INFO header */
|
||||
put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
|
||||
GFH_TYPE_BL_INFO, 1);
|
||||
gfh->bl_info.attr = cpu_to_le32(1);
|
||||
|
||||
/* GFH_BROM_CFG header */
|
||||
put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
|
||||
GFH_TYPE_BROM_CFG, 3);
|
||||
gfh->brom_cfg.cfg_bits = cpu_to_le32(
|
||||
GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
|
||||
GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
|
||||
GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN);
|
||||
gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
|
||||
|
||||
/* GFH_BL_SEC_KEY header */
|
||||
put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
|
||||
GFH_TYPE_BL_SEC_KEY, 1);
|
||||
|
||||
/* GFH_ANTI_CLONE header */
|
||||
put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
|
||||
GFH_TYPE_ANTI_CLONE, 1);
|
||||
gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
|
||||
gfh->anti_clone.ac_len = cpu_to_le32(0x80);
|
||||
|
||||
/* GFH_BROM_SEC_CFG header */
|
||||
put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
|
||||
sizeof(gfh->brom_sec_cfg),
|
||||
GFH_TYPE_BROM_SEC_CFG, 1);
|
||||
gfh->brom_sec_cfg.cfg_bits =
|
||||
cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
|
||||
}
|
||||
|
||||
static void put_hash(uint8_t *buff, int size)
|
||||
{
|
||||
sha256_context ctx;
|
||||
|
||||
sha256_starts(&ctx);
|
||||
sha256_update(&ctx, buff, size);
|
||||
sha256_finish(&ctx, buff + size);
|
||||
}
|
||||
|
||||
static void mtk_image_set_gen_header(void *ptr, off_t filesize,
|
||||
uint32_t loadaddr)
|
||||
{
|
||||
struct gen_device_header *hdr = (struct gen_device_header *)ptr;
|
||||
struct gfh_header *gfh;
|
||||
const char *bootname = NULL;
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_NOR)
|
||||
bootname = SF_BOOT_NAME;
|
||||
else if (hdr_media == BRLYT_TYPE_EMMC)
|
||||
bootname = EMMC_BOOT_NAME;
|
||||
else if (hdr_media == BRLYT_TYPE_SDMMC)
|
||||
bootname = SDMMC_BOOT_NAME;
|
||||
|
||||
/* Generic device header */
|
||||
strncpy(hdr->boot.name, bootname, sizeof(hdr->boot.name));
|
||||
hdr->boot.version = cpu_to_le32(1);
|
||||
hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
|
||||
|
||||
/* BRLYT header */
|
||||
put_brom_layout_header(&hdr->brlyt, hdr_media);
|
||||
hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
|
||||
hdr->brlyt.total_size = cpu_to_le32(filesize);
|
||||
hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
|
||||
hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
|
||||
|
||||
/* GFH header */
|
||||
gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
|
||||
put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
|
||||
loadaddr, GFH_FLASH_TYPE_GEN);
|
||||
|
||||
/* Generate SHA256 hash */
|
||||
put_hash((uint8_t *)gfh,
|
||||
filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
|
||||
}
|
||||
|
||||
static void mtk_image_set_nand_header(void *ptr, off_t filesize,
|
||||
uint32_t loadaddr)
|
||||
{
|
||||
union nand_boot_header *nh = (union nand_boot_header *)ptr;
|
||||
struct brom_layout_header *brlyt;
|
||||
struct gfh_header *gfh;
|
||||
uint32_t payload_pages;
|
||||
int i;
|
||||
|
||||
/* NAND device header, repeat 4 times */
|
||||
for (i = 0; i < 4; i++)
|
||||
memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
|
||||
|
||||
/* BRLYT header */
|
||||
payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
|
||||
le16_to_cpu(hdr_nand->pagesize);
|
||||
brlyt = (struct brom_layout_header *)
|
||||
(ptr + le16_to_cpu(hdr_nand->pagesize));
|
||||
put_brom_layout_header(brlyt, hdr_media);
|
||||
brlyt->header_size = cpu_to_le32(2);
|
||||
brlyt->total_size = cpu_to_le32(payload_pages);
|
||||
brlyt->header_size_2 = brlyt->header_size;
|
||||
brlyt->total_size_2 = brlyt->total_size;
|
||||
brlyt->unused = cpu_to_le32(1);
|
||||
|
||||
/* GFH header */
|
||||
gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
|
||||
put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
|
||||
loadaddr, GFH_FLASH_TYPE_NAND);
|
||||
|
||||
/* Generate SHA256 hash */
|
||||
put_hash((uint8_t *)gfh,
|
||||
filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
|
||||
}
|
||||
|
||||
static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
union lk_hdr *lk = (union lk_hdr *)ptr;
|
||||
|
||||
if (use_lk_hdr) {
|
||||
lk->magic = cpu_to_le32(LK_PART_MAGIC);
|
||||
lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
|
||||
lk->loadaddr = cpu_to_le32(params->addr);
|
||||
lk->mode = 0xffffffff; /* must be non-zero */
|
||||
memset(lk->name, 0, sizeof(lk->name));
|
||||
strncpy(lk->name, lk_name, sizeof(lk->name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
|
||||
mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
|
||||
else
|
||||
mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
|
||||
}
|
||||
|
||||
U_BOOT_IMAGE_TYPE(
|
||||
mtk_image,
|
||||
"MediaTek BootROM Loadable Image support",
|
||||
0,
|
||||
NULL,
|
||||
mtk_image_check_params,
|
||||
mtk_image_verify_header,
|
||||
mtk_image_print_header,
|
||||
mtk_image_set_header,
|
||||
NULL,
|
||||
mtk_image_check_image_types,
|
||||
NULL,
|
||||
mtk_image_vrec_header
|
||||
);
|
199
tools/mtk_image.h
Normal file
199
tools/mtk_image.h
Normal file
@ -0,0 +1,199 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* MediaTek BootROM header definitions
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MTK_IMAGE_H
|
||||
#define _MTK_IMAGE_H
|
||||
|
||||
/* Device header definitions */
|
||||
|
||||
/* Header for NOR/SD/eMMC */
|
||||
union gen_boot_header {
|
||||
struct {
|
||||
char name[12];
|
||||
__le32 version;
|
||||
__le32 size;
|
||||
};
|
||||
|
||||
uint8_t pad[0x200];
|
||||
};
|
||||
|
||||
#define EMMC_BOOT_NAME "EMMC_BOOT"
|
||||
#define SF_BOOT_NAME "SF_BOOT"
|
||||
#define SDMMC_BOOT_NAME "SDMMC_BOOT"
|
||||
|
||||
/* Header for NAND */
|
||||
union nand_boot_header {
|
||||
struct {
|
||||
char name[12];
|
||||
char version[4];
|
||||
char id[8];
|
||||
__le16 ioif;
|
||||
__le16 pagesize;
|
||||
__le16 addrcycles;
|
||||
__le16 oobsize;
|
||||
__le16 pages_of_block;
|
||||
__le16 numblocks;
|
||||
__le16 writesize_shift;
|
||||
__le16 erasesize_shift;
|
||||
uint8_t dummy[60];
|
||||
uint8_t ecc_parity[28];
|
||||
};
|
||||
|
||||
uint8_t data[0x80];
|
||||
};
|
||||
|
||||
#define NAND_BOOT_NAME "BOOTLOADER!"
|
||||
#define NAND_BOOT_VERSION "V006"
|
||||
#define NAND_BOOT_ID "NFIINFO"
|
||||
|
||||
/* BootROM layout header */
|
||||
struct brom_layout_header {
|
||||
char name[8];
|
||||
__le32 version;
|
||||
__le32 header_size;
|
||||
__le32 total_size;
|
||||
__le32 magic;
|
||||
__le32 type;
|
||||
__le32 header_size_2;
|
||||
__le32 total_size_2;
|
||||
__le32 unused;
|
||||
};
|
||||
|
||||
#define BRLYT_NAME "BRLYT"
|
||||
#define BRLYT_MAGIC 0x42424242
|
||||
|
||||
enum brlyt_img_type {
|
||||
BRLYT_TYPE_INVALID = 0,
|
||||
BRLYT_TYPE_NAND = 0x10002,
|
||||
BRLYT_TYPE_EMMC = 0x10005,
|
||||
BRLYT_TYPE_NOR = 0x10007,
|
||||
BRLYT_TYPE_SDMMC = 0x10008,
|
||||
BRLYT_TYPE_SNAND = 0x10009
|
||||
};
|
||||
|
||||
/* Combined device header for NOR/SD/eMMC */
|
||||
struct gen_device_header {
|
||||
union gen_boot_header boot;
|
||||
|
||||
union {
|
||||
struct brom_layout_header brlyt;
|
||||
uint8_t brlyt_pad[0x400];
|
||||
};
|
||||
};
|
||||
|
||||
/* BootROM header definitions */
|
||||
struct gfh_common_header {
|
||||
uint8_t magic[3];
|
||||
uint8_t version;
|
||||
__le16 size;
|
||||
__le16 type;
|
||||
};
|
||||
|
||||
#define GFH_HEADER_MAGIC "MMM"
|
||||
|
||||
#define GFH_TYPE_FILE_INFO 0
|
||||
#define GFH_TYPE_BL_INFO 1
|
||||
#define GFH_TYPE_BROM_CFG 7
|
||||
#define GFH_TYPE_BL_SEC_KEY 3
|
||||
#define GFH_TYPE_ANTI_CLONE 2
|
||||
#define GFH_TYPE_BROM_SEC_CFG 8
|
||||
|
||||
struct gfh_file_info {
|
||||
struct gfh_common_header gfh;
|
||||
char name[12];
|
||||
__le32 unused;
|
||||
__le16 file_type;
|
||||
uint8_t flash_type;
|
||||
uint8_t sig_type;
|
||||
__le32 load_addr;
|
||||
__le32 total_size;
|
||||
__le32 max_size;
|
||||
__le32 hdr_size;
|
||||
__le32 sig_size;
|
||||
__le32 jump_offset;
|
||||
__le32 processed;
|
||||
};
|
||||
|
||||
#define GFH_FILE_INFO_NAME "FILE_INFO"
|
||||
|
||||
#define GFH_FLASH_TYPE_GEN 5
|
||||
#define GFH_FLASH_TYPE_NAND 2
|
||||
|
||||
#define GFH_SIG_TYPE_NONE 0
|
||||
#define GFH_SIG_TYPE_SHA256 1
|
||||
|
||||
struct gfh_bl_info {
|
||||
struct gfh_common_header gfh;
|
||||
__le32 attr;
|
||||
};
|
||||
|
||||
struct gfh_brom_cfg {
|
||||
struct gfh_common_header gfh;
|
||||
__le32 cfg_bits;
|
||||
__le32 usbdl_by_auto_detect_timeout_ms;
|
||||
uint8_t unused[0x48];
|
||||
__le32 usbdl_by_kcol0_timeout_ms;
|
||||
__le32 usbdl_by_flag_timeout_ms;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
#define GFH_BROM_CFG_USBDL_BY_AUTO_DETECT_TIMEOUT_EN 0x02
|
||||
#define GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS 0x10
|
||||
#define GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN 0x80
|
||||
#define GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN 0x100
|
||||
|
||||
struct gfh_bl_sec_key {
|
||||
struct gfh_common_header gfh;
|
||||
uint8_t pad[0x20c];
|
||||
};
|
||||
|
||||
struct gfh_anti_clone {
|
||||
struct gfh_common_header gfh;
|
||||
uint8_t ac_b2k;
|
||||
uint8_t ac_b2c;
|
||||
uint16_t pad;
|
||||
__le32 ac_offset;
|
||||
__le32 ac_len;
|
||||
};
|
||||
|
||||
struct gfh_brom_sec_cfg {
|
||||
struct gfh_common_header gfh;
|
||||
__le32 cfg_bits;
|
||||
char customer_name[0x20];
|
||||
__le32 pad;
|
||||
};
|
||||
|
||||
#define BROM_SEC_CFG_JTAG_EN 1
|
||||
#define BROM_SEC_CFG_UART_EN 2
|
||||
|
||||
struct gfh_header {
|
||||
struct gfh_file_info file_info;
|
||||
struct gfh_bl_info bl_info;
|
||||
struct gfh_brom_cfg brom_cfg;
|
||||
struct gfh_bl_sec_key bl_sec_key;
|
||||
struct gfh_anti_clone anti_clone;
|
||||
struct gfh_brom_sec_cfg brom_sec_cfg;
|
||||
};
|
||||
|
||||
/* LK image header */
|
||||
|
||||
union lk_hdr {
|
||||
struct {
|
||||
__le32 magic;
|
||||
__le32 size;
|
||||
char name[32];
|
||||
__le32 loadaddr;
|
||||
__le32 mode;
|
||||
};
|
||||
|
||||
uint8_t data[512];
|
||||
};
|
||||
|
||||
#define LK_PART_MAGIC 0x58881688
|
||||
|
||||
#endif /* _MTK_IMAGE_H */
|
Loading…
Reference in New Issue
Block a user