Bananapi R2 (#1151)

* Initial commit BPi R2:
Currently working/not working:
- u-boot:
	- builds with minor issues
	- patching and cleanup happens on 'https://github.com/chwe17/u-boot-mt'
- next (https://github.com/frank-w/BPI-R2-4.14)
	- boots with minor issues
	- ETH doesn't work with nm
	- sata works
	- no wifi (needs driver from: https://github.com/frank-w/BPI-R2-4.4)
	- USB not working (xhci-mtk 1a1c0000.usb: fail to get vbus) needs investigation
	- appended device tree is needed due to u-boot doesn't work with fdt (kernelpacking needs adjustemts e.g. cat zImage dtb > zImage-dtb
- dev (kernel.org master)
	- untested, needs adjustments in config (e.g. CONFIG_LOCALVERSION="")
	- since no defconfig is available config is based on frank-w 4.16 Kernel
	- Kernel builds without issues
	- manual packing of kernel and dtb similar to next
The board boots, serial console is available but everything else must be expected as not working!
- to do:
	- u-boot needs a cleanup
	- binary blobs needs investigation
	- eMMC is **not tested** and needs for sure adjustements! (don't try nand-sata-install!!!)
	- bootscript isn't tested (only manual boot over u-boot console at the moment)
	- both kernelconfigs aren't 'armbian standard' modules need to be adjusted

Only use it when you know're familiar with u-boot commands!

* Small fixes, add bootscript
- add bootscript for patched u-boot (needs patching of u-boot, currently under investigation and not working properly)
- revert cat zImage dtb > zImage-dtb (cause not working)
- first cleanup of dev kernelconfig (remove CONFIG_LOCALVERSION="")

* Minor fixup
-kernelconfig for next was adjustet so that USB is recognized
-firt bootscripts was written to boot with source command (doesn't work 100% reliable)
-slightly adjustd boardconfig (e.g. bootscript)
must still be considered as early wip!

* small update (FDT works now)
-working bootscript
-adjusted boardconfig
-earlyprintk activated in kernelconfig

* First attempt to get ETH working
-all interfaces are bridged together
-performance sucks at the moment (not clear if it's related to insane network configuration or I miss something obvious... :P  )

* Major update (see below for changes):
- 4.14 kernel was dropped due to https://forum.armbian.com/topic/7296-bananapi-r2-csc-mt7623-as-new-boardfamily/?do=findComment&comment=55194 and following
	- boot.cmd was adjusted to 'clean' mainline behaviour
	- next build opition and its defaultconfg was removed (at the moment dev only)
- rework of the network default configuration
	- default configuration will be over network.d **not** NetworkManager
	- per default all wired interfaces are bridged together to br0 (still wip)
	- old 'interfaces' configuration was removed
- boardconfig is adjusted (no desktop until I've prove that HDMI works)
- what works/ not works:
	- board boots up without manual u-boot hacking
	- SATA, USB3 (massstorage) is tested and works without issues
	- due to rework of network configuration this is still wip and must be considered as 'not working'

* moved to network.d for configuration of wired network
- renamed bsp packages
- blacklist wired interfaces for NetworkManager
- defined all wired interfaces as br0 in systemd/network
- defined networkd als default renderer for bionic (not tested yet!)

* The houskeeping commit:
- BOARDFAMILY was renamed to mt7623 instead of mt7623n (including patchfolders etc.)
- Network.d has no fully control over wired networkes (block NM from controll, start networkd on firstrun etc.)
- Further cleanup kernelconfig
	- CPU temp is visible from userspace
	- missed switch driver loaded
	- cryptodrivers are there (not tested)
	- still a bunch of work

* Add DMA mem alloc patch
-under testing!

* Add next option (4.17.y) stick dev to master (4.18-rc1 untested)

* minor fixes:
- solve kconfig issues between 4.17 and 4.18
- stick next branch to 4.18
- first attempts to bring up gmac2 (doesn't work currently)

* switch to upstream u-boot
- fix ext4 dependency in patch series
- kernelpacking currently broken

* add bootz & cmd_ext4

* resolved merge conflict

* apply ugly u-boot patch, fix bootscript

* remove unneeded stuff, apply forgotten stuff

* update config for dev & clean up boardconf (remove xenial)

* - drop dev and next, move into default. There is no intention to provide stock kernel
- fixed board description, renamed to WIP, where it can be merged later
- packing boot firmware to the u-boot package
- docker dependencies (aufs will be added later. not essential)
- attached to 4.19.y
- loading armbianEnv.txt
- UUID support (tested)
- enabled ZRAM (tested)
- enabled eMMC install (not quite working properly yet)
- Bionic has some issues with systemd networking.

* gov to ondemand (thermals are conservative anyway), remove unneeded kernelconfigs

* Added AUFS, remove debug from kernel boot parameters, add ath10 mPCI support (which works)

* add power-off-key and rtc

* Added onboard wireless, but it's enabling is disabled by default. Too fragile.

* Change to CSC target
This commit is contained in:
Igor Pečovnik 2018-11-08 18:51:42 +01:00 committed by GitHub
parent fc77b6f947
commit efa87b1fb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 1274094 additions and 1 deletions

View file

@ -0,0 +1 @@
verbosity=1

View file

@ -0,0 +1,26 @@
# DO NOT EDIT THIS FILE
#
# Please edit /boot/armbianEnv.txt to set supported parameters
#
setenv rootdev "/dev/mmcblk1p1"
setenv rootfs "ext4"
setenv verbosity "1"
setenv devtype "mmc"
setenv prefix "boot/"
echo "Boot script loaded from device ${devnum}"
if test -e ${devtype} ${devnum} ${prefix}armbianEnv.txt; then
load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}armbianEnv.txt
env import -t ${kernel_addr_r} ${filesize}
fi
setenv bootargs "console=ttyS2,115200n1 root=${rootdev} rw rootfstype=${rootfs} rootwait audit=0 loglevel=${verbosity}"
ext4load ${devtype} ${devnum}:${mmcpart} ${fdtaddr} ${mmcfdtfile}
ext4load ${devtype} ${devnum}:${mmcpart} ${rdaddr} ${mmcinitrdfile}
ext4load ${devtype} ${devnum}:${mmcpart} ${kernel_addr_r} ${mmckernfile}
echo "Booting ${mmckernfile} ${mmcinitrdfile} ${mmcfdtfile} from: ${devtype} ${devnum}:${mmcpart} using bootargs=${bootargs}"
bootz ${kernel_addr_r} ${rdaddr} ${fdtaddr}
# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
BOOTSCRIPT='boot-mt7623.cmd:boot.cmd'
BOOTENV_FILE='mt7623-default.txt'
UBOOT_TARGET_MAP=";;$SRC/packages/blobs/mt7623n/BPI-R2-HEAD440-0k.img $SRC/packages/blobs/mt7623n/BPI-R2-HEAD1-512b.img $SRC/packages/blobs/mt7623n/BPI-R2-preloader-2k.img u-boot.bin"
UBOOT_USE_GCC='> 7.0'
BOOTSOURCE=$MAINLINE_UBOOT_SOURCE
BOOTDIR=$MAINLINE_UBOOT_DIR
BOOTBRANCH='tag:v2018.11-rc1'
BOOTPATCHDIR='u-boot-mt7623'
case $BRANCH in
default)
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
#KERNELSOURCE="https://github.com/frank-w/BPI-R2-4.14"
KERNELBRANCH='branch:linux-4.19.y'
#KERNELBRANCH='branch:4.19-wifi_new'
KERNELDIR=$MAINLINE_KERNEL_DIR
KERNEL_USE_GCC='> 7.0'
;;
esac
CPUMIN=98000
CPUMAX=1300000
GOVERNOR="ondemand"
NM_IGNORE_DEVICES="interface-name:eth*,interface-name:wan*,interface-name:lan*,interface-name:br*"
write_uboot_platform()
{
dd if=$SRC/packages/blobs/mt7623n/BPI-R2-HEAD440-0k.img of=$2 bs=440 seek=0 count=1 status=noxfer > /dev/null 2>&1
dd if=$SRC/packages/blobs/mt7623n/BPI-R2-HEAD1-512b.img of=$2 bs=512 seek=1 status=noxfer > /dev/null 2>&1
dd if=$SRC/packages/blobs/mt7623n/BPI-R2-preloader-2k.img of=$2 bs=1k seek=2 status=noxfer > /dev/null 2>&1
dd if=$1/u-boot.bin of=$2 bs=1k seek=320 status=noxfer > /dev/null 2>&1
}
family_tweaks()
{
[[ -f $SDCARD/etc/netplan/armbian-default.yaml ]] && sed -i "s/^ renderer.*/ renderer: networkd/" $SDCARD/etc/netplan/armbian-default.yaml
cp $SRC/packages/bsp/mt7623/mt7623-wifi.service $SDCARD/lib/systemd/system/
install -m 755 $SRC/packages/bsp/mt7623/mt7623-wifi.bash $SDCARD/usr/local/bin/mt7623-wifi.bash
# very unstable wifi driver, disabled by default http://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:wlan#internal
# chroot $SDCARD /bin/bash -c "systemctl --no-reload enable mt7623-wifi.service >/dev/null 2>&1"
cp $SRC/packages/bsp/mt7623/10* $SDCARD/etc/systemd/network/
cp $SRC/packages/blobs/mt7623n/wireless/{stp_uart_launcher,wmt_loader,wmt_loopback} $SDCARD/usr/local/bin
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@
https://github.com/BPI-SINOVOIP/BPI-R2-bsp/tree/master/vendor/mediatek/connectivity/tools/binary

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -110,7 +110,8 @@ case "$1" in
# trigger red or blue LED as user feedback
echo heartbeat >/sys/class/leds/*red*/trigger 2>/dev/null || echo heartbeat >/sys/class/leds/*blue*/trigger 2>/dev/null
;;
mvebu64)
mvebu64|mt7623)
# configure/enable/start systemd-networkd
systemctl start systemd-networkd.service
systemctl start systemd-resolved.service

View file

@ -0,0 +1,3 @@
[NetDev]
Name=br0
Kind=bridge

View file

@ -0,0 +1,5 @@
[Match]
Name=br0
[Network]
DHCP=yes

View file

@ -0,0 +1,5 @@
[Match]
Name=eth0
[Network]
DHCP=yes

View file

@ -0,0 +1,5 @@
[Match]
Name=lan0
[Network]
Bridge=br0

View file

@ -0,0 +1,5 @@
[Match]
Name=lan1
[Network]
Bridge=br0

View file

@ -0,0 +1,5 @@
[Match]
Name=lan2
[Network]
Bridge=br0

View file

@ -0,0 +1,5 @@
[Match]
Name=lan3
[Network]
Bridge=br0

View file

@ -0,0 +1,5 @@
[Match]
Name=wan
[Network]
Bridge=br0

View file

@ -0,0 +1,6 @@
#!/bin/bash
/usr/local/bin/wmt_loader &
sleep 3
/usr/local/bin/stp_uart_launcher -p /lib/firmware/mediatek &
sleep 3
/bin/echo A >/dev/wmtWifi

View file

@ -0,0 +1,14 @@
[Unit]
Description=MT7623 Wireless
DefaultDependencies=no
Wants=rsyslog.service systemd-journald.service
Before=syslog.target sysinit.target
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mt7623-wifi.bash
RemainAfterExit=no
[Install]
WantedBy=sysinit.target

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,842 @@
From 83ffbaceffed1cd47a6f67fb20e39737dfb2d01a Mon Sep 17 00:00:00 2001
From: Frank Wunderlich <frank-w@public-files.de>
Date: Tue, 28 Aug 2018 18:14:56 +0200
Subject: [PATCH] [wifi] adding wifi-related changes outside driver-directory
---
arch/arm/boot/dts/mt7623.dtsi | 41 +-
arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 42 ++
drivers/soc/mediatek/mtk-pmic-wrap.c | 12 +
drivers/watchdog/mtk_wdt.c | 377 +++++++++++++++++-
include/linux/wakelock.h | 67 ++++
include/net/genetlink.h | 44 ++
include/soc/mediatek/pmic_wrap.h | 19 +
include/uapi/linux/genetlink.h | 1 +
8 files changed, 588 insertions(+), 15 deletions(-)
create mode 100644 include/linux/wakelock.h
create mode 100644 include/soc/mediatek/pmic_wrap.h
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 04228cf9ddbbc..af6b6228f8a80 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -266,6 +266,8 @@
compatible = "mediatek,mt7623-wdt",
"mediatek,mt6589-wdt";
reg = <0 0x10007000 0 0x100>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_FALLING>;
+ #reset-cells = <1>;
};
timer: timer@10008000 {
@@ -494,13 +496,26 @@
"mediatek,mtk-btif";
reg = <0 0x1100c000 0 0x1000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&pericfg CLK_PERI_BTIF>;
- clock-names = "main";
+ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>;
+ clock-names = "main", "apdmac";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
+ btif_tx: btif_tx@11000780 {
+ compatible = "mediatek,btif_tx";
+ reg = <0 0x11000780 0 0x80>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+ };
+ btif_rx: btif_rx@11000800 {
+ compatible = "mediatek,btif_rx";
+ reg = <0 0x11000800 0 0x80>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
+ status = "okay";
+ };
+
nandc: nfi@1100d000 {
compatible = "mediatek,mt7623-nfc",
"mediatek,mt2701-nfc";
@@ -683,6 +698,28 @@
status = "disabled";
};
+ consys: consys@18070000 {
+ compatible = "mediatek,mt7623-consys";
+ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */
+ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */
+ clocks = <&infracfg CLK_INFRA_CONNMCU>;
+ clock-names = "consysbus";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>, /* BGF_EINT */
+ <GIC_SPI 163 IRQ_TYPE_LEVEL_LOW>; /* WDT_EINT */
+ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>;
+ reset-names = "connsys";
+ status="disabled";
+ };
+ wifi:wifi@180f0000 {
+ compatible = "mediatek,mt7623-wifi",
+ "mediatek,wifi";
+ reg = <0 0x180f0000 0 0x005c>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_AP_DMA>;
+ clock-names = "wifi-dma";
+ };
+
hifsys: syscon@1a000000 {
compatible = "mediatek,mt7623-hifsys",
"mediatek,mt2701-hifsys",
diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
index 2b760f90f38c8..465fb887b2ca6 100644
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -84,6 +84,18 @@
};
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ consys-reserve-memory {
+ compatible = "mediatek,consys-reserve-memory";
+ no-map;
+ size = <0 0x100000>;
+ alignment = <0 0x100000>;
+ };
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -259,6 +271,36 @@
};
};
+&pio {
+ consys_pins_default: consys_pins_default {
+ adie {
+ pinmux = <MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB>,
+ <MT7623_PIN_61_GPIO61_FUNC_TEST_FD>,
+ <MT7623_PIN_62_GPIO62_FUNC_TEST_FC>,
+ <MT7623_PIN_63_WB_SCLK_FUNC_WB_SCLK>,
+ <MT7623_PIN_64_WB_SDATA_FUNC_WB_SDATA>,
+ <MT7623_PIN_65_WB_SEN_FUNC_WB_SEN>,
+ <MT7623_PIN_66_WB_CRTL0_FUNC_WB_CRTL0>,
+ <MT7623_PIN_67_WB_CRTL1_FUNC_WB_CRTL1>,
+ <MT7623_PIN_68_WB_CRTL2_FUNC_WB_CRTL2>,
+ <MT7623_PIN_69_WB_CRTL3_FUNC_WB_CRTL3>,
+ <MT7623_PIN_70_WB_CRTL4_FUNC_WB_CRTL4>,
+ <MT7623_PIN_71_WB_CRTL5_FUNC_WB_CRTL5>;
+ bias-disable;
+ };
+ };
+};
+&consys {
+ mediatek,pwrap-regmap = <&pwrap>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&consys_pins_default>;
+ vcn18-supply = <&mt6323_vcn18_reg>;
+ vcn28-supply = <&mt6323_vcn28_reg>;
+ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>;
+ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>;
+ status = "okay";
+};
+
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_default>;
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 4e931fdf4d091..6600396ee2993 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -1530,6 +1530,18 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
};
MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
+struct regmap *pwrap_node_to_regmap(struct device_node *np)
+{
+ struct platform_device *pdev;
+ struct pmic_wrapper *wrp;
+ pdev = of_find_device_by_node(np);
+ if (!pdev)
+ return ERR_PTR(-ENODEV);
+ wrp = platform_get_drvdata(pdev);
+ return wrp->regmap;
+}
+EXPORT_SYMBOL_GPL(pwrap_node_to_regmap);
+
static int pwrap_probe(struct platform_device *pdev)
{
int ret, irq;
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 4baf64f21aa11..6a361f808aed1 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: GPL-2.0+
/*
* Mediatek Watchdog Driver
*
@@ -6,20 +5,51 @@
*
* Matthias Brugger <matthias.bgg@gmail.com>
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
* Based on sunxi_wdt.c
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#ifdef CONFIG_FIQ_GLUE
+#include <linux/irqchip/mtk-gic-extend.h>
+#include <mt-plat/aee.h>
+#endif
#include <linux/types.h>
#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
#include <linux/delay.h>
+#include <linux/reset-controller.h>
+#include <linux/reset.h>
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
+#include <asm/system_misc.h>
+#include <linux/seq_file.h>
+#ifdef CONFIG_MT6397_MISC
+#include <linux/mfd/mt6397/rtc_misc.h>
+#endif
#define WDT_MAX_TIMEOUT 31
#define WDT_MIN_TIMEOUT 1
@@ -38,37 +68,167 @@
#define WDT_MODE_EXRST_EN (1 << 2)
#define WDT_MODE_IRQ_EN (1 << 3)
#define WDT_MODE_AUTO_START (1 << 4)
+#define WDT_MODE_IRQ_LVL (1 << 5)
#define WDT_MODE_DUAL_EN (1 << 6)
#define WDT_MODE_KEY 0x22000000
+#define WDT_STATUS 0x0c
+#define WDT_NONRST_REG 0x20
+#define WDT_NONRST_REG2 0x24
+
#define WDT_SWRST 0x14
#define WDT_SWRST_KEY 0x1209
+#define WDT_SWSYSRST 0x18
+#define WDT_SWSYSRST_KEY 0x88000000
+
+#define WDT_REQ_MODE 0x30
+#define WDT_REQ_MODE_KEY 0x33000000
+#define WDT_REQ_IRQ_EN 0x34
+#define WDT_REQ_IRQ_KEY 0x44000000
+#define WDT_REQ_MODE_DEBUG_EN 0x80000
+
+
#define DRV_NAME "mtk-wdt"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "2.0"
static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int timeout;
+static unsigned int timeout = WDT_MAX_TIMEOUT;
+
+struct toprgu_reset {
+ spinlock_t lock;
+ void __iomem *toprgu_swrst_base;
+ int regofs;
+ struct reset_controller_dev rcdev;
+};
struct mtk_wdt_dev {
struct watchdog_device wdt_dev;
void __iomem *wdt_base;
+ int wdt_irq_id;
+ struct notifier_block restart_handler;
+ struct toprgu_reset reset_controller;
};
-static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
- unsigned long action, void *data)
+static void __iomem *toprgu_base;
+static struct watchdog_device *wdt_dev;
+
+static int toprgu_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
{
- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ unsigned int tmp;
+ unsigned long flags;
+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev);
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs);
+ tmp |= BIT(id);
+ tmp |= WDT_SWSYSRST_KEY;
+ writel(tmp, data->toprgu_swrst_base + data->regofs);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ return 0;
+}
+
+static int toprgu_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ unsigned int tmp;
+ unsigned long flags;
+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev);
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs);
+ tmp &= ~BIT(id);
+ tmp |= WDT_SWSYSRST_KEY;
+ writel(tmp, data->toprgu_swrst_base + data->regofs);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ return 0;
+}
+
+static int toprgu_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = toprgu_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return toprgu_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops toprgu_reset_ops = {
+ .assert = toprgu_reset_assert,
+ .deassert = toprgu_reset_deassert,
+ .reset = toprgu_reset,
+};
+
+static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs)
+{
+ int ret;
+ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
+
+ spin_lock_init(&mtk_wdt->reset_controller.lock);
+
+ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base;
+ mtk_wdt->reset_controller.regofs = regofs;
+ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE;
+ mtk_wdt->reset_controller.rcdev.nr_resets = 15;
+ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops;
+ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node;
+
+ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev);
+ if (ret)
+ pr_err("could not register toprgu reset controller: %d\n", ret);
+}
+
+static int mtk_reset_handler(struct notifier_block *this, unsigned long mode,
+ void *cmd)
+{
+ struct mtk_wdt_dev *mtk_wdt;
void __iomem *wdt_base;
+ u32 reg;
+ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler);
wdt_base = mtk_wdt->wdt_base;
- while (1) {
- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
- mdelay(5);
+ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG,
+ * and then print it out in mtk_wdt_probe() after reset
+ */
+ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG);
+
+ reg = ioread32(wdt_base + WDT_MODE);
+ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN);
+ reg |= WDT_MODE_KEY;
+ iowrite32(reg, wdt_base + WDT_MODE);
+
+ if (cmd && !strcmp(cmd, "rpmbpk")) {
+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2);
+ } else if (cmd && !strcmp(cmd, "recovery")) {
+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2);
+ #ifdef CONFIG_MT6397_MISC
+ mtk_misc_mark_recovery();
+ #endif
+ } else if (cmd && !strcmp(cmd, "bootloader")) {
+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2);
+ #ifdef CONFIG_MT6397_MISC
+ mtk_misc_mark_fast();
+ #endif
}
- return 0;
+ if (!arm_pm_restart) {
+ while (1) {
+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
+ mdelay(5);
+ }
+ }
+ return NOTIFY_DONE;
}
static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
@@ -77,6 +237,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
void __iomem *wdt_base = mtk_wdt->wdt_base;
iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST);
+ printk_deferred("[WDK]: kick Ex WDT\n");
return 0;
}
@@ -128,7 +289,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev)
return ret;
reg = ioread32(wdt_base + WDT_MODE);
- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
+ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN);
+ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH);
reg |= (WDT_MODE_EN | WDT_MODE_KEY);
iowrite32(reg, wdt_base + WDT_MODE);
@@ -148,13 +310,56 @@ static const struct watchdog_ops mtk_wdt_ops = {
.stop = mtk_wdt_stop,
.ping = mtk_wdt_ping,
.set_timeout = mtk_wdt_set_timeout,
- .restart = mtk_wdt_restart,
};
+#ifdef CONFIG_FIQ_GLUE
+static void wdt_fiq(void *arg, void *regs, void *svc_sp)
+{
+ unsigned int wdt_mode_val;
+ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base;
+
+ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS);
+ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG);
+
+ aee_wdt_fiq_info(arg, regs, svc_sp);
+}
+#else
+static void wdt_report_info(void)
+{
+ struct task_struct *task;
+
+ task = &init_task;
+ pr_debug("Qwdt: -- watchdog time out\n");
+
+ for_each_process(task) {
+ if (task->state == 0) {
+ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm);
+ show_stack(task, NULL);
+ pr_debug("\n");
+ }
+ }
+
+ pr_debug("backtrace of current task:\n");
+ show_stack(NULL, NULL);
+ pr_debug("Qwdt: -- watchdog time out\n");
+}
+
+static irqreturn_t mtk_wdt_isr(int irq, void *dev_id)
+{
+ pr_err("fwq mtk_wdt_isr\n");
+
+ wdt_report_info();
+ BUG();
+
+ return IRQ_HANDLED;
+}
+#endif
+
static int mtk_wdt_probe(struct platform_device *pdev)
{
struct mtk_wdt_dev *mtk_wdt;
struct resource *res;
+ unsigned int tmp;
int err;
mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL);
@@ -165,9 +370,32 @@ static int mtk_wdt_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+
if (IS_ERR(mtk_wdt->wdt_base))
return PTR_ERR(mtk_wdt->wdt_base);
+ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG));
+
+ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (!mtk_wdt->wdt_irq_id) {
+ pr_err("RGU get IRQ ID failed\n");
+ return -ENODEV;
+ }
+
+#ifndef CONFIG_FIQ_GLUE
+ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt);
+#else
+ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id);
+ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt);
+#endif
+ if (err != 0) {
+ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err);
+ return err;
+ }
+
+ toprgu_base = mtk_wdt->wdt_base;
+ wdt_dev = &mtk_wdt->wdt_dev;
+
mtk_wdt->wdt_dev.info = &mtk_wdt_info;
mtk_wdt->wdt_dev.ops = &mtk_wdt_ops;
mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
@@ -177,7 +405,6 @@ static int mtk_wdt_probe(struct platform_device *pdev)
watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev);
watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
@@ -187,9 +414,40 @@ static int mtk_wdt_probe(struct platform_device *pdev)
if (unlikely(err))
return err;
+ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler;
+ mtk_wdt->restart_handler.priority = 128;
+
+ if (arm_pm_restart) {
+ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n");
+ err = register_reboot_notifier(&mtk_wdt->restart_handler);
+ if (err != 0)
+ dev_warn(&pdev->dev,
+ "cannot register reboot notifier (err=%d)\n", err);
+ } else {
+ err = register_restart_handler(&mtk_wdt->restart_handler);
+ if (err)
+ dev_warn(&pdev->dev,
+ "cannot register restart handler (err=%d)\n", err);
+ }
+
dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
mtk_wdt->wdt_dev.timeout, nowayout);
+ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) &
+ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE);
+
+ toprgu_register_reset_controller(pdev, WDT_SWSYSRST);
+
+ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */
+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0);
+ tmp |= WDT_REQ_MODE_KEY;
+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE);
+
+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN);
+ tmp &= ~((1 << 18) | (1 << 0));
+ tmp |= WDT_REQ_IRQ_KEY;
+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN);
+
return 0;
}
@@ -205,8 +463,12 @@ static int mtk_wdt_remove(struct platform_device *pdev)
{
struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
+ unregister_restart_handler(&mtk_wdt->restart_handler);
+
watchdog_unregister_device(&mtk_wdt->wdt_dev);
+ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev);
+
return 0;
}
@@ -258,6 +520,95 @@ static struct platform_driver mtk_wdt_driver = {
module_platform_driver(mtk_wdt_driver);
+static int wk_proc_cmd_read(struct seq_file *s, void *v)
+{
+ unsigned int enabled = 1;
+
+ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN))
+ enabled = 0;
+
+ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout);
+
+ return 0;
+}
+
+static int wk_proc_cmd_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wk_proc_cmd_read, NULL);
+}
+
+static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data)
+{
+ int ret;
+ int enable;
+ int timeout;
+ char wk_cmd_buf[256];
+
+ if (count == 0)
+ return -1;
+
+ if (count > 255)
+ count = 255;
+
+ ret = copy_from_user(wk_cmd_buf, buf, count);
+ if (ret < 0)
+ return -1;
+
+ wk_cmd_buf[count] = '\0';
+
+ pr_debug("Write %s\n", wk_cmd_buf);
+
+ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout);
+ if (ret != 2)
+ pr_debug("%s: expect 2 numbers\n", __func__);
+
+ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout);
+
+ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) {
+ wdt_dev->timeout = timeout;
+ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
+ } else {
+ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n",
+ timeout, WDT_MAX_TIMEOUT);
+
+ }
+
+ if (enable == 1) {
+ mtk_wdt_start(wdt_dev);
+ set_bit(WDOG_ACTIVE, &wdt_dev->status);
+ pr_err("[WDK] enable wdt\n");
+ } else if (enable == 0) {
+ mtk_wdt_stop(wdt_dev);
+ clear_bit(WDOG_ACTIVE, &wdt_dev->status);
+ pr_err("[WDK] disable wdt\n");
+ }
+
+ return count;
+}
+
+static const struct file_operations wk_proc_cmd_fops = {
+ .owner = THIS_MODULE,
+ .open = wk_proc_cmd_open,
+ .read = seq_read,
+ .write = wk_proc_cmd_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init wk_proc_init(void)
+{
+ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops);
+
+ if (!de)
+ pr_err("[wk_proc_init]: create /proc/wdk failed\n");
+
+ pr_debug("[WDK] Initialize proc\n");
+
+ return 0;
+}
+
+late_initcall(wk_proc_init);
+
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds");
diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
new file mode 100644
index 0000000000000..f4a698a228803
--- /dev/null
+++ b/include/linux/wakelock.h
@@ -0,0 +1,67 @@
+/* include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/ktime.h>
+#include <linux/device.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend.
+ */
+
+enum {
+ WAKE_LOCK_SUSPEND, /* Prevent suspend */
+ WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+ struct wakeup_source ws;
+};
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+ const char *name)
+{
+ wakeup_source_init(&lock->ws, name);
+}
+
+static inline void wake_lock_destroy(struct wake_lock *lock)
+{
+ wakeup_source_trash(&lock->ws);
+}
+
+static inline void wake_lock(struct wake_lock *lock)
+{
+ __pm_stay_awake(&lock->ws);
+}
+
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout)
+{
+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout));
+}
+
+static inline void wake_unlock(struct wake_lock *lock)
+{
+ __pm_relax(&lock->ws);
+}
+
+static inline int wake_lock_active(struct wake_lock *lock)
+{
+ return lock->ws.active;
+}
+
+#endif
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index decf6012a4016..6471da92334ad 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -144,6 +144,50 @@ struct genl_ops {
};
int genl_register_family(struct genl_family *family);
+
+/**
+ * genl_register_family_with_ops - register a generic netlink family with ops
+ * @family: generic netlink family
+ * @ops: operations to be registered
+ * @n_ops: number of elements to register
+ *
+ * Registers the specified family and operations from the specified table.
+ * Only one family may be registered with the same family name or identifier.
+ *
+ * The family id may equal GENL_ID_GENERATE causing an unique id to
+ * be automatically generated and assigned.
+ *
+ * Either a doit or dumpit callback must be specified for every registered
+ * operation or the function will fail. Only one operation structure per
+ * command identifier may be registered.
+ *
+ * See include/net/genetlink.h for more documenation on the operations
+ * structure.
+ *
+ * Return 0 on success or a negative error code.
+ */
+static inline int
+_genl_register_family_with_ops_grps(struct genl_family *family,
+ const struct genl_ops *ops, size_t n_ops,
+ const struct genl_multicast_group *mcgrps,
+ size_t n_mcgrps)
+{
+ family->module = THIS_MODULE;
+ family->ops = ops;
+ family->n_ops = n_ops;
+ family->mcgrps = mcgrps;
+ family->n_mcgrps = n_mcgrps;
+ return genl_register_family(family);
+}
+#define genl_register_family_with_ops(family, ops) \
+ _genl_register_family_with_ops_grps((family), \
+ (ops), ARRAY_SIZE(ops), \
+ NULL, 0)
+#define genl_register_family_with_ops_groups(family, ops, grps) \
+ _genl_register_family_with_ops_grps((family), \
+ (ops), ARRAY_SIZE(ops), \
+ (grps), ARRAY_SIZE(grps))
+
int genl_unregister_family(const struct genl_family *family);
void genl_notify(const struct genl_family *family, struct sk_buff *skb,
struct genl_info *info, u32 group, gfp_t flags);
diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h
new file mode 100644
index 0000000000000..5b5c85272c58b
--- /dev/null
+++ b/include/soc/mediatek/pmic_wrap.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 MediaTek Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SOC_MEDIATEK_PMIC_WRAP_H
+#define __SOC_MEDIATEK_PMIC_WRAP_H
+
+extern struct regmap *pwrap_node_to_regmap(struct device_node *np);
+
+#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */
diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
index 877f7fa954666..6a176b3d43f9b 100644
--- a/include/uapi/linux/genetlink.h
+++ b/include/uapi/linux/genetlink.h
@@ -27,6 +27,7 @@ struct genlmsghdr {
/*
* List of reserved static generic netlink identifiers:
*/
+#define GENL_ID_GENERATE 0
#define GENL_ID_CTRL NLMSG_MIN_TYPE
#define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1)
#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2)

View file

@ -0,0 +1,75 @@
From 203a5a7727a80ab519ea00181a909e415c5567ab Mon Sep 17 00:00:00 2001
From: Frank Wunderlich <frank-w@public-files.de>
Date: Wed, 29 Aug 2018 19:17:00 +0200
Subject: [PATCH] [gcc] gcc8-fixes by Dominik Koch + nic_rx-patch from
https://bugs.linaro.org/show_bug.cgi?id=3823
---
.../misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c | 10 ++++++----
.../misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c | 2 +-
.../connectivity/wlan/gen2/os/linux/include/gl_kal.h | 2 +-
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
index ba4840414da85..65823023cec0e 100644
--- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c
@@ -2061,7 +2061,6 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb
case EVENT_ID_BT_OVER_WIFI:
#if CFG_ENABLE_BT_OVER_WIFI
{
- UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)];
P_EVENT_BT_OVER_WIFI prEventBtOverWifi;
P_AMPC_EVENT prBowEvent;
P_BOW_LINK_CONNECTED prBowLinkConnected;
@@ -2069,11 +2068,11 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb
prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer);
- /* construct event header */
- prBowEvent = (P_AMPC_EVENT) aucTmp;
-
if (prEventBtOverWifi->ucLinkStatus == 0) {
/* Connection */
+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)];
+ /* construct event header */
+ prBowEvent = (P_AMPC_EVENT) aucTmp;
prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED;
prBowEvent->rHeader.ucSeqNumber = 0;
prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED);
@@ -2086,6 +2085,9 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb
kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent);
} else {
/* Disconnection */
+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)];
+ /* construct event header */
+ prBowEvent = (P_AMPC_EVENT) aucTmp;
prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED;
prBowEvent->rHeader.ucSeqNumber = 0;
prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED);
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
index dd00859d46082..ad7107b1d9a44 100644
--- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c
@@ -5021,7 +5021,7 @@ VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) {
if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */
prBssInfo->prStaRecOfAP->aucMacAddr)) {
- strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */
+ memcpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */
DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n",
apIp[0], apIp[1], apIp[2], apIp[3]);
}
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
index 1406905095e64..b1386918c08de 100644
--- a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h
@@ -852,7 +852,7 @@ struct KAL_HALT_CTRL_T {
/* string operation */
#define kalStrCpy(dest, src) strcpy(dest, src)
-#define kalStrnCpy(dest, src, n) strncpy(dest, src, n)
+#define kalStrnCpy(dest, src, n) memcpy(dest, src, n)
#define kalStrCmp(ct, cs) strcmp(ct, cs)
#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n)
#define kalStrChr(s, c) strchr(s, c)

View file

@ -0,0 +1,715 @@
From 981dbf745c8c80300707ee2a5c1e25189b51a2e6 Mon Sep 17 00:00:00 2001
From: Frank Wunderlich <frank-w@public-files.de>
Date: Tue, 23 Oct 2018 12:09:37 +0200
Subject: [PATCH] [poweroff] add power-off patch from jofri
---
.../devicetree/bindings/mfd/mt6397.txt | 10 +-
.../bindings/power/reset/mt6323-poweroff.txt | 20 +++
.../devicetree/bindings/rtc/rtc-mt6397.txt | 29 ++++
MAINTAINERS | 7 +
arch/arm/boot/dts/mt6323.dtsi | 46 +++++-
arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 +-
drivers/mfd/mt6397-core.c | 40 +++--
drivers/power/reset/Kconfig | 10 ++
drivers/power/reset/Makefile | 1 +
drivers/power/reset/mt6323-poweroff.c | 97 ++++++++++++
drivers/rtc/rtc-mt6397.c | 147 ++++--------------
include/linux/mfd/mt6397/core.h | 2 +
include/linux/mfd/mt6397/rtc.h | 71 +++++++++
13 files changed, 356 insertions(+), 128 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
create mode 100644 drivers/power/reset/mt6323-poweroff.c
create mode 100644 include/linux/mfd/mt6397/rtc.h
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 0ebd08af777d4..44acb98277168 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -8,6 +8,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
- Clock
- LED
- Keys
+- Power controller
It is interfaced to host controller using SPI interface by a proprietary hardware
called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
@@ -22,8 +23,10 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323"
Optional subnodes:
- rtc
- Required properties:
+ Required properties: Should be one of follows
+ - compatible: "mediatek,mt6323-rtc"
- compatible: "mediatek,mt6397-rtc"
+ For details, see Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
@@ -46,6 +49,11 @@ Optional subnodes:
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
+- power-controller
+ Required properties:
+ - compatible: "mediatek,mt6323-pwrc"
+ For details, see Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
+
Example:
pwrap: pwrap@1000f000 {
compatible = "mediatek,mt8135-pwrap";
diff --git a/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
new file mode 100644
index 0000000000000..6f7c5905a6529
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
@@ -0,0 +1,20 @@
+Device Tree Bindings for Power Controller on MediaTek PMIC
+
+The power controller which could be found on PMIC is responsible for externally
+powering off or on the remote MediaTek SoC through the circuit BBPU.
+
+Required properties:
+- compatible: Should be one of follows
+ "mediatek,mt6323-pwrc": for MT6323 PMIC
+
+Example:
+
+ pmic {
+ compatible = "mediatek,mt6323";
+
+ ...
+
+ power-controller {
+ compatible = "mediatek,mt6323-pwrc";
+ };
+ }
diff --git a/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
new file mode 100644
index 0000000000000..6e97248e89306
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt
@@ -0,0 +1,29 @@
+Device-Tree bindings for MediaTek PMIC based RTC
+
+MediaTek PMIC based RTC is an independent function of MediaTek PMIC that works
+as a type of multi-function device (MFD). The RTC can be configured and set up
+with PMIC wrapper bus which is a common resource shared with the other
+functions found on the same PMIC.
+
+For MediaTek PMIC MFD bindings, see:
+Documentation/devicetree/bindings/mfd/mt6397.txt
+
+For MediaTek PMIC wrapper bus bindings, see:
+Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+
+Required properties:
+- compatible: Should be one of follows
+ "mediatek,mt6323-rtc": for MT6323 PMIC
+ "mediatek,mt6397-rtc": for MT6397 PMIC
+
+Example:
+
+ pmic {
+ compatible = "mediatek,mt6323";
+
+ ...
+
+ rtc {
+ compatible = "mediatek,mt6323-rtc";
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index b2f710eee67a7..ed4733bbd124f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9227,6 +9227,13 @@ S: Maintained
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
+MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS
+M: Sean Wang <sean.wang@mediatek.com>
+L: linux-pm@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
+F: drivers/power/reset/mt6323-poweroff.c
+
MEDIATEK JPEG DRIVER
M: Rick Chang <rick.chang@mediatek.com>
M: Bin Liu <bin.liu@mediatek.com>
diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi
index ba397407c1dd0..871de0bb349bd 100644
--- a/arch/arm/boot/dts/mt6323.dtsi
+++ b/arch/arm/boot/dts/mt6323.dtsi
@@ -18,7 +18,24 @@
compatible = "mediatek,mt6323-led";
#address-cells = <1>;
#size-cells = <0>;
- status = "disabled";
+
+ led@0 {
+ reg = <0>;
+ label = "bpi-r2:isink:green";
+ default-state = "off";
+ };
+
+ led@1 {
+ reg = <1>;
+ label = "bpi-r2:isink:red";
+ default-state = "off";
+ };
+
+ led@2 {
+ reg = <2>;
+ label = "bpi-r2:isink:blue";
+ default-state = "off";
+ };
};
mt6323regulator: mt6323regulator{
@@ -238,5 +255,32 @@
regulator-enable-ramp-delay = <216>;
};
};
+
+ mt6323keys: mt6323keys {
+ compatible = "mediatek,mt6323-keys";
+ mediatek,long-press-mode = <1>;
+ power-off-time-sec = <0>;
+
+ power {
+ linux,keycodes = <116>;
+ wakeup-source;
+ };
+
+ home {
+ linux,keycodes = <114>;
+ };
+ };
+
+ codec: mt6397codec {
+ compatible = "mediatek,mt6397-codec";
+ };
+
+ power-controller {
+ compatible = "mediatek,mt6323-pwrc";
+ };
+
+ rtc {
+ compatible = "mediatek,mt6323-rtc";
+ };
};
};
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 77b64bd64df36..e0012e2624734 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 MediaTek Inc.
+ * Copyright (c) 2014-2018 MediaTek Inc.
* Author: Flora Fu, MediaTek
*
* This program is free software; you can redistribute it and/or modify
@@ -13,6 +13,7 @@
*/
#include <linux/interrupt.h>
+#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
@@ -23,24 +24,27 @@
#include <linux/mfd/mt6397/registers.h>
#include <linux/mfd/mt6323/registers.h>
+#define MT6323_RTC_BASE 0x8000
+#define MT6323_RTC_SIZE 0x40
+
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
+#define MT6323_PWRC_BASE 0x8000
+#define MT6323_PWRC_SIZE 0x40
+
#define MT6323_CID_CODE 0x23
#define MT6391_CID_CODE 0x91
#define MT6397_CID_CODE 0x97
+static const struct resource mt6323_rtc_resources[] = {
+ DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
+};
+
static const struct resource mt6397_rtc_resources[] = {
- {
- .start = MT6397_RTC_BASE,
- .end = MT6397_RTC_BASE + MT6397_RTC_SIZE,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MT6397_IRQ_RTC,
- .end = MT6397_IRQ_RTC,
- .flags = IORESOURCE_IRQ,
- },
+ DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6397_IRQ_RTC),
};
static const struct resource mt6323_keys_resources[] = {
@@ -53,8 +57,17 @@ static const struct resource mt6397_keys_resources[] = {
DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
};
+static const struct resource mt6323_pwrc_resources[] = {
+ DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE),
+};
+
static const struct mfd_cell mt6323_devs[] = {
{
+ .name = "mt6323-rtc",
+ .num_resources = ARRAY_SIZE(mt6323_rtc_resources),
+ .resources = mt6323_rtc_resources,
+ .of_compatible = "mediatek,mt6323-rtc",
+ }, {
.name = "mt6323-regulator",
.of_compatible = "mediatek,mt6323-regulator"
}, {
@@ -65,6 +78,11 @@ static const struct mfd_cell mt6323_devs[] = {
.num_resources = ARRAY_SIZE(mt6323_keys_resources),
.resources = mt6323_keys_resources,
.of_compatible = "mediatek,mt6323-keys"
+ }, {
+ .name = "mt6323-pwrc",
+ .num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
+ .resources = mt6323_pwrc_resources,
+ .of_compatible = "mediatek,mt6323-pwrc"
},
};
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 6533aa560aa1f..3d0c050c51601 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -139,6 +139,16 @@ config POWER_RESET_LTC2952
This driver supports an external powerdown trigger and board power
down via the LTC2952. Bindings are made in the device tree.
+config POWER_RESET_MT6323
+ bool "MediaTek MT6323 power-off driver"
+ depends on MFD_MT6397
+ help
+ The power-off driver is responsible for externally shutdown down
+ the power of a remote MediaTek SoC MT6323 is connected to through
+ controlling a tiny circuit BBPU inside MT6323 RTC.
+
+ Say Y if you have a board where MT6323 could be found.
+
config POWER_RESET_QNAP
bool "QNAP power-off driver"
depends on OF_GPIO && PLAT_ORION
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0aebee954ac1b..94eaceb01d665 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
+obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
new file mode 100644
index 0000000000000..c195766f75704
--- /dev/null
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Power off through MediaTek PMIC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Sean Wang <sean.wang@mediatek.com>
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6397/rtc.h>
+
+struct mt6323_pwrc {
+ struct device *dev;
+ struct regmap *regmap;
+ u32 base;
+};
+
+static struct mt6323_pwrc *mt_pwrc;
+
+static void mt6323_do_pwroff(void)
+{
+ struct mt6323_pwrc *pwrc = mt_pwrc;
+ unsigned int val;
+ int ret;
+
+ regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY);
+ regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1);
+
+ ret = regmap_read_poll_timeout(pwrc->regmap,
+ pwrc->base + RTC_BBPU, val,
+ !(val & RTC_BBPU_CBUSY),
+ MTK_RTC_POLL_DELAY_US,
+ MTK_RTC_POLL_TIMEOUT);
+ if (ret)
+ dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret);
+
+ /* Wait some time until system down, otherwise, notice with a warn */
+ mdelay(1000);
+
+ WARN_ONCE(1, "Unable to power off system\n");
+}
+
+static int mt6323_pwrc_probe(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
+ struct mt6323_pwrc *pwrc;
+ struct resource *res;
+
+ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
+ if (!pwrc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pwrc->base = res->start;
+ pwrc->regmap = mt6397_chip->regmap;
+ pwrc->dev = &pdev->dev;
+ mt_pwrc = pwrc;
+
+ pm_power_off = &mt6323_do_pwroff;
+
+ return 0;
+}
+
+static int mt6323_pwrc_remove(struct platform_device *pdev)
+{
+ if (pm_power_off == &mt6323_do_pwroff)
+ pm_power_off = NULL;
+
+ return 0;
+}
+
+static const struct of_device_id mt6323_pwrc_dt_match[] = {
+ { .compatible = "mediatek,mt6323-pwrc" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
+
+static struct platform_driver mt6323_pwrc_driver = {
+ .probe = mt6323_pwrc_probe,
+ .remove = mt6323_pwrc_remove,
+ .driver = {
+ .name = "mt6323-pwrc",
+ .of_match_table = mt6323_pwrc_dt_match,
+ },
+};
+
+module_platform_driver(mt6323_pwrc_driver);
+
+MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index 385f8303bb412..66e949df8d6a1 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -1,80 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
/*
-* Copyright (c) 2014-2015 MediaTek Inc.
-* Author: Tianping.Fang <tianping.fang@mediatek.com>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*/
-
-#include <linux/delay.h>
-#include <linux/init.h>
+ * MediaTek PMIC RTC driver
+ *
+ * Copyright (C) 2014-2018 MediaTek Inc.
+ *
+ * Author: Tianping.Fang <tianping.fang@mediatek.com>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
-#include <linux/irqdomain.h>
-#include <linux/platform_device.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/mfd/mt6397/core.h>
-
-#define RTC_BBPU 0x0000
-#define RTC_BBPU_CBUSY BIT(6)
-
-#define RTC_WRTGR 0x003c
-
-#define RTC_IRQ_STA 0x0002
-#define RTC_IRQ_STA_AL BIT(0)
-#define RTC_IRQ_STA_LP BIT(3)
-
-#define RTC_IRQ_EN 0x0004
-#define RTC_IRQ_EN_AL BIT(0)
-#define RTC_IRQ_EN_ONESHOT BIT(2)
-#define RTC_IRQ_EN_LP BIT(3)
-#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
-
-#define RTC_AL_MASK 0x0008
-#define RTC_AL_MASK_DOW BIT(4)
-
-#define RTC_TC_SEC 0x000a
-/* Min, Hour, Dom... register offset to RTC_TC_SEC */
-#define RTC_OFFSET_SEC 0
-#define RTC_OFFSET_MIN 1
-#define RTC_OFFSET_HOUR 2
-#define RTC_OFFSET_DOM 3
-#define RTC_OFFSET_DOW 4
-#define RTC_OFFSET_MTH 5
-#define RTC_OFFSET_YEAR 6
-#define RTC_OFFSET_COUNT 7
-
-#define RTC_AL_SEC 0x0018
-
-#define RTC_PDN2 0x002e
-#define RTC_PDN2_PWRON_ALARM BIT(4)
-
-#define RTC_MIN_YEAR 1968
-#define RTC_BASE_YEAR 1900
-#define RTC_NUM_YEARS 128
-#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
-
-struct mt6397_rtc {
- struct device *dev;
- struct rtc_device *rtc_dev;
- struct mutex lock;
- struct regmap *regmap;
- int irq;
- u32 addr_base;
-};
+#include <linux/mfd/mt6397/rtc.h>
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
{
- unsigned long timeout = jiffies + HZ;
int ret;
u32 data;
@@ -82,19 +28,13 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
if (ret < 0)
return ret;
- while (1) {
- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU,
- &data);
- if (ret < 0)
- break;
- if (!(data & RTC_BBPU_CBUSY))
- break;
- if (time_after(jiffies, timeout)) {
- ret = -ETIMEDOUT;
- break;
- }
- cpu_relax();
- }
+ ret = regmap_read_poll_timeout(rtc->regmap,
+ rtc->addr_base + RTC_BBPU, data,
+ !(data & RTC_BBPU_CBUSY),
+ MTK_RTC_POLL_DELAY_US,
+ MTK_RTC_POLL_TIMEOUT);
+ if (ret < 0)
+ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret);
return ret;
}
@@ -332,44 +272,25 @@ static int mtk_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- ret = request_threaded_irq(rtc->irq, NULL,
- mtk_rtc_irq_handler_thread,
- IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
- "mt6397-rtc", rtc);
+ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
+ mtk_rtc_irq_handler_thread,
+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+ "mt6397-rtc", rtc);
if (ret) {
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
rtc->irq, ret);
- goto out_dispose_irq;
+ return ret;
}
device_init_wakeup(&pdev->dev, 1);
- rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev,
- &mtk_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc->rtc_dev)) {
- dev_err(&pdev->dev, "register rtc device failed\n");
- ret = PTR_ERR(rtc->rtc_dev);
- goto out_free_irq;
- }
-
- return 0;
+ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+ if (IS_ERR(rtc->rtc_dev))
+ return PTR_ERR(rtc->rtc_dev);
-out_free_irq:
- free_irq(rtc->irq, rtc->rtc_dev);
-out_dispose_irq:
- irq_dispose_mapping(rtc->irq);
- return ret;
-}
+ rtc->rtc_dev->ops = &mtk_rtc_ops;
-static int mtk_rtc_remove(struct platform_device *pdev)
-{
- struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
-
- rtc_device_unregister(rtc->rtc_dev);
- free_irq(rtc->irq, rtc->rtc_dev);
- irq_dispose_mapping(rtc->irq);
-
- return 0;
+ return rtc_register_device(rtc->rtc_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -398,6 +319,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
mt6397_rtc_resume);
static const struct of_device_id mt6397_rtc_of_match[] = {
+ { .compatible = "mediatek,mt6323-rtc", },
{ .compatible = "mediatek,mt6397-rtc", },
{ }
};
@@ -410,7 +332,6 @@ static struct platform_driver mtk_rtc_driver = {
.pm = &mt6397_pm_ops,
},
.probe = mtk_rtc_probe,
- .remove = mtk_rtc_remove,
};
module_platform_driver(mtk_rtc_driver);
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index d678f526e4986..0425c68cc1877 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -15,6 +15,8 @@
#ifndef __MFD_MT6397_CORE_H__
#define __MFD_MT6397_CORE_H__
+#include <linux/mutex.h>
+
enum mt6397_irq_numbers {
MT6397_IRQ_SPKL_AB = 0,
MT6397_IRQ_SPKR_AB,
diff --git a/include/linux/mfd/mt6397/rtc.h b/include/linux/mfd/mt6397/rtc.h
new file mode 100644
index 0000000000000..ac932c93da8f2
--- /dev/null
+++ b/include/linux/mfd/mt6397/rtc.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2014-2018 MediaTek Inc.
+ *
+ * Author: Tianping.Fang <tianping.fang@mediatek.com>
+ * Sean Wang <sean.wang@mediatek.com>
+ */
+
+#ifndef _LINUX_MFD_MT6397_RTC_H_
+#define _LINUX_MFD_MT6397_RTC_H_
+
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+
+#define RTC_BBPU 0x0000
+#define RTC_BBPU_CBUSY BIT(6)
+#define RTC_BBPU_KEY (0x43 << 8)
+
+#define RTC_WRTGR 0x003c
+
+#define RTC_IRQ_STA 0x0002
+#define RTC_IRQ_STA_AL BIT(0)
+#define RTC_IRQ_STA_LP BIT(3)
+
+#define RTC_IRQ_EN 0x0004
+#define RTC_IRQ_EN_AL BIT(0)
+#define RTC_IRQ_EN_ONESHOT BIT(2)
+#define RTC_IRQ_EN_LP BIT(3)
+#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
+
+#define RTC_AL_MASK 0x0008
+#define RTC_AL_MASK_DOW BIT(4)
+
+#define RTC_TC_SEC 0x000a
+/* Min, Hour, Dom... register offset to RTC_TC_SEC */
+#define RTC_OFFSET_SEC 0
+#define RTC_OFFSET_MIN 1
+#define RTC_OFFSET_HOUR 2
+#define RTC_OFFSET_DOM 3
+#define RTC_OFFSET_DOW 4
+#define RTC_OFFSET_MTH 5
+#define RTC_OFFSET_YEAR 6
+#define RTC_OFFSET_COUNT 7
+
+#define RTC_AL_SEC 0x0018
+
+#define RTC_PDN2 0x002e
+#define RTC_PDN2_PWRON_ALARM BIT(4)
+
+#define RTC_MIN_YEAR 1968
+#define RTC_BASE_YEAR 1900
+#define RTC_NUM_YEARS 128
+#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR)
+
+#define MTK_RTC_POLL_DELAY_US 10
+#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ))
+
+struct mt6397_rtc {
+ struct device *dev;
+ struct rtc_device *rtc_dev;
+
+ /* Protect register access from multiple tasks */
+ struct mutex lock;
+ struct regmap *regmap;
+ int irq;
+ u32 addr_base;
+};
+
+#endif /* _LINUX_MFD_MT6397_RTC_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,221 @@
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 90c9a8a..3c79b90 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -29,6 +29,27 @@ create_package() {
# in case we are in a restrictive umask environment like 0077
chmod -R a+rX "$pdir"
+ # Create preinstall and post install script to remove dtb
+ if [[ "$1" == *dtb* ]]; then
+ echo "if [ -d /boot/dtb-$version ]; then mv /boot/dtb-$version /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/preinst
+ echo "if [ -d /boot/dtb.old ]; then rm -rf /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
+ echo "if [ -d /boot/dtb ]; then mv /boot/dtb /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
+ echo "exit 0" >> $pdir/DEBIAN/preinst
+ chmod 775 $pdir/DEBIAN/preinst
+
+ echo "if [ -d /boot/dtb-$version.old ]; then rm -rf /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/postinst
+ echo "ln -sf dtb-$version /boot/dtb > /dev/null 2>&1 || mv /boot/dtb-$version /boot/dtb" >> $pdir/DEBIAN/postinst
+ echo "exit 0" >> $pdir/DEBIAN/postinst
+ chmod 775 $pdir/DEBIAN/postinst
+ fi
+
+ # Create postinstall script for headers
+ if [[ "$1" == *headers* ]]; then
+ echo "cd /usr/src/linux-headers-$version; echo \"Compiling headers - please wait ...\"; find -type f -exec touch {} +;make -s scripts >/dev/null 2>&1" >> $pdir/DEBIAN/postinst
+ echo "exit 0" >> $pdir/DEBIAN/postinst
+ chmod 775 $pdir/DEBIAN/postinst
+ fi
+
# Create the package
dpkg-gencontrol -p$pname -P"$pdir"
dpkg --build "$pdir" ..
@@ -39,9 +60,11 @@ tmpdir="$objtree/debian/tmp"
kernel_headers_dir="$objtree/debian/hdrtmp"
libc_headers_dir="$objtree/debian/headertmp"
dbg_dir="$objtree/debian/dbgtmp"
-packagename=linux-image-$version
-kernel_headers_packagename=linux-headers-$version
-libc_headers_packagename=linux-libc-dev
+dtb_dir="$objtree/debian/dtbtmp"
+packagename=linux-image"$LOCALVERSION"
+kernel_headers_packagename=linux-headers"$LOCALVERSION"
+dtb_packagename=linux-dtb"$LOCALVERSION"
+libc_headers_packagename=linux-libc-dev"$LOCALVERSION"
dbg_packagename=$packagename-dbg
if [ "$ARCH" = "um" ] ; then
@@ -52,6 +75,15 @@ fi
# XXX: have each arch Makefile export a variable of the canonical image install
# path instead
case $ARCH in
+aarch64|arm64)
+ image_name=zImage
+ installed_image_path="boot/vmlinuz-$version"
+
+ ;;
+arm*)
+ image_name=zImage
+ installed_image_path="boot/vmlinuz-$version"
+ ;;
um)
installed_image_path="usr/bin/linux-$version"
;;
@@ -65,7 +97,9 @@ esac
BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
# Setup the directory structure
-rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
+rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" "$dtb_dir" $objtree/debian/files
+mkdir -m 755 -p "$dtb_dir/DEBIAN"
+mkdir -p "$dtb_dir/boot/dtb-$version" "$dtb_dir/usr/share/doc/$dtb_packagename"
mkdir -m 755 -p "$tmpdir/DEBIAN"
mkdir -p "$tmpdir/lib" "$tmpdir/boot"
mkdir -p "$kernel_headers_dir/lib/modules/$version/"
@@ -118,6 +152,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then
fi
fi
+if grep -q '^CONFIG_OF=y' $KCONFIG_CONFIG ; then
+ #mkdir -p "$tmpdir/boot/dtb"
+ INSTALL_DTBS_PATH="$dtb_dir/boot/dtb-$version" $MAKE KBUILD_SRC= dtbs_install
+fi
+
if [ "$ARCH" != "um" ]; then
$MAKE headers_check KBUILD_SRC=
$MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr"
@@ -137,7 +176,7 @@ fi
for script in postinst postrm preinst prerm ; do
mkdir -p "$tmpdir$debhookdir/$script.d"
cat <<EOF > "$tmpdir/DEBIAN/$script"
-#!/bin/sh
+#!/bin/bash
set -e
@@ -153,9 +192,60 @@ EOF
chmod 755 "$tmpdir/DEBIAN/$script"
done
+##
+## Create sym link to kernel image
+##
+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/postinst
+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/postinst
+cat >> $tmpdir/DEBIAN/postinst <<EOT
+if [ "\$(grep nand /proc/partitions)" != "" ] && [ "\$(grep mmc /proc/partitions)" = "" ]; then
+ mkimage -A arm -O linux -T kernel -C none -a "0x40008000" -e "0x40008000" -n "Linux kernel" -d /$installed_image_path /boot/zImage > /dev/null 2>&1
+ cp /boot/zImage /tmp/zImage
+ sync
+ mountpoint -q /boot || mount /boot
+ cp /tmp/uImage /boot/zImage
+ rm -f /$installed_image_path
+else
+ ln -sf $(basename $installed_image_path) /boot/$image_name || mv /$installed_image_path /boot/$image_name
+fi
+touch /boot/.next
+exit 0
+EOT
+
+##
+## FAT install workaround
+##
+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/preinst
+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/preinst
+cat >> $tmpdir/DEBIAN/preinst <<EOT
+# exit if we are running chroot
+if [ "\$(stat -c %d:%i /)" != "\$(stat -c %d:%i /proc/1/root/.)" ]; then exit 0; fi
+
+check_and_unmount (){
+ boot_device=\$(mountpoint -d /boot)
+
+ for file in /dev/* ; do
+ CURRENT_DEVICE=\$(printf "%d:%d" \$(stat --printf="0x%t 0x%T" \$file))
+ if [[ "\$CURRENT_DEVICE" = "\$boot_device" ]]; then
+ boot_partition=\$file
+ break
+ fi
+ done
+
+ bootfstype=\$(blkid -s TYPE -o value \$boot_partition)
+ if [ "\$bootfstype" = "vfat" ]; then
+ umount /boot
+ rm -f /boot/System.map* /boot/config* /boot/vmlinuz* /boot/$image_name /boot/uImage
+ fi
+}
+mountpoint -q /boot && check_and_unmount
+EOT
+echo "exit 0" >> $tmpdir/DEBIAN/preinst
+
# Build kernel header package
(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find security/*/include -type f) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
@@ -167,15 +257,19 @@ if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then
fi
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
+(cd $destdir; patch -p1 < /tmp/headers-debian-byteshift.patch)
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
(cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -)
(cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be
ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
+(cd $destdir; make M=scripts clean)
+
if [ "$ARCH" != "um" ]; then
create_package "$kernel_headers_packagename" "$kernel_headers_dir"
- create_package "$libc_headers_packagename" "$libc_headers_dir"
+ # create_package "$libc_headers_packagename" "$libc_headers_dir"
+ create_package "$dtb_packagename" "$dtb_dir"
fi
create_package "$packagename" "$tmpdir"
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
index 6adb3a1..00e12eb 100755
--- a/scripts/package/mkdebian
+++ b/scripts/package/mkdebian
@@ -61,10 +61,12 @@ else
packageversion=$version-$revision
fi
sourcename=$KDEB_SOURCENAME
-packagename=linux-image-$version
-kernel_headers_packagename=linux-headers-$version
+packagename=linux-image$LOCALVERSION
+kernel_headers_packagename=linux-headers$LOCALVERSION
+dtb_packagename=linux-dtb$LOCALVERSION
dbg_packagename=$packagename-dbg
debarch=
+image_name=
set_debarch
if [ "$ARCH" = "um" ] ; then
@@ -168,6 +170,11 @@ Architecture: $debarch
Description: Linux kernel debugging symbols for $version
This package will come in handy if you need to debug the kernel. It provides
all the necessary debug symbols for the kernel and its modules.
+
+Package: $dtb_packagename
+Architecture: $debarch
+Description: Linux DTB, version $version
+ This package contains device blobs from the Linux kernel, version $version
EOF
cat <<EOF > debian/rules
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index f839ecd9..cd276162 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -103,7 +103,7 @@ core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
# Default target when executing plain make
boot := arch/arm64/boot
-KBUILD_IMAGE := $(boot)/Image.gz
+KBUILD_IMAGE := $(boot)/Image
KBUILD_DTBS := dtbs
all: Image.gz $(KBUILD_DTBS)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 918f449..561b71c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -39,6 +39,8 @@ source "drivers/net/wireless/cisco/Kconfig"
source "drivers/net/wireless/intel/Kconfig"
source "drivers/net/wireless/intersil/Kconfig"
source "drivers/net/wireless/marvell/Kconfig"
+source "drivers/net/wireless/rtl8812au/Kconfig"
+source "drivers/net/wireless/rtl8814au/Kconfig"
source "drivers/net/wireless/mediatek/Kconfig"
source "drivers/net/wireless/ralink/Kconfig"
source "drivers/net/wireless/realtek/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 59df552..614ddf4 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -12,6 +12,8 @@ obj-$(CONFIG_WLAN_VENDOR_CISCO) += cisco/
obj-$(CONFIG_WLAN_VENDOR_INTEL) += intel/
obj-$(CONFIG_WLAN_VENDOR_INTERSIL) += intersil/
obj-$(CONFIG_WLAN_VENDOR_MARVELL) += marvell/
+obj-$(CONFIG_RTL8812AU) += rtl8812au/
+obj-$(CONFIG_RTL8814AU) += rtl8814au/
obj-$(CONFIG_WLAN_VENDOR_MEDIATEK) += mediatek/
obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/
obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/

View file

@ -0,0 +1,46 @@
diff --git a/drivers/net/wireless/rtl8812au/Kconfig b/drivers/net/wireless/rtl8812au/Kconfig
index 16d3567..f87653d 100644
--- a/drivers/net/wireless/rtl8812au/Kconfig
+++ b/drivers/net/wireless/rtl8812au/Kconfig
@@ -4,8 +4,3 @@ config RTL8812AU
---help---
Help message of RTL8812AU
-config RTL8814AU
- tristate "Realtek 8814A USB WiFi"
- depends on USB
- ---help---
- Help message of RTL8814AU
diff --git a/drivers/net/wireless/rtl8814au/Kconfig b/drivers/net/wireless/rtl8814au/Kconfig
index 16d3567..730c4e0 100644
--- a/drivers/net/wireless/rtl8814au/Kconfig
+++ b/drivers/net/wireless/rtl8814au/Kconfig
@@ -1,9 +1,3 @@
-config RTL8812AU
- tristate "Realtek 8812A USB WiFi"
- depends on USB
- ---help---
- Help message of RTL8812AU
-
config RTL8814AU
tristate "Realtek 8814A USB WiFi"
depends on USB
diff --git a/drivers/net/wireless/rtl8814au/Makefile b/drivers/net/wireless/rtl8814au/Makefile
index ef959e7..f71f524 100644
--- a/drivers/net/wireless/rtl8814au/Makefile
+++ b/drivers/net/wireless/rtl8814au/Makefile
@@ -32,11 +32,11 @@ CONFIG_AUTOCFG_CP = n
########################## WIFI IC ############################
CONFIG_MULTIDRV = n
CONFIG_RTL8188E = n
-CONFIG_RTL8812A = y
-CONFIG_RTL8821A = y
+CONFIG_RTL8812A = n
+CONFIG_RTL8821A = n
CONFIG_RTL8192E = n
CONFIG_RTL8723B = n
-CONFIG_RTL8814A = n
+CONFIG_RTL8814A = y
CONFIG_RTL8723C = n
CONFIG_RTL8188F = n
CONFIG_RTL8822B = n

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,645 @@
From patchwork Tue Oct 2 06:13:39 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,02/20] arm: MediaTek: add basic support for MT7629 boards
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977711
Message-Id: <3bf0f6e0b89aab3ebf9cf95ad9784073ef7d686a.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:39 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This adds a general board file based on MT7629 SoCs from MediaTek.
Apart from the generic parts (cpu) we add some low level init codes and
initialize the early clocks.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
arch/arm/Kconfig | 14 +++
arch/arm/Makefile | 1 +
arch/arm/mach-mediatek/Kconfig | 24 +++++
arch/arm/mach-mediatek/Makefile | 6 ++
arch/arm/mach-mediatek/cpu.c | 34 ++++++
arch/arm/mach-mediatek/include/mach/chipid.h | 17 +++
arch/arm/mach-mediatek/include/mach/gpio.h | 9 ++
arch/arm/mach-mediatek/init.h | 11 ++
arch/arm/mach-mediatek/mt7629/Makefile | 4 +
arch/arm/mach-mediatek/mt7629/init.c | 142 ++++++++++++++++++++++++++
arch/arm/mach-mediatek/mt7629/lowlevel_init.S | 50 +++++++++
arch/arm/mach-mediatek/spl.c | 43 ++++++++
board/mediatek/mt7629/Kconfig | 17 +++
board/mediatek/mt7629/MAINTAINERS | 7 ++
board/mediatek/mt7629/Makefile | 4 +
board/mediatek/mt7629/mt7629_rfb.c | 16 +++
include/configs/mt7629.h | 68 ++++++++++++
17 files changed, 467 insertions(+)
create mode 100644 arch/arm/mach-mediatek/Kconfig
create mode 100644 arch/arm/mach-mediatek/Makefile
create mode 100644 arch/arm/mach-mediatek/cpu.c
create mode 100644 arch/arm/mach-mediatek/include/mach/chipid.h
create mode 100644 arch/arm/mach-mediatek/include/mach/gpio.h
create mode 100644 arch/arm/mach-mediatek/init.h
create mode 100644 arch/arm/mach-mediatek/mt7629/Makefile
create mode 100644 arch/arm/mach-mediatek/mt7629/init.c
create mode 100644 arch/arm/mach-mediatek/mt7629/lowlevel_init.S
create mode 100644 arch/arm/mach-mediatek/spl.c
create mode 100644 board/mediatek/mt7629/Kconfig
create mode 100644 board/mediatek/mt7629/MAINTAINERS
create mode 100644 board/mediatek/mt7629/Makefile
create mode 100644 board/mediatek/mt7629/mt7629_rfb.c
create mode 100644 include/configs/mt7629.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ccf2a84..eac03f0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -668,6 +668,18 @@ 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 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.
+
config ARCH_MX8M
bool "NXP i.MX8M platform"
select ARM64
@@ -1423,6 +1435,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"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 8f50560..ddb9618 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -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
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
new file mode 100644
index 0000000..a932e70
--- /dev/null
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -0,0 +1,24 @@
+if ARCH_MEDIATEK
+
+config SYS_SOC
+ default "mediatek"
+
+config SYS_VENDOR
+ default "mediatek"
+
+choice
+ prompt "MediaTek board select"
+
+config TARGET_MT7629
+ bool "MediaTek MT7629 SoC"
+ select CPU_V7A
+ select SPL
+ select ARCH_MISC_INIT
+ help
+ Support MediaTek MT7629 SoC.
+
+endchoice
+
+source "board/mediatek/mt7629/Kconfig"
+
+endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
new file mode 100644
index 0000000..852d330
--- /dev/null
+++ b/arch/arm/mach-mediatek/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += cpu.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
+
+obj-$(CONFIG_TARGET_MT7629) += mt7629/
diff --git a/arch/arm/mach-mediatek/cpu.c b/arch/arm/mach-mediatek/cpu.c
new file mode 100644
index 0000000..2bfeab7
--- /dev/null
+++ b/arch/arm/mach-mediatek/cpu.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <wdt.h>
+
+int arch_misc_init(void)
+{
+ struct udevice *wdt;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_WDT, 0, &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();
+}
diff --git a/arch/arm/mach-mediatek/include/mach/chipid.h b/arch/arm/mach-mediatek/include/mach/chipid.h
new file mode 100644
index 0000000..a2bc0a6
--- /dev/null
+++ b/arch/arm/mach-mediatek/include/mach/chipid.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_CHIPID_H_
+#define __MEDIATEK_CHIPID_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_CHIPID_H_ */
diff --git a/arch/arm/mach-mediatek/include/mach/gpio.h b/arch/arm/mach-mediatek/include/mach/gpio.h
new file mode 100644
index 0000000..d302ab3
--- /dev/null
+++ b/arch/arm/mach-mediatek/include/mach/gpio.h
@@ -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_ */
diff --git a/arch/arm/mach-mediatek/init.h b/arch/arm/mach-mediatek/init.h
new file mode 100644
index 0000000..1d896fb
--- /dev/null
+++ b/arch/arm/mach-mediatek/init.h
@@ -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_ */
diff --git a/arch/arm/mach-mediatek/mt7629/Makefile b/arch/arm/mach-mediatek/mt7629/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7629/init.c b/arch/arm/mach-mediatek/mt7629/init.c
new file mode 100644
index 0000000..00cf8af
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/init.c
@@ -0,0 +1,142 @@
+// 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/uclass.h>
+#include <fdtdec.h>
+#include <ram.h>
+#include <clk.h>
+#include <linux/io.h>
+#include <mach/chipid.h>
+#include <asm/sections.h>
+
+#define L2_SHARE_CFG_MP0 0x7f0
+#define L2_SHARE_MODE_OFF BIT(8)
+
+#define BROM_SF_HDR_SIZE 0x920
+
+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_get_device(UCLASS_RAM, 0, &dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mach_cpu_init(void)
+{
+ void __iomem *base;
+ int node;
+
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+ "mediatek,mt7629-mcucfg");
+ base = (void __iomem *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+ if (!base)
+ return -ENOENT;
+
+ /* 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_get_device(UCLASS_RAM, 0, &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;
+}
+
+unsigned long get_spl_size(void)
+{
+ ulong sz = (unsigned long)&_image_binary_end -
+ (unsigned long)&__image_copy_start;
+
+#if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_NOR_SUPPORT)
+ sz += BROM_SF_HDR_SIZE;
+#endif
+ return sz;
+}
diff --git a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
new file mode 100644
index 0000000..90dd4ea
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
@@ -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)
diff --git a/arch/arm/mach-mediatek/spl.c b/arch/arm/mach-mediatek/spl.c
new file mode 100644
index 0000000..9b3590f
--- /dev/null
+++ b/arch/arm/mach-mediatek/spl.c
@@ -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
+}
diff --git a/board/mediatek/mt7629/Kconfig b/board/mediatek/mt7629/Kconfig
new file mode 100644
index 0000000..6055164
--- /dev/null
+++ b/board/mediatek/mt7629/Kconfig
@@ -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
diff --git a/board/mediatek/mt7629/MAINTAINERS b/board/mediatek/mt7629/MAINTAINERS
new file mode 100644
index 0000000..424f115
--- /dev/null
+++ b/board/mediatek/mt7629/MAINTAINERS
@@ -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
diff --git a/board/mediatek/mt7629/Makefile b/board/mediatek/mt7629/Makefile
new file mode 100644
index 0000000..aa8790c
--- /dev/null
+++ b/board/mediatek/mt7629/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += mt7629_rfb.o
+
diff --git a/board/mediatek/mt7629/mt7629_rfb.c b/board/mediatek/mt7629/mt7629_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7629/mt7629_rfb.c
@@ -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;
+}
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
new file mode 100644
index 0000000..ea979f0
--- /dev/null
+++ b/include/configs/mt7629.h
@@ -0,0 +1,68 @@
+/* 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>
+
+#ifndef __ASSEMBLY__
+extern unsigned long get_spl_size(void);
+#endif
+
+/* Machine ID */
+#define CONFIG_MACH_TYPE 7629
+
+/* 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_128K
+#define CONFIG_SPL_MAX_FOOTPRINT SZ_64K
+
+#define NOR_MMAP_ADDR 0x30000000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS get_spl_size()
+#define CONFIG_SYS_UBOOT_BASE (NOR_MMAP_ADDR + get_spl_size())
+
+/* 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
+
+/* Serial device */
+#define CONFIG_SYS_NS16550_CLK 40000000
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_BAUDRATE 115200
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+#endif

View file

@ -0,0 +1,422 @@
From patchwork Tue Oct 2 06:13:40 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,03/20] arm: MediaTek: add basic support for MT7623 boards
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977712
Message-Id: <2b475007f0a7b9ade918575555edd264c5c4016a.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:40 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
From: Weijie Gao <weijie.gao@mediatek.com>
This adds a general board file based on MT7623 SoCs from MediaTek.
As this u-boot is loaded by preloader, there is no low level
initializtion codes.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
arch/arm/mach-mediatek/Kconfig | 8 +++
arch/arm/mach-mediatek/Makefile | 1 +
arch/arm/mach-mediatek/mt7623/Makefile | 4 ++
arch/arm/mach-mediatek/mt7623/init.c | 53 ++++++++++++++
arch/arm/mach-mediatek/mt7623/lowlevel_init.S | 22 ++++++
arch/arm/mach-mediatek/mt7623/preloader.h | 99 +++++++++++++++++++++++++++
board/mediatek/mt7623/Kconfig | 13 ++++
board/mediatek/mt7623/MAINTAINERS | 7 ++
board/mediatek/mt7623/Makefile | 4 ++
board/mediatek/mt7623/mt7623_rfb.c | 16 +++++
include/configs/mt7623.h | 66 ++++++++++++++++++
11 files changed, 293 insertions(+)
create mode 100644 arch/arm/mach-mediatek/mt7623/Makefile
create mode 100644 arch/arm/mach-mediatek/mt7623/init.c
create mode 100644 arch/arm/mach-mediatek/mt7623/lowlevel_init.S
create mode 100644 arch/arm/mach-mediatek/mt7623/preloader.h
create mode 100644 board/mediatek/mt7623/Kconfig
create mode 100644 board/mediatek/mt7623/MAINTAINERS
create mode 100644 board/mediatek/mt7623/Makefile
create mode 100644 board/mediatek/mt7623/mt7623_rfb.c
create mode 100644 include/configs/mt7623.h
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index a932e70..b39bc44 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -9,6 +9,13 @@ config SYS_VENDOR
choice
prompt "MediaTek board select"
+config TARGET_MT7623
+ bool "MediaTek MT7623 SoC"
+ select CPU_V7A
+ select ARCH_MISC_INIT
+ help
+ Support MediaTek MT7623 SoC.
+
config TARGET_MT7629
bool "MediaTek MT7629 SoC"
select CPU_V7A
@@ -19,6 +26,7 @@ config TARGET_MT7629
endchoice
+source "board/mediatek/mt7623/Kconfig"
source "board/mediatek/mt7629/Kconfig"
endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 852d330..b5d3a37 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -3,4 +3,5 @@
obj-y += cpu.o
obj-$(CONFIG_SPL_BUILD) += spl.o
+obj-$(CONFIG_TARGET_MT7623) += mt7623/
obj-$(CONFIG_TARGET_MT7629) += mt7629/
diff --git a/arch/arm/mach-mediatek/mt7623/Makefile b/arch/arm/mach-mediatek/mt7623/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7623/init.c b/arch/arm/mach-mediatek/mt7623/init.c
new file mode 100644
index 0000000..e891e1b
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/init.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <mach/chipid.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;
+}
diff --git a/arch/arm/mach-mediatek/mt7623/lowlevel_init.S b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
new file mode 100644
index 0000000..afb9476
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
@@ -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)
diff --git a/arch/arm/mach-mediatek/mt7623/preloader.h b/arch/arm/mach-mediatek/mt7623/preloader.h
new file mode 100644
index 0000000..2d2c71a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/preloader.h
@@ -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_ */
diff --git a/board/mediatek/mt7623/Kconfig b/board/mediatek/mt7623/Kconfig
new file mode 100644
index 0000000..a8c670e
--- /dev/null
+++ b/board/mediatek/mt7623/Kconfig
@@ -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
diff --git a/board/mediatek/mt7623/MAINTAINERS b/board/mediatek/mt7623/MAINTAINERS
new file mode 100644
index 0000000..2a78b72
--- /dev/null
+++ b/board/mediatek/mt7623/MAINTAINERS
@@ -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-bananapi-bpi-r2_defconfig
diff --git a/board/mediatek/mt7623/Makefile b/board/mediatek/mt7623/Makefile
new file mode 100644
index 0000000..8943111
--- /dev/null
+++ b/board/mediatek/mt7623/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += mt7623_rfb.o
+
diff --git a/board/mediatek/mt7623/mt7623_rfb.c b/board/mediatek/mt7623/mt7623_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7623/mt7623_rfb.c
@@ -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;
+}
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
new file mode 100644
index 0000000..00bad8b
--- /dev/null
+++ b/include/configs/mt7623.h
@@ -0,0 +1,66 @@
+/* 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>
+
+#include <dt-bindings/clock/mt7623-clk.h>
+
+/* Machine ID */
+#define CONFIG_MACH_TYPE 7623
+
+/* 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
+
+/* Serial device */
+#define CONFIG_SYS_NS16550_CLK 26000000
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_BAUDRATE 115200
+
+/* 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

View file

@ -0,0 +1,617 @@
From patchwork Tue Oct 2 06:13:41 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot, 04/20] arm: dts: MediaTek: add MT7629 reference board support
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977709
Message-Id: <18b18d60f006d1da99b9442cac2424963d37958c.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:41 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds mt7629.dtsi and reference board support.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
arch/arm/dts/Makefile | 3 +
arch/arm/dts/mt7629-rfb.dts | 71 ++++++++++
arch/arm/dts/mt7629.dtsi | 232 +++++++++++++++++++++++++++++++
include/configs/mt7629.h | 2 +
include/dt-bindings/clock/mt7629-clk.h | 217 +++++++++++++++++++++++++++++
include/dt-bindings/power/mt7629-power.h | 13 ++
6 files changed, 538 insertions(+)
create mode 100644 arch/arm/dts/mt7629-rfb.dts
create mode 100644 arch/arm/dts/mt7629.dtsi
create mode 100644 include/dt-bindings/clock/mt7629-clk.h
create mode 100644 include/dt-bindings/power/mt7629-power.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 44ebc50..9f88146 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -554,6 +554,9 @@ dtb-$(CONFIG_TARGET_STM32MP1) += \
dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt7629-rfb.dtb
+
targets += $(dtb-y)
# Add any required device tree compiler flags here
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
new file mode 100644
index 0000000..ed85450
--- /dev/null
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -0,0 +1,71 @@
+/*
+ * 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 {
+ pins_bus {
+ groups = "nor_flash_io", "nor_flash_wp",
+ "nor_flash_hold";
+ function = "nor_flash";
+ };
+ };
+
+ 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";
+};
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
new file mode 100644
index 0000000..0e03e2d
--- /dev/null
+++ b/arch/arm/dts/mt7629.dtsi
@@ -0,0 +1,232 @@
+/*
+ * 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,mt7629-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 = "ns16550a";
+ 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 = "ns16550a";
+ 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 = "ns16550a";
+ 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>;
+ };
+};
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
index ea979f0..d57adaa 100644
--- a/include/configs/mt7629.h
+++ b/include/configs/mt7629.h
@@ -11,6 +11,8 @@
#include <linux/sizes.h>
+#include <dt-bindings/clock/mt7629-clk.h>
+
#ifndef __ASSEMBLY__
extern unsigned long get_spl_size(void);
#endif
diff --git a/include/dt-bindings/clock/mt7629-clk.h b/include/dt-bindings/clock/mt7629-clk.h
new file mode 100644
index 0000000..e3a451d
--- /dev/null
+++ b/include/dt-bindings/clock/mt7629-clk.h
@@ -0,0 +1,217 @@
+/* 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_FDIVS_OFF 10
+
+#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_MUXES_OFF 73
+
+#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_0 */
+#define CLK_SGMII0_TX_EN 0
+#define CLK_SGMII0_RX_EN 1
+#define CLK_SGMII0_CDR_REF 2
+#define CLK_SGMII0_CDR_FB 3
+#define CLK_SGMII0_NR_CLK 4
+
+/* SGMIISYS_1 */
+#define CLK_SGMII1_TX_EN 0
+#define CLK_SGMII1_RX_EN 1
+#define CLK_SGMII1_CDR_REF 2
+#define CLK_SGMII1_CDR_FB 3
+#define CLK_SGMII1_NR_CLK 4
+
+#endif /* _DT_BINDINGS_CLK_MT7629_H */
diff --git a/include/dt-bindings/power/mt7629-power.h b/include/dt-bindings/power/mt7629-power.h
new file mode 100644
index 0000000..c7e6130
--- /dev/null
+++ b/include/dt-bindings/power/mt7629-power.h
@@ -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 */

View file

@ -0,0 +1,104 @@
From patchwork Tue Oct 2 06:13:43 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,06/20] configs: MediaTek: add MT7629 reference board support
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977704
Message-Id: <954f511890383a9df28fa6b20ebe025084b32370.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:43 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds defconfig for the MT7629 reference board.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
configs/mt7629_rfb_defconfig | 73 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 configs/mt7629_rfb_defconfig
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
new file mode 100644
index 0000000..2ae9c8f
--- /dev/null
+++ b/configs/mt7629_rfb_defconfig
@@ -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_SYS_NS16550=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

View file

@ -0,0 +1,88 @@
From patchwork Tue Oct 2 06:13:44 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,
07/20] configs: MediaTek: add MT7623 Bananapi R2 board support
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977703
Message-Id: <e02ee94b8b68b9ca5d784527fecd6710d80446f1.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:44 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
From: Weijie Gao <weijie.gao@mediatek.com>
This patch adds defconfig for the MT7623 Bananapi R2 board.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
configs/mt7623n_bpir2_defconfig | 53 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 configs/mt7623n_bpir2_defconfig
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
new file mode 100644
index 0000000..a896d6a
--- /dev/null
+++ b/configs/mt7623n_bpir2_defconfig
@@ -0,0 +1,53 @@
+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_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_SYS_NS16550=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

View file

@ -0,0 +1,909 @@
From patchwork Tue Oct 2 06:13:46 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,09/20] clk: MediaTek: add clock driver for MT7623 SoC.
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977714
Message-Id: <1b21e108d37dc1a46f07f8f10aab239db7ee21d0.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:46 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds the hardware details of MT7623 clock blocks.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/clk/mediatek/Makefile | 1 +
drivers/clk/mediatek/clk-mt7623.c | 867 ++++++++++++++++++++++++++++++++++++++
2 files changed, 868 insertions(+)
create mode 100644 drivers/clk/mediatek/clk-mt7623.c
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 297f99d..0632dc8 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -3,4 +3,5 @@
obj-$(CONFIG_ARCH_MEDIATEK) += clk-mtk.o
# SoC Drivers
+obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
new file mode 100644
index 0000000..b706877
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7623.c
@@ -0,0 +1,867 @@
+// 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 "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 = &eth_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,
+ .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_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_clk_init(dev, &mt7623_clk_tree);
+}
+
+static int mt7623_infracfg_probe(struct udevice *dev)
+{
+ return mtk_clk_gate_init(dev, &mt7623_clk_tree, infra_cgs);
+}
+
+static int mt7623_pericfg_probe(struct udevice *dev)
+{
+ return mtk_clk_gate_init(dev, &mt7623_clk_tree, peri_cgs);
+}
+
+static int mt7623_ethsys_probe(struct udevice *dev)
+{
+ return mtk_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,
+};

View file

@ -0,0 +1,143 @@
From patchwork Tue Oct 2 06:13:47 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,10/20] timer: MediaTek: add timer driver for MediaTek SoCs
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977708
Message-Id: <d615166666683e3210e0afe7e81a360b28baee90.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:47 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds clock source/event for the timer found on the Mediatek SoCs.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/timer/Kconfig | 7 ++++
drivers/timer/Makefile | 1 +
drivers/timer/mtk_timer.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+)
create mode 100644 drivers/timer/mtk_timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index a7d600b..83ec0e6 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -147,4 +147,11 @@ config MPC83XX_TIMER
Select this to enable support for the timer found on
devices based on the MPC83xx family of SoCs.
+config MTK_TIMER
+ bool "MediaTek timer support"
+ depends on TIMER
+ help
+ Select this to enable support for the timer found on
+ MediaTek devices.
+
endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 7f19c49..c4fbab2 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -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
diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
new file mode 100644
index 0000000..b5e76bd
--- /dev/null
+++ b/drivers/timer/mtk_timer.c
@@ -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,
+};

View file

@ -0,0 +1,197 @@
From patchwork Tue Oct 2 06:13:48 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,
11/20] watchdog: MediaTek: add watchdog driver for MediaTek SoCs
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977705
Message-Id: <9b2fea0152ddf3254de66870136a25174ca0841d.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:48 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds a common driver for the Mediatek SoC integrated watchdog.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/watchdog/Kconfig | 8 +++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/mtk_wdt.c | 135 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+)
create mode 100644 drivers/watchdog/mtk_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index d545b3e..57a12f5 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -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
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 08406ca..04fa4a6 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
obj-$(CONFIG_WDT_ORION) += orion_wdt.o
obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o
+obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
new file mode 100644
index 0000000..0b50173
--- /dev/null
+++ b/drivers/watchdog/mtk_wdt.c
@@ -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,
+};

View file

@ -0,0 +1,398 @@
From patchwork Tue Oct 2 06:13:51 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,
14/20] power domain: MediaTek: add power domain driver for MT7629 SoC
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977719
Message-Id: <b1292bd95d2e449b276571a595faa58794dcebb9.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:51 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This adds a power domain driver for the Mediatek SCPSYS unit.
The System Control Processor System (SCPSYS) has several power
management related tasks in the system. The tasks include thermal
measurement, dynamic voltage frequency scaling (DVFS), interrupt
filter and lowlevel sleep control. The System Power Manager (SPM)
inside the SCPSYS is for the MTCMOS power domain control.
For now this driver only adds power domain support.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/power/domain/Kconfig | 7 +
drivers/power/domain/Makefile | 1 +
drivers/power/domain/mtk-power-domain.c | 326 ++++++++++++++++++++++++++++++++
3 files changed, 334 insertions(+)
create mode 100644 drivers/power/domain/mtk-power-domain.c
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 2c34488..e479fed 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -16,6 +16,13 @@ config BCM6328_POWER_DOMAIN
Enable support for manipulating BCM6345 power domains via MMIO
mapped registers.
+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
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index 6bdaa17..d6c7aa7 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-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
diff --git a/drivers/power/domain/mtk-power-domain.c b/drivers/power/domain/mtk-power-domain.c
new file mode 100644
index 0000000..5ebeabd
--- /dev/null
+++ b/drivers/power/domain/mtk-power-domain.c
@@ -0,0 +1,326 @@
+// 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/mt7629-power.h>
+
+#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_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_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_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;
+
+ 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;
+
+ if (power_domain->id >= ARRAY_SIZE(scpd->data))
+ return -EINVAL;
+
+ 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_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,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),
+};

View file

@ -0,0 +1,153 @@
From patchwork Tue Oct 2 06:13:52 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,
15/20] power domain: MediaTek: add power domain driver for MT7623 SoC
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977710
Message-Id: <da4a9aa9132a653a421531cfd09b52c1a9f5a364.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:52 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This adds power domain (scpsys) support for MT7623 SoC.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/power/domain/mtk-power-domain.c | 80 +++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/drivers/power/domain/mtk-power-domain.c b/drivers/power/domain/mtk-power-domain.c
index 5ebeabd..8b97a16 100644
--- a/drivers/power/domain/mtk-power-domain.c
+++ b/drivers/power/domain/mtk-power-domain.c
@@ -14,8 +14,18 @@
#include <asm/processor.h>
#include <linux/iopoll.h>
+#include <dt-bindings/power/mt7623-power.h>
#include <dt-bindings/power/mt7629-power.h>
+#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
@@ -28,6 +38,15 @@
#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)
@@ -40,6 +59,7 @@
#define DCM_TOP_EN BIT(0)
enum scp_domain_type {
+ SCPSYS_MT7623,
SCPSYS_MT7629,
};
@@ -61,6 +81,59 @@ struct scp_domain {
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,
@@ -252,6 +325,9 @@ static int mtk_power_domain_hook(struct udevice *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;
@@ -303,6 +379,10 @@ static int mtk_power_domain_probe(struct udevice *dev)
static const struct udevice_id mtk_power_domain_ids[] = {
{
+ .compatible = "mediatek,mt7623-scpsys",
+ .data = SCPSYS_MT7623,
+ },
+ {
.compatible = "mediatek,mt7629-scpsys",
.data = SCPSYS_MT7629,
},

View file

@ -0,0 +1,57 @@
From patchwork Tue Oct 2 06:13:53 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,
16/20] serial: 16550: allow the driver to support MediaTek serial
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977706
Message-Id: <ed6cd147dd628fa30748f62a063849433fe6254b.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:53 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
MediaTek UARTs has a highspeed register which influences the calcualtion
of the divisor. This patch adds an extra control in ns16550.c to suuport
MediaTek SoCs.
Note that we don't support the baudrate larger than 115200 currently.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/serial/ns16550.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index f9041aa..f5410af 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -148,6 +148,13 @@ int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
static void NS16550_setbrg(NS16550_t com_port, int baud_divisor)
{
+#ifdef CONFIG_ARCH_MEDIATEK
+ /*
+ * MediaTek UARTs has an extra highspeed register.
+ * We need to clear it if baudrate <= 115200.
+ */
+ serial_out(0, &com_port->reg9);
+#endif
serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
serial_out(baud_divisor & 0xff, &com_port->dll);
serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
@@ -261,6 +268,9 @@ static inline void _debug_uart_init(void)
serial_dout(&com_port->mcr, UART_MCRVAL);
serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
+#ifdef CONFIG_ARCH_MEDIATEK
+ serial_dout(&com_port->reg9, 0);
+#endif
serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
serial_dout(&com_port->dll, baud_divisor & 0xff);
serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);

View file

@ -0,0 +1,824 @@
From patchwork Tue Oct 2 06:13:54 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,17/20] ram: MediaTek: add DDR3 driver for MT7629 SoC
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977724
Message-Id: <9e157983f9b559ea56166f8d1d6b5bf3b2c08f21.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>,
u-boot@lists.denx.de, Wu Zou <wu.zou@mediatek.com>
Date: Tue, 2 Oct 2018 14:13:54 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
This patch adds a DDR3 driver for MT7629 SoC.
Signed-off-by: Wu Zou <wu.zou@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/ram/Makefile | 1 +
drivers/ram/mediatek/Makefile | 7 +
drivers/ram/mediatek/ddr3-mt7629.c | 766 +++++++++++++++++++++++++++++++++++++
3 files changed, 774 insertions(+)
create mode 100644 drivers/ram/mediatek/Makefile
create mode 100644 drivers/ram/mediatek/ddr3-mt7629.c
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 4ad3604..65cba80 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
diff --git a/drivers/ram/mediatek/Makefile b/drivers/ram/mediatek/Makefile
new file mode 100644
index 0000000..95507b5
--- /dev/null
+++ b/drivers/ram/mediatek/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2018 MediaTek Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+#
+
+obj-$(CONFIG_TARGET_MT7629) = ddr3-mt7629.o
diff --git a/drivers/ram/mediatek/ddr3-mt7629.c b/drivers/ram/mediatek/ddr3-mt7629.c
new file mode 100644
index 0000000..26882a9
--- /dev/null
+++ b/drivers/ram/mediatek/ddr3-mt7629.c
@@ -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),
+};

View file

@ -0,0 +1,474 @@
From patchwork Tue Oct 2 06:13:55 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,18/20] spi: mtk_qspi: add qspi driver for MT7629 SoC
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977717
Message-Id: <8fb2d6da7f5a599cc8fcb89b979efbc9e7e9c243.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>,
u-boot@lists.denx.de, Jagan Teki <jagan@openedev.com>,
Guochun Mao <guochun.mao@mediatek.com>
Date: Tue, 2 Oct 2018 14:13:55 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
From: Guochun Mao <guochun.mao@mediatek.com>
This patch adds MT7629 qspi driver for accessing SPI NOR flash.
Cc: Jagan Teki <jagan@openedev.com>
Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
---
drivers/spi/Kconfig | 7 +
drivers/spi/Makefile | 1 +
drivers/spi/mtk_qspi.c | 406 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 414 insertions(+)
create mode 100644 drivers/spi/mtk_qspi.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7d4d47d..0c37ac0 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -117,6 +117,13 @@ config MVEBU_A3700_SPI
used to access the SPI NOR flash on platforms embedding this
Marvell IP core.
+config MTK_QSPI
+ bool "Mediatek QSPI driver"
+ help
+ Enable the Mediatek QSPI driver. This driver can be
+ used to access the SPI NOR flash on platforms embedding this
+ Mediatek QSPI IP core.
+
config PIC32_SPI
bool "Microchip PIC32 SPI driver"
depends on MACH_PIC32
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6679987..f1c6400 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+obj-$(CONFIG_MTK_QSPI) += mtk_qspi.o
obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
obj-$(CONFIG_MXC_SPI) += mxc_spi.o
obj-$(CONFIG_MXS_SPI) += mxs_spi.o
diff --git a/drivers/spi/mtk_qspi.c b/drivers/spi/mtk_qspi.c
new file mode 100644
index 0000000..87117fa
--- /dev/null
+++ b/drivers/spi/mtk_qspi.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek, Inc.
+ * Author : Guochun.Mao@mediatek.com
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+
+/* Register Offset */
+struct mtk_qspi_regs {
+ u32 cmd;
+ u32 cnt;
+ u32 rdsr;
+ u32 rdata;
+ u32 radr[3];
+ u32 wdata;
+ u32 prgdata[6];
+ u32 shreg[10];
+ u32 cfg[2];
+ u32 shreg10;
+ u32 mode_mon;
+ u32 status[4];
+ u32 flash_time;
+ u32 flash_cfg;
+ u32 reserved_0[3];
+ u32 sf_time;
+ u32 pp_dw_data;
+ u32 reserved_1;
+ u32 delsel_0[2];
+ u32 intrstus;
+ u32 intren;
+ u32 reserved_2;
+ u32 cfg3;
+ u32 reserved_3;
+ u32 chksum;
+ u32 aaicmd;
+ u32 wrprot;
+ u32 radr3;
+ u32 dual;
+ u32 delsel_1[3];
+};
+
+struct mtk_qspi_platdata {
+ fdt_addr_t reg_base;
+ fdt_addr_t mem_base;
+};
+
+struct mtk_qspi_priv {
+ struct mtk_qspi_regs *regs;
+ unsigned long *mem_base;
+ u8 op;
+ /* Max paras length is 3 bytes. */
+ u8 tx[3];
+ u32 txlen;
+ u8 *rx;
+ u32 rxlen;
+};
+
+#define MTK_QSPI_CMD_POLLINGREG_US 500000
+#define MTK_QSPI_WRBUF_SIZE 256
+#define MTK_QSPI_COMMAND_ENABLE 0x30
+
+/* NOR flash controller commands */
+#define MTK_QSPI_RD_TRIGGER BIT(0)
+#define MTK_QSPI_READSTATUS BIT(1)
+#define MTK_QSPI_PRG_CMD BIT(2)
+#define MTK_QSPI_WR_TRIGGER BIT(4)
+#define MTK_QSPI_WRITESTATUS BIT(5)
+#define MTK_QSPI_AUTOINC BIT(7)
+
+/* NOR flash commands */
+#define MTK_QSPI_OP_WREN 0x6
+#define MTK_QSPI_OP_READ_QUAD 0x6B
+#define MTK_QSPI_OP_READ_DUAL 0x3B
+#define MTK_QSPI_OP_FAST_READ 0xB
+#define MTK_QSPI_OP_READ 0x3
+#define MTK_QSPI_OP_PP 0x2
+
+#define MTK_QSPI_MAX_RX_TX_SHIFT 0x6
+#define MTK_QSPI_MAX_SHIFT 0x8
+
+#define MTK_QSPI_WR_BUF_ENABLE 0x1
+#define MTK_QSPI_WR_BUF_DISABLE 0x0
+
+#define MTK_QSPI_FAST_READ_ENABLE 0x1
+#define MTK_QSPI_FAST_READ_DISABLE 0x0
+
+#define MTK_QSPI_READ_MODE_MASK 0x1f
+#define MTK_QSPI_READ_QUAD_EN 0x4
+#define MTK_QSPI_READ_DUAL_EN 0x1
+
+static int mtk_qspi_execute_cmd(struct mtk_qspi_priv *priv, u8 cmd)
+{
+ u8 tmp;
+ u8 val = cmd & ~MTK_QSPI_AUTOINC;
+
+ writeb(cmd, &priv->regs->cmd);
+
+ return readb_poll_timeout(&priv->regs->cmd, tmp, !(val & tmp),
+ MTK_QSPI_CMD_POLLINGREG_US);
+}
+
+static int mtk_qspi_tx_rx(struct mtk_qspi_priv *priv)
+{
+ int len = 1 + priv->txlen + priv->rxlen;
+ int i, ret, idx;
+
+ if (len > MTK_QSPI_MAX_SHIFT)
+ return -ERR_INVAL;
+
+ writeb(len * 8, &priv->regs->cnt);
+
+ /* start at PRGDATA5, go down to PRGDATA0 */
+ idx = MTK_QSPI_MAX_RX_TX_SHIFT - 1;
+
+ /* opcode */
+ writeb(priv->op, &priv->regs->prgdata[idx]);
+ idx--;
+
+ /* program TX data */
+ for (i = 0; i < priv->txlen; i++, idx--)
+ writeb(priv->tx[i], &priv->regs->prgdata[idx]);
+
+ /* clear out rest of TX registers */
+ while (idx >= 0) {
+ writeb(0, &priv->regs->prgdata[idx]);
+ idx--;
+ }
+
+ ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_PRG_CMD);
+ if (ret)
+ return ret;
+
+ /* restart at first RX byte */
+ idx = priv->rxlen - 1;
+
+ /* read out RX data */
+ for (i = 0; i < priv->rxlen; i++, idx--)
+ priv->rx[i] = readb(&priv->regs->shreg[idx]);
+
+ return 0;
+}
+
+static void mtk_qspi_set_read_mode(struct mtk_qspi_priv *priv)
+{
+ u8 val = readb(&priv->regs->dual) & (~MTK_QSPI_READ_MODE_MASK);
+
+ /* clean fast read bit */
+ writeb(MTK_QSPI_FAST_READ_DISABLE, &priv->regs->cfg[0]);
+
+ switch (priv->op) {
+ case MTK_QSPI_OP_FAST_READ:
+ writeb(MTK_QSPI_FAST_READ_ENABLE, &priv->regs->cfg[0]);
+ break;
+ case MTK_QSPI_OP_READ_DUAL:
+ writeb(priv->op, &priv->regs->prgdata[3]);
+ val |= MTK_QSPI_READ_DUAL_EN;
+ break;
+ case MTK_QSPI_OP_READ_QUAD:
+ writeb(priv->op, &priv->regs->prgdata[4]);
+ val |= MTK_QSPI_READ_QUAD_EN;
+ break;
+ default:
+ break;
+ }
+
+ writeb(val, &priv->regs->dual);
+}
+
+static int mtk_qspi_read(struct mtk_qspi_priv *priv,
+ u32 addr, u8 *buf, u32 len)
+{
+ memcpy(buf, (u8 *)priv->mem_base + addr, len);
+ return 0;
+}
+
+static void mtk_qspi_set_addr(struct mtk_qspi_priv *priv, u32 addr)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ writeb(addr & 0xff, &priv->regs->radr[i]);
+ addr >>= 8;
+ }
+}
+
+static int mtk_qspi_write_single_byte(struct mtk_qspi_priv *priv,
+ u32 addr, u32 length, const u8 *data)
+{
+ int i, ret;
+
+ mtk_qspi_set_addr(priv, addr);
+
+ for (i = 0; i < length; i++) {
+ writeb(*data++, &priv->regs->wdata);
+ ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int mtk_qspi_write_buffer(struct mtk_qspi_priv *priv, u32 addr,
+ const u8 *buf)
+{
+ int i, data;
+
+ mtk_qspi_set_addr(priv, addr);
+
+ for (i = 0; i < MTK_QSPI_WRBUF_SIZE; i += 4) {
+ data = buf[i + 3] << 24 | buf[i + 2] << 16 |
+ buf[i + 1] << 8 | buf[i];
+ writel(data, &priv->regs->pp_dw_data);
+ }
+
+ return mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
+}
+
+static int mtk_qspi_write(struct mtk_qspi_priv *priv,
+ u32 addr, const u8 *buf, u32 len)
+{
+ int ret;
+
+ /* setting pre-fetch buffer for page program*/
+ writel(MTK_QSPI_WR_BUF_ENABLE, &priv->regs->cfg[1]);
+ while (len >= MTK_QSPI_WRBUF_SIZE) {
+ ret = mtk_qspi_write_buffer(priv, addr, buf);
+ if (ret < 0)
+ return ret;
+
+ len -= MTK_QSPI_WRBUF_SIZE;
+ addr += MTK_QSPI_WRBUF_SIZE;
+ buf += MTK_QSPI_WRBUF_SIZE;
+ }
+ /* disable pre-fetch buffer for page program*/
+ writel(MTK_QSPI_WR_BUF_DISABLE, &priv->regs->cfg[1]);
+
+ if (len)
+ return mtk_qspi_write_single_byte(priv, addr, len, buf);
+
+ return 0;
+}
+
+static int mtk_qspi_claim_bus(struct udevice *dev)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int mtk_qspi_release_bus(struct udevice *dev)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int mtk_qspi_transfer(struct mtk_qspi_priv *priv, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ u32 bytes = DIV_ROUND_UP(bitlen, 8);
+ u32 addr;
+
+ if (!bytes)
+ return -ERR_INVAL;
+
+ if (dout) {
+ if (flags & SPI_XFER_BEGIN) {
+ /* dout format unknown here,
+ * parse op code & potential paras first.
+ */
+ priv->op = *(u8 *)dout;
+ if (bytes > 1)
+ memcpy(priv->tx, (u8 *)dout + 1,
+ bytes <= 4 ? bytes - 1 : 3);
+ priv->txlen = bytes - 1;
+ }
+
+ if (flags == SPI_XFER_END) {
+ if (priv->op == MTK_QSPI_OP_PP) {
+ /* here dout format should be:
+ * 1B op-code + 3B address + data
+ */
+ if (bytes <= 4)
+ return -ERR_INVAL;
+ addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
+ priv->tx[2];
+ return mtk_qspi_write(priv, addr,
+ (u8 *)dout + 4,
+ bytes - 4);
+ }
+
+ /* operations without reveiving data. */
+ priv->rx = NULL;
+ priv->rxlen = 0;
+ return mtk_qspi_tx_rx(priv);
+ }
+ }
+
+ if (din) {
+ if (priv->op == MTK_QSPI_OP_READ ||
+ priv->op == MTK_QSPI_OP_FAST_READ ||
+ priv->op == MTK_QSPI_OP_READ_DUAL ||
+ priv->op == MTK_QSPI_OP_READ_QUAD) {
+ /* if run to here, priv->tx[3] should be the address
+ * where read data from,
+ * and, din is the buf to receive data.
+ */
+ mtk_qspi_set_read_mode(priv);
+ addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
+ priv->tx[2];
+ return mtk_qspi_read(priv, addr, (u8 *)din, bytes);
+ }
+
+ /* would be reading flash register */
+ priv->rx = (u8 *)din;
+ priv->rxlen = bytes;
+ return mtk_qspi_tx_rx(priv);
+ }
+
+ return 0;
+}
+
+static int mtk_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct udevice *bus = dev->parent;
+ struct mtk_qspi_priv *priv = dev_get_priv(bus);
+
+ return mtk_qspi_transfer(priv, bitlen, dout, din, flags);
+}
+
+static int mtk_qspi_set_speed(struct udevice *bus, uint speed)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int mtk_qspi_set_mode(struct udevice *bus, uint mode)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int mtk_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+ struct resource res_reg, res_mem;
+ struct mtk_qspi_platdata *plat = bus->platdata;
+ int ret;
+
+ ret = dev_read_resource_byname(bus, "reg_base", &res_reg);
+ if (ret) {
+ debug("Error: can't get regs base address(ret = %d)!\n", ret);
+ return -ENOMEM;
+ }
+ ret = dev_read_resource_byname(bus, "mem_base", &res_mem);
+ if (ret) {
+ debug("Error: can't get mmap base address(ret = %d)!\n", ret);
+ return -ENOMEM;
+ }
+ plat->mem_base = res_mem.start;
+ plat->reg_base = res_reg.start;
+
+ return 0;
+}
+
+static int mtk_qspi_probe(struct udevice *bus)
+{
+ struct mtk_qspi_platdata *plat = dev_get_platdata(bus);
+ struct mtk_qspi_priv *priv = dev_get_priv(bus);
+
+ priv->regs = (struct mtk_qspi_regs *)plat->reg_base;
+ priv->mem_base = (unsigned long *)plat->mem_base;
+
+ writel(MTK_QSPI_COMMAND_ENABLE, &priv->regs->wrprot);
+
+ return 0;
+}
+
+static const struct dm_spi_ops mtk_qspi_ops = {
+ .claim_bus = mtk_qspi_claim_bus,
+ .release_bus = mtk_qspi_release_bus,
+ .xfer = mtk_qspi_xfer,
+ .set_speed = mtk_qspi_set_speed,
+ .set_mode = mtk_qspi_set_mode,
+};
+
+static const struct udevice_id mtk_qspi_ids[] = {
+ { .compatible = "mediatek,mt7629-qspi" },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_qspi) = {
+ .name = "mtk_qspi",
+ .id = UCLASS_SPI,
+ .of_match = mtk_qspi_ids,
+ .ops = &mtk_qspi_ops,
+ .ofdata_to_platdata = mtk_qspi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct mtk_qspi_platdata),
+ .priv_auto_alloc_size = sizeof(struct mtk_qspi_priv),
+ .probe = mtk_qspi_probe,
+};

View file

@ -0,0 +1,53 @@
From patchwork Tue Oct 2 06:13:57 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [U-Boot,20/20] MAINTAINERS: add an entry for MediaTek
X-Patchwork-Submitter: Ryder Lee <ryder.lee@mediatek.com>
X-Patchwork-Id: 977725
Message-Id: <57e2a2148427c56b47886d79cd4393c4a0f6685a.1538460580.git.ryder.lee@mediatek.com>
To: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>, Albert
Aribaud <albert.u.boot@aribaud.net>
Cc: Steven Liu <steven.liu@mediatek.com>,
Roy Luo <cheng-hao.luo@mediatek.com>, Sean Wang <sean.wang@mediatek.com>,
Weijie Gao <weijie.gao@mediatek.com>, u-boot@lists.denx.de
Date: Tue, 2 Oct 2018 14:13:57 +0800
From: Ryder Lee <ryder.lee@mediatek.com>
List-Id: U-Boot discussion <u-boot.lists.denx.de>
Add an entry for MediaTek.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
MAINTAINERS | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 6147a4f..f3b4f95 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -157,6 +157,24 @@ 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: 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/mtkimage.c
+N: mediatek
+
ARM OWL
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
S: Maintained

View file

@ -0,0 +1,12 @@
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
index a896d6a..642dc9f 100644
--- a/configs/mt7623n_bpir2_defconfig
+++ b/configs/mt7623n_bpir2_defconfig
@@ -49,5 +49,7 @@ CONFIG_SYSRESET_WATCHDOG=y
CONFIG_TIMER=y
CONFIG_MTK_TIMER=y
CONFIG_WDT_MTK=y
+CONFIG_FS_EXT4=y
+CONFIG_EXT4_WRITE=y
CONFIG_LZMA=y
# CONFIG_EFI_LOADER is not set

View file

@ -0,0 +1,21 @@
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
index 642dc9f..ce30e40 100644
--- a/configs/mt7623n_bpir2_defconfig
+++ b/configs/mt7623n_bpir2_defconfig
@@ -13,6 +13,7 @@ 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_BOOTZ=y
CONFIG_CMD_BOOTMENU=y
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_XIMG is not set
@@ -25,6 +26,8 @@ CONFIG_CMD_READ=y
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_EMBED=y

View file

@ -0,0 +1,67 @@
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
index 00bad8bb..c01e4cbc 100644
--- a/include/configs/mt7623.h
+++ b/include/configs/mt7623.h
@@ -41,7 +41,7 @@
GENERATED_GBL_DATA_SIZE)
/* UBoot -> Kernel */
-#define CONFIG_LOADADDR 0x84000000
+#define CONFIG_LOADADDR 0x82000000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
/* Serial device */
@@ -56,11 +56,50 @@
/* DRAM */
#define CONFIG_SYS_SDRAM_BASE 0x80000000
-/* This is neede for kernel booting */
-#define FDT_HIGH "fdt_high=0xac000000\0"
+#define SCRIPT_BOOT \
+ "fileload=${mmctype}load mmc ${devnum}:${mmcpart} " \
+ "${loadaddr} ${mmcfile}\0" \
+ "kernload=setenv loadaddr ${kernel_addr_r};" \
+ "setenv mmcfile ${mmckernfile};" \
+ "run fileload\0" \
+ "initrdload=setenv loadaddr ${rdaddr};" \
+ "setenv mmcfile ${mmcinitrdfile};" \
+ "run fileload\0" \
+ "fdtload=setenv loadaddr ${fdtaddr};" \
+ "setenv mmcfile ${mmcfdtfile};" \
+ "run fileload\0" \
+ "scriptload=setenv loadaddr ${scriptaddr};" \
+ "setenv mmcfile ${mmcscriptfile};" \
+ "run fileload\0" \
+ "scriptboot=echo Running ${mmcscriptfile} from: mmc ${devnum}:${mmcpart} using ${mmcscriptfile};" \
+ "source ${scriptaddr};" \
/* Extra environment variables */
#define CONFIG_EXTRA_ENV_SETTINGS \
- FDT_HIGH
+ "loadaddr=0x82000000\0" \
+ "kernel_addr_r=0x82000000\0" \
+ "scriptaddr=0x85F80000\0" \
+ "fdtaddr=0x86000000\0" \
+ "fdt_addr_r=0x86000000\0" \
+ "rdaddr=0x86080000\0" \
+ "ramdisk_addr_r=0x86080000\0" \
+ "bootm_size=0x10000000\0" \
+ "mmckernfile=boot/zImage\0" \
+ "mmcinitrdfile= boot/uInitrd\0" \
+ "mmcfdtfile=boot/dtb/mt7623n-bananapi-bpi-r2.dtb\0" \
+ "mmcscriptfile=boot/boot.scr\0" \
+ "mmctype=ext4\0" \
+ "devnum=1\0" \
+ "mmcpart=1\0" \
+ SCRIPT_BOOT
+
+#define CONFIG_BOOTCOMMAND \
+ "mmc dev 1;" \
+ "run scriptload;" \
+ "run scriptboot;" \
+ "setenv devnum 0;" \
+ "mmc dev 0;" \
+ "run scriptload;" \
+ "run scriptboot"
#endif