[U-Boot] [PATCH v2 0/6] U-boot: add PCIe, its PHY and AHCI support

This series adds PCIe/PHY drivers which were adapted from Linux version. The related drivers were tested on bpi-r2.
To get AHCI (SATA) working on R2 (ASM1061 PCIe2SATA-Controller) 2 addional changes are needed (see Parts 5+6 from Oleksandr Rybalko)
changes since v1: - replaced mt2701 PCIe driver with version (PHY+PCIe) from Ryder
Oleksandr Rybalko (2): ahci-pci: ASM1061 report wrong class, but support AHCI. ata: ahci: Don't forget to clear upper address regs.
Ryder Lee (4): pci: mediatek: add PCIe controller support for MT7623 phy: mediatek: add MediaTek T-PHY support for PCIe arm: dts: add PCIe controller for MT7623 SoC arm: dts: split mtk-reset.h into per-chip header
arch/arm/dts/mt7623.dtsi | 130 +++++- arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 ++ arch/arm/dts/mt7629.dtsi | 2 +- drivers/ata/ahci-pci.c | 1 + drivers/ata/ahci.c | 9 +- drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pcie_mediatek.c | 292 +++++++++++++ drivers/phy/Kconfig | 11 + drivers/phy/Makefile | 1 + drivers/phy/phy-mtk-tphy.c | 388 ++++++++++++++++++ .../reset/{mtk-reset.h => mt7623-reset.h} | 4 +- include/dt-bindings/reset/mt7629-reset.h | 36 ++ 13 files changed, 905 insertions(+), 7 deletions(-) create mode 100644 drivers/pci/pcie_mediatek.c create mode 100644 drivers/phy/phy-mtk-tphy.c rename include/dt-bindings/reset/{mtk-reset.h => mt7623-reset.h} (88%) create mode 100644 include/dt-bindings/reset/mt7629-reset.h
-- 2.17.1

From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe controller support for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com --- drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pcie_mediatek.c | 292 ++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 drivers/pci/pcie_mediatek.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 3fe38f7315..6f19471ae7 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -145,4 +145,12 @@ config PCI_MVEBU Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs.
+config PCIE_MEDIATEK + bool "MediaTek PCIe controller" + depends on DM_PCI + depends on ARCH_MEDIATEK + help + Say Y here if you want to enable PCIe controller support on + MediaTek SoCs. + endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index b5ebd50c85..7093d63918 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ pcie_layerscape_gen4_fixup.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o +obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c new file mode 100644 index 0000000000..3f24060d26 --- /dev/null +++ b/drivers/pci/pcie_mediatek.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek PCIe host controller driver. + * + * Copyright (c) 2017-2019 MediaTek Inc. + * Author: Ryder Lee ryder.lee@mediatek.com + * Honghui Zhang honghui.zhang@mediatek.com + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <pci.h> +#include <reset.h> +#include <asm/io.h> +#include <linux/iopoll.h> +#include <linux/list.h> + +/* PCIe shared registers */ +#define PCIE_SYS_CFG 0x00 +#define PCIE_INT_ENABLE 0x0c +#define PCIE_CFG_ADDR 0x20 +#define PCIE_CFG_DATA 0x24 + +/* PCIe per port registers */ +#define PCIE_BAR0_SETUP 0x10 +#define PCIE_CLASS 0x34 +#define PCIE_LINK_STATUS 0x50 + +#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +#define PCIE_PORT_PERST(x) BIT(1 + (x)) +#define PCIE_PORT_LINKUP BIT(0) +#define PCIE_BAR_MAP_MAX GENMASK(31, 16) + +#define PCIE_BAR_ENABLE BIT(0) +#define PCIE_REVISION_ID BIT(0) +#define PCIE_CLASS_CODE (0x60400 << 8) +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \ + ((((regn) >> 8) & GENMASK(3, 0)) << 24)) +#define PCIE_CONF_ADDR(regn, bdf) \ + (PCIE_CONF_REG(regn) | (bdf)) + +/* MediaTek specific configuration registers */ +#define PCIE_FTS_NUM 0x70c +#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8) + +#define PCIE_FC_CREDIT 0x73c +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16) + +struct mtk_pcie_port { + void __iomem *base; + struct list_head list; + struct mtk_pcie *pcie; + struct reset_ctl reset; + struct clk sys_ck; + struct phy phy; + u32 slot; +}; + +struct mtk_pcie { + void __iomem *base; + struct clk free_ck; + struct list_head ports; +}; + +static int mtk_pcie_config_address(struct udevice *udev, pci_dev_t bdf, + uint offset, void **paddress) +{ + struct mtk_pcie *pcie = dev_get_priv(udev); + + writel(PCIE_CONF_ADDR(offset, bdf), pcie->base + PCIE_CFG_ADDR); + *paddress = pcie->base + PCIE_CFG_DATA + (offset & 3); + + return 0; +} + +static int mtk_pcie_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + return pci_generic_mmap_read_config(bus, mtk_pcie_config_address, + bdf, offset, valuep, size); +} + +static int mtk_pcie_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + return pci_generic_mmap_write_config(bus, mtk_pcie_config_address, + bdf, offset, value, size); +} + +static const struct dm_pci_ops mtk_pcie_ops = { + .read_config = mtk_pcie_read_config, + .write_config = mtk_pcie_write_config, +}; + +static void mtk_pcie_port_free(struct mtk_pcie_port *port) +{ + list_del(&port->list); + free(port); +} + +static int mtk_pcie_startup_port(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie = port->pcie; + u32 slot = PCI_DEV(port->slot << 11); + u32 val; + int err; + + /* assert port PERST_N */ + val = readl(pcie->base + PCIE_SYS_CFG); + val |= PCIE_PORT_PERST(port->slot); + writel(val, pcie->base + PCIE_SYS_CFG); + + /* de-assert port PERST_N */ + val = readl(pcie->base + PCIE_SYS_CFG); + val &= ~PCIE_PORT_PERST(port->slot); + writel(val, pcie->base + PCIE_SYS_CFG); + + /* 100ms timeout value should be enough for Gen1/2 training */ + err = readl_poll_timeout(port->base + PCIE_LINK_STATUS, val, + !!(val & PCIE_PORT_LINKUP), 100000); + if (err) + return -ETIMEDOUT; + + /* disable interrupt */ + val = readl(pcie->base + PCIE_INT_ENABLE); + val &= ~PCIE_PORT_INT_EN(port->slot); + writel(val, pcie->base + PCIE_INT_ENABLE); + + /* map to all DDR region. We need to set it before cfg operation. */ + writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, + port->base + PCIE_BAR0_SETUP); + + /* configure class code and revision ID */ + writel(PCIE_CLASS_CODE | PCIE_REVISION_ID, port->base + PCIE_CLASS); + + /* configure FC credit */ + writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, slot), + pcie->base + PCIE_CFG_ADDR); + val = readl(pcie->base + PCIE_CFG_DATA); + val &= ~PCIE_FC_CREDIT_MASK; + val |= PCIE_FC_CREDIT_VAL(0x806c); + writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, slot), + pcie->base + PCIE_CFG_ADDR); + writel(val, pcie->base + PCIE_CFG_DATA); + + /* configure RC FTS number to 250 when it leaves L0s */ + writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, slot), pcie->base + PCIE_CFG_ADDR); + val = readl(pcie->base + PCIE_CFG_DATA); + val &= ~PCIE_FTS_NUM_MASK; + val |= PCIE_FTS_NUM_L0(0x50); + writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, slot), pcie->base + PCIE_CFG_ADDR); + writel(val, pcie->base + PCIE_CFG_DATA); + + return 0; +} + +static void mtk_pcie_enable_port(struct mtk_pcie_port *port) +{ + int err; + + err = clk_enable(&port->sys_ck); + if (err) + goto exit; + + err = reset_assert(&port->reset); + if (err) + goto exit; + + err = reset_deassert(&port->reset); + if (err) + goto exit; + + err = generic_phy_init(&port->phy); + if (err) + goto exit; + + err = generic_phy_power_on(&port->phy); + if (err) + goto exit; + + if (!mtk_pcie_startup_port(port)) + return; + + pr_err("Port%d link down\n", port->slot); +exit: + mtk_pcie_port_free(port); +} + +static int mtk_pcie_parse_port(struct udevice *dev, u32 slot) +{ + struct mtk_pcie *pcie = dev_get_priv(dev); + struct mtk_pcie_port *port; + char name[10]; + int err; + + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + snprintf(name, sizeof(name), "port%d", slot); + port->base = dev_remap_addr_name(dev, name); + if (!port->base) + return -ENOENT; + + snprintf(name, sizeof(name), "sys_ck%d", slot); + err = clk_get_by_name(dev, name, &port->sys_ck); + if (err) + return err; + + err = reset_get_by_index(dev, slot, &port->reset); + if (err) + return err; + + err = generic_phy_get_by_index(dev, slot, &port->phy); + if (err) + return err; + + port->slot = slot; + port->pcie = pcie; + + INIT_LIST_HEAD(&port->list); + list_add_tail(&port->list, &pcie->ports); + + return 0; +} + +static int mtk_pcie_probe(struct udevice *dev) +{ + struct mtk_pcie *pcie = dev_get_priv(dev); + struct mtk_pcie_port *port, *tmp; + ofnode subnode; + int err; + + INIT_LIST_HEAD(&pcie->ports); + + pcie->base = dev_remap_addr_name(dev, "subsys"); + if (!pcie->base) + return -ENOENT; + + err = clk_get_by_name(dev, "free_ck", &pcie->free_ck); + if (err) + return err; + + /* enable top level clock */ + err = clk_enable(&pcie->free_ck); + if (err) + return err; + + dev_for_each_subnode(subnode, dev) { + struct fdt_pci_addr addr; + u32 slot = 0; + + if (!ofnode_is_available(subnode)) + continue; + + err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); + if (err) + return err; + + slot = PCI_DEV(addr.phys_hi); + + err = mtk_pcie_parse_port(dev, slot); + if (err) + return err; + } + + /* enable each port, and then check link status */ + list_for_each_entry_safe(port, tmp, &pcie->ports, list) + mtk_pcie_enable_port(port); + + return 0; +} + +static const struct udevice_id mtk_pcie_ids[] = { + { .compatible = "mediatek,mt7623-pcie", }, + { } +}; + +U_BOOT_DRIVER(pcie_mediatek) = { + .name = "pcie_mediatek", + .id = UCLASS_PCI, + .of_match = mtk_pcie_ids, + .ops = &mtk_pcie_ops, + .probe = mtk_pcie_probe, + .priv_auto_alloc_size = sizeof(struct mtk_pcie), +}; -- 2.17.1

On Sun, Aug 4, 2019 at 8:25 PM Frank Wunderlich frank-w@public-files.de wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe controller support for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pcie_mediatek.c | 292 ++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 drivers/pci/pcie_mediatek.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 3fe38f7315..6f19471ae7 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -145,4 +145,12 @@ config PCI_MVEBU Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs.
+config PCIE_MEDIATEK
bool "MediaTek PCIe controller"
depends on DM_PCI
depends on ARCH_MEDIATEK
help
Say Y here if you want to enable PCIe controller support on
MediaTek SoCs.
This is too generic, is there a version number ? who is the IP vendor behind that Mediatek PCIe ? on which mediatek SoCs ?
endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index b5ebd50c85..7093d63918 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ pcie_layerscape_gen4_fixup.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o +obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c new file mode 100644 index 0000000000..3f24060d26 --- /dev/null +++ b/drivers/pci/pcie_mediatek.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- MediaTek PCIe host controller driver.
- Copyright (c) 2017-2019 MediaTek Inc.
- Author: Ryder Lee ryder.lee@mediatek.com
Honghui Zhang <honghui.zhang@mediatek.com>
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <pci.h> +#include <reset.h> +#include <asm/io.h> +#include <linux/iopoll.h> +#include <linux/list.h>
+/* PCIe shared registers */ +#define PCIE_SYS_CFG 0x00 +#define PCIE_INT_ENABLE 0x0c +#define PCIE_CFG_ADDR 0x20 +#define PCIE_CFG_DATA 0x24
+/* PCIe per port registers */ +#define PCIE_BAR0_SETUP 0x10 +#define PCIE_CLASS 0x34 +#define PCIE_LINK_STATUS 0x50
+#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +#define PCIE_PORT_PERST(x) BIT(1 + (x)) +#define PCIE_PORT_LINKUP BIT(0) +#define PCIE_BAR_MAP_MAX GENMASK(31, 16)
+#define PCIE_BAR_ENABLE BIT(0) +#define PCIE_REVISION_ID BIT(0) +#define PCIE_CLASS_CODE (0x60400 << 8) +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \
((((regn) >> 8) & GENMASK(3, 0)) << 24))
+#define PCIE_CONF_ADDR(regn, bdf) \
(PCIE_CONF_REG(regn) | (bdf))
+/* MediaTek specific configuration registers */ +#define PCIE_FTS_NUM 0x70c +#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8)
+#define PCIE_FC_CREDIT 0x73c +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16)
+struct mtk_pcie_port {
void __iomem *base;
struct list_head list;
struct mtk_pcie *pcie;
struct reset_ctl reset;
struct clk sys_ck;
struct phy phy;
u32 slot;
+};
+struct mtk_pcie {
void __iomem *base;
struct clk free_ck;
struct list_head ports;
+};
+static int mtk_pcie_config_address(struct udevice *udev, pci_dev_t bdf,
uint offset, void **paddress)
+{
struct mtk_pcie *pcie = dev_get_priv(udev);
writel(PCIE_CONF_ADDR(offset, bdf), pcie->base + PCIE_CFG_ADDR);
*paddress = pcie->base + PCIE_CFG_DATA + (offset & 3);
return 0;
+}
+static int mtk_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
return pci_generic_mmap_read_config(bus, mtk_pcie_config_address,
bdf, offset, valuep, size);
+}
+static int mtk_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
+{
return pci_generic_mmap_write_config(bus, mtk_pcie_config_address,
bdf, offset, value, size);
+}
+static const struct dm_pci_ops mtk_pcie_ops = {
.read_config = mtk_pcie_read_config,
.write_config = mtk_pcie_write_config,
+};
+static void mtk_pcie_port_free(struct mtk_pcie_port *port) +{
list_del(&port->list);
free(port);
+}
+static int mtk_pcie_startup_port(struct mtk_pcie_port *port) +{
struct mtk_pcie *pcie = port->pcie;
u32 slot = PCI_DEV(port->slot << 11);
u32 val;
int err;
/* assert port PERST_N */
val = readl(pcie->base + PCIE_SYS_CFG);
val |= PCIE_PORT_PERST(port->slot);
writel(val, pcie->base + PCIE_SYS_CFG);
/* de-assert port PERST_N */
val = readl(pcie->base + PCIE_SYS_CFG);
val &= ~PCIE_PORT_PERST(port->slot);
writel(val, pcie->base + PCIE_SYS_CFG);
/* 100ms timeout value should be enough for Gen1/2 training */
err = readl_poll_timeout(port->base + PCIE_LINK_STATUS, val,
!!(val & PCIE_PORT_LINKUP), 100000);
if (err)
return -ETIMEDOUT;
/* disable interrupt */
val = readl(pcie->base + PCIE_INT_ENABLE);
val &= ~PCIE_PORT_INT_EN(port->slot);
writel(val, pcie->base + PCIE_INT_ENABLE);
You might want to consider using setbits_le32/clrbits_le32.
/* map to all DDR region. We need to set it before cfg operation. */
writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE,
port->base + PCIE_BAR0_SETUP);
/* configure class code and revision ID */
writel(PCIE_CLASS_CODE | PCIE_REVISION_ID, port->base + PCIE_CLASS);
/* configure FC credit */
writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, slot),
pcie->base + PCIE_CFG_ADDR);
val = readl(pcie->base + PCIE_CFG_DATA);
val &= ~PCIE_FC_CREDIT_MASK;
val |= PCIE_FC_CREDIT_VAL(0x806c);
writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, slot),
pcie->base + PCIE_CFG_ADDR);
writel(val, pcie->base + PCIE_CFG_DATA);
/* configure RC FTS number to 250 when it leaves L0s */
writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, slot), pcie->base + PCIE_CFG_ADDR);
val = readl(pcie->base + PCIE_CFG_DATA);
val &= ~PCIE_FTS_NUM_MASK;
val |= PCIE_FTS_NUM_L0(0x50);
writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, slot), pcie->base + PCIE_CFG_ADDR);
writel(val, pcie->base + PCIE_CFG_DATA);
return 0;
+}
+static void mtk_pcie_enable_port(struct mtk_pcie_port *port) +{
int err;
err = clk_enable(&port->sys_ck);
if (err)
goto exit;
err = reset_assert(&port->reset);
if (err)
goto exit;
err = reset_deassert(&port->reset);
if (err)
goto exit;
err = generic_phy_init(&port->phy);
if (err)
goto exit;
err = generic_phy_power_on(&port->phy);
if (err)
goto exit;
if (!mtk_pcie_startup_port(port))
return;
pr_err("Port%d link down\n", port->slot);
+exit:
mtk_pcie_port_free(port);
+}
+static int mtk_pcie_parse_port(struct udevice *dev, u32 slot) +{
struct mtk_pcie *pcie = dev_get_priv(dev);
struct mtk_pcie_port *port;
char name[10];
int err;
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
snprintf(name, sizeof(name), "port%d", slot);
port->base = dev_remap_addr_name(dev, name);
if (!port->base)
return -ENOENT;
snprintf(name, sizeof(name), "sys_ck%d", slot);
err = clk_get_by_name(dev, name, &port->sys_ck);
if (err)
return err;
err = reset_get_by_index(dev, slot, &port->reset);
if (err)
return err;
err = generic_phy_get_by_index(dev, slot, &port->phy);
if (err)
return err;
port->slot = slot;
port->pcie = pcie;
INIT_LIST_HEAD(&port->list);
list_add_tail(&port->list, &pcie->ports);
return 0;
+}
+static int mtk_pcie_probe(struct udevice *dev) +{
struct mtk_pcie *pcie = dev_get_priv(dev);
struct mtk_pcie_port *port, *tmp;
ofnode subnode;
int err;
INIT_LIST_HEAD(&pcie->ports);
pcie->base = dev_remap_addr_name(dev, "subsys");
if (!pcie->base)
return -ENOENT;
err = clk_get_by_name(dev, "free_ck", &pcie->free_ck);
if (err)
return err;
/* enable top level clock */
err = clk_enable(&pcie->free_ck);
if (err)
return err;
dev_for_each_subnode(subnode, dev) {
struct fdt_pci_addr addr;
u32 slot = 0;
if (!ofnode_is_available(subnode))
continue;
err = ofnode_read_pci_addr(subnode, 0, "reg", &addr);
if (err)
return err;
slot = PCI_DEV(addr.phys_hi);
err = mtk_pcie_parse_port(dev, slot);
if (err)
return err;
}
/* enable each port, and then check link status */
list_for_each_entry_safe(port, tmp, &pcie->ports, list)
mtk_pcie_enable_port(port);
return 0;
+}
+static const struct udevice_id mtk_pcie_ids[] = {
{ .compatible = "mediatek,mt7623-pcie", },
{ }
+};
+U_BOOT_DRIVER(pcie_mediatek) = {
.name = "pcie_mediatek",
.id = UCLASS_PCI,
.of_match = mtk_pcie_ids,
.ops = &mtk_pcie_ops,
.probe = mtk_pcie_probe,
.priv_auto_alloc_size = sizeof(struct mtk_pcie),
+};
2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

Hi Ramon
Thank you for first review,answers below...
Am 5. August 2019 08:33:11 MESZ schrieb Ramon Fried rfried.dev@gmail.com:
--- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -145,4 +145,12 @@ config PCI_MVEBU Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs.
+config PCIE_MEDIATEK
bool "MediaTek PCIe controller"
depends on DM_PCI
depends on ARCH_MEDIATEK
help
Say Y here if you want to enable PCIe controller support on
MediaTek SoCs.
This is too generic, is there a version number ? who is the IP vendor behind that Mediatek PCIe ? on which mediatek SoCs ?
It is designed to be a generic driver,but currently only mt7623 is supported/tested.others can be added in future
/* disable interrupt */
val = readl(pcie->base + PCIE_INT_ENABLE);
val &= ~PCIE_PORT_INT_EN(port->slot);
writel(val, pcie->base + PCIE_INT_ENABLE);
You might want to consider using setbits_le32/clrbits_le32.
We will check this
Regards Frank

On Mon, 2019-08-05 at 09:33 +0300, Ramon Fried wrote:
On Sun, Aug 4, 2019 at 8:25 PM Frank Wunderlich frank-w@public-files.de wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe controller support for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pcie_mediatek.c | 292 ++++++++++++++++++++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 drivers/pci/pcie_mediatek.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 3fe38f7315..6f19471ae7 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -145,4 +145,12 @@ config PCI_MVEBU Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs.
+config PCIE_MEDIATEK
bool "MediaTek PCIe controller"
depends on DM_PCI
depends on ARCH_MEDIATEK
help
Say Y here if you want to enable PCIe controller support on
MediaTek SoCs.
This is too generic, is there a version number ? who is the IP vendor behind that Mediatek PCIe ? on which mediatek SoCs ?
No meaningful version number, and here is a copy-paste from Linux version and we use single driver for different generation IPs (via soc data):
static const struct of_device_id mtk_pcie_ids[] = { { .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 }, { .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 },
{ .compatible = "mediatek,mt7622-pcie", .data = &mtk_pcie_soc_mt7622 }, {}, };
We can modify the description if you think this is better- something like this:
Say Y here if you want to enable gen2 v1 PCIe controller, which could be found on MT7623 SoC family.
endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index b5ebd50c85..7093d63918 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ pcie_layerscape_gen4_fixup.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o +obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c new file mode 100644 index 0000000000..3f24060d26 --- /dev/null +++ b/drivers/pci/pcie_mediatek.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- MediaTek PCIe host controller driver.
- Copyright (c) 2017-2019 MediaTek Inc.
- Author: Ryder Lee ryder.lee@mediatek.com
Honghui Zhang <honghui.zhang@mediatek.com>
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <pci.h> +#include <reset.h> +#include <asm/io.h> +#include <linux/iopoll.h> +#include <linux/list.h>
+/* PCIe shared registers */ +#define PCIE_SYS_CFG 0x00 +#define PCIE_INT_ENABLE 0x0c +#define PCIE_CFG_ADDR 0x20 +#define PCIE_CFG_DATA 0x24
+/* PCIe per port registers */ +#define PCIE_BAR0_SETUP 0x10 +#define PCIE_CLASS 0x34 +#define PCIE_LINK_STATUS 0x50
+#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +#define PCIE_PORT_PERST(x) BIT(1 + (x)) +#define PCIE_PORT_LINKUP BIT(0) +#define PCIE_BAR_MAP_MAX GENMASK(31, 16)
+#define PCIE_BAR_ENABLE BIT(0) +#define PCIE_REVISION_ID BIT(0) +#define PCIE_CLASS_CODE (0x60400 << 8) +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \
((((regn) >> 8) & GENMASK(3, 0)) << 24))
+#define PCIE_CONF_ADDR(regn, bdf) \
(PCIE_CONF_REG(regn) | (bdf))
+/* MediaTek specific configuration registers */ +#define PCIE_FTS_NUM 0x70c +#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8)
+#define PCIE_FC_CREDIT 0x73c +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16)
+struct mtk_pcie_port {
void __iomem *base;
struct list_head list;
struct mtk_pcie *pcie;
struct reset_ctl reset;
struct clk sys_ck;
struct phy phy;
u32 slot;
+};
+struct mtk_pcie {
void __iomem *base;
struct clk free_ck;
struct list_head ports;
+};
+static int mtk_pcie_config_address(struct udevice *udev, pci_dev_t bdf,
uint offset, void **paddress)
+{
struct mtk_pcie *pcie = dev_get_priv(udev);
writel(PCIE_CONF_ADDR(offset, bdf), pcie->base + PCIE_CFG_ADDR);
*paddress = pcie->base + PCIE_CFG_DATA + (offset & 3);
return 0;
+}
+static int mtk_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
return pci_generic_mmap_read_config(bus, mtk_pcie_config_address,
bdf, offset, valuep, size);
+}
+static int mtk_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
+{
return pci_generic_mmap_write_config(bus, mtk_pcie_config_address,
bdf, offset, value, size);
+}
+static const struct dm_pci_ops mtk_pcie_ops = {
.read_config = mtk_pcie_read_config,
.write_config = mtk_pcie_write_config,
+};
+static void mtk_pcie_port_free(struct mtk_pcie_port *port) +{
list_del(&port->list);
free(port);
+}
+static int mtk_pcie_startup_port(struct mtk_pcie_port *port) +{
struct mtk_pcie *pcie = port->pcie;
u32 slot = PCI_DEV(port->slot << 11);
u32 val;
int err;
/* assert port PERST_N */
val = readl(pcie->base + PCIE_SYS_CFG);
val |= PCIE_PORT_PERST(port->slot);
writel(val, pcie->base + PCIE_SYS_CFG);
/* de-assert port PERST_N */
val = readl(pcie->base + PCIE_SYS_CFG);
val &= ~PCIE_PORT_PERST(port->slot);
writel(val, pcie->base + PCIE_SYS_CFG);
/* 100ms timeout value should be enough for Gen1/2 training */
err = readl_poll_timeout(port->base + PCIE_LINK_STATUS, val,
!!(val & PCIE_PORT_LINKUP), 100000);
if (err)
return -ETIMEDOUT;
/* disable interrupt */
val = readl(pcie->base + PCIE_INT_ENABLE);
val &= ~PCIE_PORT_INT_EN(port->slot);
writel(val, pcie->base + PCIE_INT_ENABLE);
You might want to consider using setbits_le32/clrbits_le32.
@Frank, could you please switch all the w/r into set/clrbits_le32 ?
Ryder

From: Ryder Lee ryder.lee@mediatek.com
The driver provides PHY for USB2, USB3.0, PCIe and SATA, and now we just enable PCIe. As for the other functionalities will be added gradually in upcoming days.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com --- drivers/phy/Kconfig | 11 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-mtk-tphy.c | 388 +++++++++++++++++++++++++++++++++++++ 3 files changed, 400 insertions(+) create mode 100644 drivers/phy/phy-mtk-tphy.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 957efb3984..2099dd9547 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -190,4 +190,15 @@ config MT76X8_USB_PHY
This PHY is found on MT76x8 devices supporting USB.
+config PHY_MTK_TPHY + bool "MediaTek T-PHY Driver" + depends on PHY + depends on ARCH_MEDIATEK + help + MediaTek T-PHY driver supports usb2.0, usb3.0 ports, PCIe and + SATA, and meanwhile supports two version T-PHY which have + different banks layout, the T-PHY with shared banks between + multi-ports is first version, otherwise is second veriosn, + so you can easily distinguish them by banks layout. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90646ca55b..15b4d58a2d 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o +obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o diff --git a/drivers/phy/phy-mtk-tphy.c b/drivers/phy/phy-mtk-tphy.c new file mode 100644 index 0000000000..422e727c22 --- /dev/null +++ b/drivers/phy/phy-mtk-tphy.c @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2015 - 2019 MediaTek Inc. + * Author: Chunfeng Yun chunfeng.yun@mediatek.com + * Ryder Lee ryder.lee@mediatek.com + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <mapmem.h> +#include <asm/io.h> + +#include <dt-bindings/phy/phy.h> + +/* version V1 sub-banks offset base address */ +/* banks shared by multiple phys */ +#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */ +#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */ +/* u3/pcie/sata phy banks */ +#define SSUSB_SIFSLV_V1_U3PHYD 0x000 +#define SSUSB_SIFSLV_V1_U3PHYA 0x200 + +#define U3P_U3_CHIP_GPIO_CTLD 0x0c +#define P3C_REG_IP_SW_RST BIT(31) +#define P3C_MCU_BUS_CK_GATE_EN BIT(30) +#define P3C_FORCE_IP_SW_RST BIT(29) + +#define U3P_U3_CHIP_GPIO_CTLE 0x10 +#define P3C_RG_SWRST_U3_PHYD BIT(25) +#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24) + +#define U3P_U3_PHYA_REG0 0x000 +#define P3A_RG_CLKDRV_OFF GENMASK(3, 2) +#define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2) + +#define U3P_U3_PHYA_REG1 0x004 +#define P3A_RG_CLKDRV_AMP GENMASK(31, 29) +#define P3A_RG_CLKDRV_AMP_VAL(x) ((0x7 & (x)) << 29) + +#define U3P_U3_PHYA_DA_REG0 0x100 +#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16) +#define P3A_RG_XTAL_EXT_PE2H_VAL(x) ((0x3 & (x)) << 16) +#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12) +#define P3A_RG_XTAL_EXT_PE1H_VAL(x) ((0x3 & (x)) << 12) +#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10) +#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10) + +#define U3P_U3_PHYA_DA_REG4 0x108 +#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19) +#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6) +#define P3A_RG_PLL_BC_PE2H_VAL(x) ((0x3 & (x)) << 6) + +#define U3P_U3_PHYA_DA_REG5 0x10c +#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28) +#define P3A_RG_PLL_BR_PE2H_VAL(x) ((0x3 & (x)) << 28) +#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12) +#define P3A_RG_PLL_IC_PE2H_VAL(x) ((0xf & (x)) << 12) + +#define U3P_U3_PHYA_DA_REG6 0x110 +#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16) +#define P3A_RG_PLL_IR_PE2H_VAL(x) ((0xf & (x)) << 16) + +#define U3P_U3_PHYA_DA_REG7 0x114 +#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16) +#define P3A_RG_PLL_BP_PE2H_VAL(x) ((0xf & (x)) << 16) + +#define U3P_U3_PHYA_DA_REG20 0x13c +#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16) +#define P3A_RG_PLL_DELTA1_PE2H_VAL(x) ((0xffff & (x)) << 16) + +#define U3P_U3_PHYA_DA_REG25 0x148 +#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0) +#define P3A_RG_PLL_DELTA_PE2H_VAL(x) (0xffff & (x)) + +#define U3P_U3_PHYD_RXDET1 0x128 +#define P3D_RG_RXDET_STB2_SET GENMASK(17, 9) +#define P3D_RG_RXDET_STB2_SET_VAL(x) ((0x1ff & (x)) << 9) + +#define U3P_U3_PHYD_RXDET2 0x12c +#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0) +#define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x)) + +struct u3phy_banks { + void __iomem *spllc; + void __iomem *chip; + void __iomem *phyd; /* include u3phyd_bank2 */ + void __iomem *phya; /* include u3phya_da */ +}; + +struct mtk_phy_instance { + void __iomem *port_base; + const struct device_node *np; + + struct u3phy_banks u3_banks; + + /* reference clock of anolog phy */ + struct clk ref_clk; + u32 index; + u8 type; +}; + +struct mtk_tphy { + void __iomem *sif_base; + struct mtk_phy_instance **phys; + int nphys; +}; + +static void pcie_phy_instance_init(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct u3phy_banks *u3_banks = &instance->u3_banks; + u32 tmp; + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); + tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H); + tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0); + + /* ref clk drive */ + tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG1); + tmp &= ~P3A_RG_CLKDRV_AMP; + tmp |= P3A_RG_CLKDRV_AMP_VAL(0x4); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG1); + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0); + tmp &= ~P3A_RG_CLKDRV_OFF; + tmp |= P3A_RG_CLKDRV_OFF_VAL(0x1); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0); + + /* SSC delta -5000ppm */ + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG20); + tmp &= ~P3A_RG_PLL_DELTA1_PE2H; + tmp |= P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG20); + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG25); + tmp &= ~P3A_RG_PLL_DELTA_PE2H; + tmp |= P3A_RG_PLL_DELTA_PE2H_VAL(0x36); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG25); + + /* change pll BW 0.6M */ + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG5); + tmp &= ~(P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H); + tmp |= P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG5); + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG4); + tmp &= ~(P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H); + tmp |= P3A_RG_PLL_BC_PE2H_VAL(0x3); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG4); + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG6); + tmp &= ~P3A_RG_PLL_IR_PE2H; + tmp |= P3A_RG_PLL_IR_PE2H_VAL(0x2); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG6); + + tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG7); + tmp &= ~P3A_RG_PLL_BP_PE2H; + tmp |= P3A_RG_PLL_BP_PE2H_VAL(0xa); + writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG7); + + /* Tx Detect Rx Timing: 10us -> 5us */ + tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1); + tmp &= ~P3D_RG_RXDET_STB2_SET; + tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10); + writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1); + + tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2); + tmp &= ~P3D_RG_RXDET_STB2_SET_P3; + tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10); + writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2); + + /* wait for PCIe subsys register to active */ + udelay(3000); +} + +static void pcie_phy_instance_power_on(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct u3phy_banks *bank = &instance->u3_banks; + u32 tmp; + + tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD); + tmp &= ~(P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST); + writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD); + + tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE); + tmp &= ~(P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD); + writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE); +} + +static void pcie_phy_instance_power_off(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) + +{ + struct u3phy_banks *bank = &instance->u3_banks; + u32 tmp; + + tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD); + tmp |= P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST; + writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD); + + tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE); + tmp |= P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD; + writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE); +} + +static void phy_v1_banks_init(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct u3phy_banks *u3_banks = &instance->u3_banks; + + switch (instance->type) { + case PHY_TYPE_PCIE: + u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC; + u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP; + u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; + u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; + break; + default: + return; + } +} + +static int mtk_phy_init(struct phy *phy) +{ + struct mtk_tphy *tphy = dev_get_priv(phy->dev); + struct mtk_phy_instance *instance = tphy->phys[phy->id]; + int ret; + + /* we may use a fixed-clock here */ + ret = clk_enable(&instance->ref_clk); + if (ret && ret != -ENOSYS) + return ret; + + switch (instance->type) { + case PHY_TYPE_PCIE: + pcie_phy_instance_init(tphy, instance); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mtk_phy_power_on(struct phy *phy) +{ + struct mtk_tphy *tphy = dev_get_priv(phy->dev); + struct mtk_phy_instance *instance = tphy->phys[phy->id]; + + pcie_phy_instance_power_on(tphy, instance); + + return 0; +} + +static int mtk_phy_power_off(struct phy *phy) +{ + struct mtk_tphy *tphy = dev_get_priv(phy->dev); + struct mtk_phy_instance *instance = tphy->phys[phy->id]; + + pcie_phy_instance_power_off(tphy, instance); + + return 0; +} + +static int mtk_phy_exit(struct phy *phy) +{ + struct mtk_tphy *tphy = dev_get_priv(phy->dev); + struct mtk_phy_instance *instance = tphy->phys[phy->id]; + + clk_disable(&instance->ref_clk); + + return 0; +} + +static int mtk_phy_xlate(struct phy *phy, + struct ofnode_phandle_args *args) +{ + struct mtk_tphy *tphy = dev_get_priv(phy->dev); + struct mtk_phy_instance *instance = NULL; + const struct device_node *phy_np = ofnode_to_np(args->node); + u32 index; + + if (!phy_np) { + dev_err(phy->dev, "null pointer phy node\n"); + return -EINVAL; + } + + if (args->args_count < 1) { + dev_err(phy->dev, "invalid number of cells in 'phy' property\n"); + return -EINVAL; + } + + for (index = 0; index < tphy->nphys; index++) + if (phy_np == tphy->phys[index]->np) { + instance = tphy->phys[index]; + break; + } + + if (!instance) { + dev_err(phy->dev, "failed to find appropriate phy\n"); + return -EINVAL; + } + + phy->id = index; + instance->type = args->args[1]; + if (!(instance->type == PHY_TYPE_USB2 || + instance->type == PHY_TYPE_USB3 || + instance->type == PHY_TYPE_PCIE || + instance->type == PHY_TYPE_SATA)) { + dev_err(phy->dev, "unsupported device type\n"); + return -EINVAL; + } + + phy_v1_banks_init(tphy, instance); + + return 0; +} + +static const struct phy_ops mtk_tphy_ops = { + .init = mtk_phy_init, + .exit = mtk_phy_exit, + .power_on = mtk_phy_power_on, + .power_off = mtk_phy_power_off, + .of_xlate = mtk_phy_xlate, +}; + +static int mtk_tphy_probe(struct udevice *dev) +{ + struct mtk_tphy *tphy = dev_get_priv(dev); + ofnode subnode; + int index = 0; + + dev_for_each_subnode(subnode, dev) + tphy->nphys++; + + tphy->phys = devm_kcalloc(dev, tphy->nphys, sizeof(*tphy->phys), + GFP_KERNEL); + if (!tphy->phys) + return -ENOMEM; + + tphy->sif_base = dev_read_addr_ptr(dev); + if (!tphy->sif_base) + return -ENOENT; + + dev_for_each_subnode(subnode, dev) { + struct mtk_phy_instance *instance; + fdt_addr_t addr; + int err; + + instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); + if (!instance) + return -ENOMEM; + + addr = ofnode_get_addr(subnode); + if (addr == FDT_ADDR_T_NONE) + return -ENOMEM; + + instance->port_base = map_sysmem(addr, 0); + instance->index = index; + instance->np = ofnode_to_np(subnode); + tphy->phys[index] = instance; + index++; + + err = clk_get_by_index_nodev(subnode, 0, &instance->ref_clk); + if (err) + return err; + } + + return 0; +} + +static const struct udevice_id mtk_tphy_id_table[] = { + { .compatible = "mediatek,generic-tphy-v1", }, + { } +}; + +U_BOOT_DRIVER(mtk_tphy) = { + .name = "mtk-tphy", + .id = UCLASS_PHY, + .of_match = mtk_tphy_id_table, + .ops = &mtk_tphy_ops, + .probe = mtk_tphy_probe, + .priv_auto_alloc_size = sizeof(struct mtk_tphy), +}; -- 2.17.1

On Sun, Aug 4, 2019 at 8:27 PM Frank Wunderlich frank-w@public-files.de wrote:
From: Ryder Lee ryder.lee@mediatek.com
The driver provides PHY for USB2, USB3.0, PCIe and SATA, and now we just enable PCIe. As for the other functionalities will be added gradually in upcoming days.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
drivers/phy/Kconfig | 11 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-mtk-tphy.c | 388 +++++++++++++++++++++++++++++++++++++ 3 files changed, 400 insertions(+) create mode 100644 drivers/phy/phy-mtk-tphy.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 957efb3984..2099dd9547 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -190,4 +190,15 @@ config MT76X8_USB_PHY
This PHY is found on MT76x8 devices supporting USB.
+config PHY_MTK_TPHY
bool "MediaTek T-PHY Driver"
depends on PHY
depends on ARCH_MEDIATEK
help
MediaTek T-PHY driver supports usb2.0, usb3.0 ports, PCIe and
SATA, and meanwhile supports two version T-PHY which have
different banks layout, the T-PHY with shared banks between
multi-ports is first version, otherwise is second veriosn,
so you can easily distinguish them by banks layout.
endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90646ca55b..15b4d58a2d 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o +obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o diff --git a/drivers/phy/phy-mtk-tphy.c b/drivers/phy/phy-mtk-tphy.c new file mode 100644 index 0000000000..422e727c22 --- /dev/null +++ b/drivers/phy/phy-mtk-tphy.c @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (c) 2015 - 2019 MediaTek Inc.
- Author: Chunfeng Yun chunfeng.yun@mediatek.com
Ryder Lee <ryder.lee@mediatek.com>
- */
+#include <common.h> +#include <clk.h> +#include <dm.h> +#include <generic-phy.h> +#include <mapmem.h> +#include <asm/io.h>
+#include <dt-bindings/phy/phy.h>
+/* version V1 sub-banks offset base address */ +/* banks shared by multiple phys */ +#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */ +#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */ +/* u3/pcie/sata phy banks */ +#define SSUSB_SIFSLV_V1_U3PHYD 0x000 +#define SSUSB_SIFSLV_V1_U3PHYA 0x200
+#define U3P_U3_CHIP_GPIO_CTLD 0x0c +#define P3C_REG_IP_SW_RST BIT(31) +#define P3C_MCU_BUS_CK_GATE_EN BIT(30) +#define P3C_FORCE_IP_SW_RST BIT(29)
+#define U3P_U3_CHIP_GPIO_CTLE 0x10 +#define P3C_RG_SWRST_U3_PHYD BIT(25) +#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
+#define U3P_U3_PHYA_REG0 0x000 +#define P3A_RG_CLKDRV_OFF GENMASK(3, 2) +#define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
+#define U3P_U3_PHYA_REG1 0x004 +#define P3A_RG_CLKDRV_AMP GENMASK(31, 29) +#define P3A_RG_CLKDRV_AMP_VAL(x) ((0x7 & (x)) << 29)
+#define U3P_U3_PHYA_DA_REG0 0x100 +#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16) +#define P3A_RG_XTAL_EXT_PE2H_VAL(x) ((0x3 & (x)) << 16) +#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12) +#define P3A_RG_XTAL_EXT_PE1H_VAL(x) ((0x3 & (x)) << 12) +#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10) +#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
+#define U3P_U3_PHYA_DA_REG4 0x108 +#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19) +#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6) +#define P3A_RG_PLL_BC_PE2H_VAL(x) ((0x3 & (x)) << 6)
+#define U3P_U3_PHYA_DA_REG5 0x10c +#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28) +#define P3A_RG_PLL_BR_PE2H_VAL(x) ((0x3 & (x)) << 28) +#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12) +#define P3A_RG_PLL_IC_PE2H_VAL(x) ((0xf & (x)) << 12)
+#define U3P_U3_PHYA_DA_REG6 0x110 +#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16) +#define P3A_RG_PLL_IR_PE2H_VAL(x) ((0xf & (x)) << 16)
+#define U3P_U3_PHYA_DA_REG7 0x114 +#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16) +#define P3A_RG_PLL_BP_PE2H_VAL(x) ((0xf & (x)) << 16)
+#define U3P_U3_PHYA_DA_REG20 0x13c +#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16) +#define P3A_RG_PLL_DELTA1_PE2H_VAL(x) ((0xffff & (x)) << 16)
+#define U3P_U3_PHYA_DA_REG25 0x148 +#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0) +#define P3A_RG_PLL_DELTA_PE2H_VAL(x) (0xffff & (x))
+#define U3P_U3_PHYD_RXDET1 0x128 +#define P3D_RG_RXDET_STB2_SET GENMASK(17, 9) +#define P3D_RG_RXDET_STB2_SET_VAL(x) ((0x1ff & (x)) << 9)
+#define U3P_U3_PHYD_RXDET2 0x12c +#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0) +#define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x))
+struct u3phy_banks {
void __iomem *spllc;
void __iomem *chip;
void __iomem *phyd; /* include u3phyd_bank2 */
void __iomem *phya; /* include u3phya_da */
+};
+struct mtk_phy_instance {
void __iomem *port_base;
const struct device_node *np;
struct u3phy_banks u3_banks;
/* reference clock of anolog phy */
struct clk ref_clk;
u32 index;
u8 type;
+};
+struct mtk_tphy {
void __iomem *sif_base;
struct mtk_phy_instance **phys;
int nphys;
+};
+static void pcie_phy_instance_init(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance)
+{
struct u3phy_banks *u3_banks = &instance->u3_banks;
u32 tmp;
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H);
tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0);
clrsetbits_le32 is easier on the eyes.
/* ref clk drive */
tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG1);
tmp &= ~P3A_RG_CLKDRV_AMP;
tmp |= P3A_RG_CLKDRV_AMP_VAL(0x4);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG1);
tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
tmp &= ~P3A_RG_CLKDRV_OFF;
tmp |= P3A_RG_CLKDRV_OFF_VAL(0x1);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
/* SSC delta -5000ppm */
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG20);
tmp &= ~P3A_RG_PLL_DELTA1_PE2H;
tmp |= P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG20);
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG25);
tmp &= ~P3A_RG_PLL_DELTA_PE2H;
tmp |= P3A_RG_PLL_DELTA_PE2H_VAL(0x36);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG25);
/* change pll BW 0.6M */
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG5);
tmp &= ~(P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H);
tmp |= P3A_RG_PLL_BR_PE2H_VAL(0x1) | P3A_RG_PLL_IC_PE2H_VAL(0x1);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG5);
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG4);
tmp &= ~(P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H);
tmp |= P3A_RG_PLL_BC_PE2H_VAL(0x3);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG4);
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG6);
tmp &= ~P3A_RG_PLL_IR_PE2H;
tmp |= P3A_RG_PLL_IR_PE2H_VAL(0x2);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG6);
tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG7);
tmp &= ~P3A_RG_PLL_BP_PE2H;
tmp |= P3A_RG_PLL_BP_PE2H_VAL(0xa);
writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG7);
/* Tx Detect Rx Timing: 10us -> 5us */
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1);
tmp &= ~P3D_RG_RXDET_STB2_SET;
tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10);
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1);
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2);
tmp &= ~P3D_RG_RXDET_STB2_SET_P3;
tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
/* wait for PCIe subsys register to active */
udelay(3000);
+}
+static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance)
+{
struct u3phy_banks *bank = &instance->u3_banks;
u32 tmp;
tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
tmp &= ~(P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
tmp &= ~(P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+}
+static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance)
+{
struct u3phy_banks *bank = &instance->u3_banks;
u32 tmp;
tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLD);
tmp |= P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST;
writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLD);
tmp = readl(bank->chip + U3P_U3_CHIP_GPIO_CTLE);
tmp |= P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD;
writel(tmp, bank->chip + U3P_U3_CHIP_GPIO_CTLE);
+}
+static void phy_v1_banks_init(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance)
+{
struct u3phy_banks *u3_banks = &instance->u3_banks;
switch (instance->type) {
case PHY_TYPE_PCIE:
u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
break;
default:
return;
}
+}
+static int mtk_phy_init(struct phy *phy) +{
struct mtk_tphy *tphy = dev_get_priv(phy->dev);
struct mtk_phy_instance *instance = tphy->phys[phy->id];
int ret;
/* we may use a fixed-clock here */
ret = clk_enable(&instance->ref_clk);
if (ret && ret != -ENOSYS)
return ret;
switch (instance->type) {
case PHY_TYPE_PCIE:
pcie_phy_instance_init(tphy, instance);
break;
default:
return -EINVAL;
}
return 0;
+}
+static int mtk_phy_power_on(struct phy *phy) +{
struct mtk_tphy *tphy = dev_get_priv(phy->dev);
struct mtk_phy_instance *instance = tphy->phys[phy->id];
pcie_phy_instance_power_on(tphy, instance);
return 0;
+}
+static int mtk_phy_power_off(struct phy *phy) +{
struct mtk_tphy *tphy = dev_get_priv(phy->dev);
struct mtk_phy_instance *instance = tphy->phys[phy->id];
pcie_phy_instance_power_off(tphy, instance);
return 0;
+}
+static int mtk_phy_exit(struct phy *phy) +{
struct mtk_tphy *tphy = dev_get_priv(phy->dev);
struct mtk_phy_instance *instance = tphy->phys[phy->id];
clk_disable(&instance->ref_clk);
return 0;
+}
+static int mtk_phy_xlate(struct phy *phy,
struct ofnode_phandle_args *args)
+{
struct mtk_tphy *tphy = dev_get_priv(phy->dev);
struct mtk_phy_instance *instance = NULL;
const struct device_node *phy_np = ofnode_to_np(args->node);
u32 index;
if (!phy_np) {
dev_err(phy->dev, "null pointer phy node\n");
return -EINVAL;
}
if (args->args_count < 1) {
dev_err(phy->dev, "invalid number of cells in 'phy' property\n");
return -EINVAL;
}
for (index = 0; index < tphy->nphys; index++)
if (phy_np == tphy->phys[index]->np) {
instance = tphy->phys[index];
break;
}
if (!instance) {
dev_err(phy->dev, "failed to find appropriate phy\n");
return -EINVAL;
}
phy->id = index;
instance->type = args->args[1];
if (!(instance->type == PHY_TYPE_USB2 ||
instance->type == PHY_TYPE_USB3 ||
instance->type == PHY_TYPE_PCIE ||
instance->type == PHY_TYPE_SATA)) {
dev_err(phy->dev, "unsupported device type\n");
return -EINVAL;
}
phy_v1_banks_init(tphy, instance);
return 0;
+}
+static const struct phy_ops mtk_tphy_ops = {
.init = mtk_phy_init,
.exit = mtk_phy_exit,
.power_on = mtk_phy_power_on,
.power_off = mtk_phy_power_off,
.of_xlate = mtk_phy_xlate,
+};
+static int mtk_tphy_probe(struct udevice *dev) +{
struct mtk_tphy *tphy = dev_get_priv(dev);
ofnode subnode;
int index = 0;
dev_for_each_subnode(subnode, dev)
tphy->nphys++;
tphy->phys = devm_kcalloc(dev, tphy->nphys, sizeof(*tphy->phys),
GFP_KERNEL);
if (!tphy->phys)
return -ENOMEM;
tphy->sif_base = dev_read_addr_ptr(dev);
if (!tphy->sif_base)
return -ENOENT;
dev_for_each_subnode(subnode, dev) {
struct mtk_phy_instance *instance;
fdt_addr_t addr;
int err;
instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
if (!instance)
return -ENOMEM;
addr = ofnode_get_addr(subnode);
if (addr == FDT_ADDR_T_NONE)
return -ENOMEM;
instance->port_base = map_sysmem(addr, 0);
instance->index = index;
instance->np = ofnode_to_np(subnode);
tphy->phys[index] = instance;
index++;
err = clk_get_by_index_nodev(subnode, 0, &instance->ref_clk);
if (err)
return err;
}
return 0;
+}
+static const struct udevice_id mtk_tphy_id_table[] = {
{ .compatible = "mediatek,generic-tphy-v1", },
{ }
+};
+U_BOOT_DRIVER(mtk_tphy) = {
.name = "mtk-tphy",
.id = UCLASS_PHY,
.of_match = mtk_tphy_id_table,
.ops = &mtk_tphy_ops,
.probe = mtk_tphy_probe,
.priv_auto_alloc_size = sizeof(struct mtk_tphy),
+};
2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe and its PHY nodes for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com --- arch/arm/dts/mt7623.dtsi | 128 +++++++++++++++++++++++ arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 +++++ 2 files changed, 157 insertions(+)
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 64079c61bf..3a868ea2ee 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> #include <dt-bindings/reset/mtk-reset.h> #include "skeleton.dtsi" @@ -255,6 +256,133 @@ #reset-cells = <1>; };
+ pcie: pcie@1a140000 { + compatible = "mediatek,mt7623-pcie"; + device_type = "pci"; + reg = <0x1a140000 0x1000>, /* PCIe shared registers */ + <0x1a142000 0x1000>, /* Port0 registers */ + <0x1a143000 0x1000>, /* Port1 registers */ + <0x1a144000 0x1000>; /* Port2 registers */ + reg-names = "subsys", "port0", "port1", "port2"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, + <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, + <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <&hifsys CLK_HIFSYS_PCIE0>, + <&hifsys CLK_HIFSYS_PCIE1>, + <&hifsys CLK_HIFSYS_PCIE2>; + clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; + resets = <&hifsys HIFSYS_PCIE0_RST>, + <&hifsys HIFSYS_PCIE1_RST>, + <&hifsys HIFSYS_PCIE2_RST>; + reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; + phys = <&pcie0_port PHY_TYPE_PCIE>, + <&pcie1_port PHY_TYPE_PCIE>, + <&u3port1 PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + power-domains = <&scpsys MT7623_POWER_DOMAIN_HIF>; + bus-range = <0x00 0xff>; + status = "disabled"; + ranges = <0x81000000 0 0x1a160000 0x1a160000 0 0x00010000 + 0x83000000 0 0x60000000 0x60000000 0 0x10000000>; + + pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; + ranges; + status = "disabled"; + }; + + pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + ranges; + status = "disabled"; + }; + + pcie@2,0 { + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + ranges; + status = "disabled"; + }; + }; + + pcie0_phy: pcie-phy@1a149000 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0x1a149000 0x0700>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + pcie0_port: pcie-phy@1a149900 { + reg = <0x1a149900 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + + pcie1_phy: pcie-phy@1a14a000 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0x1a14a000 0x0700>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + pcie1_port: pcie-phy@1a14a900 { + reg = <0x1a14a900 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + + u3phy2: usb-phy@1a244000 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0x1a244000 0x0700>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + u2port1: usb-phy@1a244800 { + reg = <0x1a244800 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port1: usb-phy@1a244900 { + reg = <0x1a244900 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "syscon"; reg = <0x1b000000 0x1000>; diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts index 51628bb639..b0c86219b6 100644 --- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts @@ -172,6 +172,13 @@ }; };
+ pcie_default: pcie-default { + mux { + function = "pcie"; + groups = "pcie0_0_perst", "pcie1_0_perst"; + }; + }; + uart0_pins_a: uart0-default { mux { function = "uart"; @@ -201,6 +208,28 @@ }; };
+&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_default>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; + + pcie@1,0 { + status = "okay"; + }; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.17.1

On Sun, Aug 4, 2019 at 8:26 PM Frank Wunderlich frank-w@public-files.de wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe and its PHY nodes for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
arch/arm/dts/mt7623.dtsi | 128 +++++++++++++++++++++++ arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 +++++ 2 files changed, 157 insertions(+)
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 64079c61bf..3a868ea2ee 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> #include <dt-bindings/reset/mtk-reset.h> #include "skeleton.dtsi" @@ -255,6 +256,133 @@ #reset-cells = <1>; };
pcie: pcie@1a140000 {
compatible = "mediatek,mt7623-pcie";
device_type = "pci";
reg = <0x1a140000 0x1000>, /* PCIe shared registers */
<0x1a142000 0x1000>, /* Port0 registers */
<0x1a143000 0x1000>, /* Port1 registers */
<0x1a144000 0x1000>; /* Port2 registers */
reg-names = "subsys", "port0", "port1", "port2";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xf800 0 0 0>;
interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
<0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
<0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
<&hifsys CLK_HIFSYS_PCIE0>,
<&hifsys CLK_HIFSYS_PCIE1>,
<&hifsys CLK_HIFSYS_PCIE2>;
clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2";
resets = <&hifsys HIFSYS_PCIE0_RST>,
<&hifsys HIFSYS_PCIE1_RST>,
<&hifsys HIFSYS_PCIE2_RST>;
reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2";
phys = <&pcie0_port PHY_TYPE_PCIE>,
<&pcie1_port PHY_TYPE_PCIE>,
<&u3port1 PHY_TYPE_PCIE>;
phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
power-domains = <&scpsys MT7623_POWER_DOMAIN_HIF>;
bus-range = <0x00 0xff>;
status = "disabled";
ranges = <0x81000000 0 0x1a160000 0x1a160000 0 0x00010000
0x83000000 0 0x60000000 0x60000000 0 0x10000000>;
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@1,0 {
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@2,0 {
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
};
pcie0_phy: pcie-phy@1a149000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a149000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie0_port: pcie-phy@1a149900 {
reg = <0x1a149900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
pcie1_phy: pcie-phy@1a14a000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a14a000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie1_port: pcie-phy@1a14a900 {
reg = <0x1a14a900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
u3phy2: usb-phy@1a244000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a244000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
u2port1: usb-phy@1a244800 {
reg = <0x1a244800 0x0100>;
clocks = <&topckgen CLK_TOP_USB_PHY48M>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
u3port1: usb-phy@1a244900 {
reg = <0x1a244900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "syscon"; reg = <0x1b000000 0x1000>;
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts index 51628bb639..b0c86219b6 100644 --- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts @@ -172,6 +172,13 @@ }; };
pcie_default: pcie-default {
mux {
function = "pcie";
groups = "pcie0_0_perst", "pcie1_0_perst";
};
};
uart0_pins_a: uart0-default { mux { function = "uart";
@@ -201,6 +208,28 @@ }; };
+&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_default>;
status = "okay";
pcie@0,0 {
status = "okay";
};
pcie@1,0 {
status = "okay";
};
+};
+&pcie0_phy {
status = "okay";
+};
+&pcie1_phy {
status = "okay";
+};
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
What about dts binding document ?

On Mon, 2019-08-05 at 09:34 +0300, Ramon Fried wrote:
On Sun, Aug 4, 2019 at 8:26 PM Frank Wunderlich frank-w@public-files.de wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe and its PHY nodes for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
arch/arm/dts/mt7623.dtsi | 128 +++++++++++++++++++++++ arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 +++++ 2 files changed, 157 insertions(+)
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 64079c61bf..3a868ea2ee 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> #include <dt-bindings/reset/mtk-reset.h> #include "skeleton.dtsi" @@ -255,6 +256,133 @@ #reset-cells = <1>; };
pcie: pcie@1a140000 {
compatible = "mediatek,mt7623-pcie";
device_type = "pci";
reg = <0x1a140000 0x1000>, /* PCIe shared registers */
<0x1a142000 0x1000>, /* Port0 registers */
<0x1a143000 0x1000>, /* Port1 registers */
<0x1a144000 0x1000>; /* Port2 registers */
reg-names = "subsys", "port0", "port1", "port2";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xf800 0 0 0>;
interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
<0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
<0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
<&hifsys CLK_HIFSYS_PCIE0>,
<&hifsys CLK_HIFSYS_PCIE1>,
<&hifsys CLK_HIFSYS_PCIE2>;
clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2";
resets = <&hifsys HIFSYS_PCIE0_RST>,
<&hifsys HIFSYS_PCIE1_RST>,
<&hifsys HIFSYS_PCIE2_RST>;
reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2";
phys = <&pcie0_port PHY_TYPE_PCIE>,
<&pcie1_port PHY_TYPE_PCIE>,
<&u3port1 PHY_TYPE_PCIE>;
phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
power-domains = <&scpsys MT7623_POWER_DOMAIN_HIF>;
bus-range = <0x00 0xff>;
status = "disabled";
ranges = <0x81000000 0 0x1a160000 0x1a160000 0 0x00010000
0x83000000 0 0x60000000 0x60000000 0 0x10000000>;
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@1,0 {
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@2,0 {
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
};
pcie0_phy: pcie-phy@1a149000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a149000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie0_port: pcie-phy@1a149900 {
reg = <0x1a149900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
pcie1_phy: pcie-phy@1a14a000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a14a000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie1_port: pcie-phy@1a14a900 {
reg = <0x1a14a900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
u3phy2: usb-phy@1a244000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a244000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
u2port1: usb-phy@1a244800 {
reg = <0x1a244800 0x0100>;
clocks = <&topckgen CLK_TOP_USB_PHY48M>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
u3port1: usb-phy@1a244900 {
reg = <0x1a244900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "syscon"; reg = <0x1b000000 0x1000>;
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts index 51628bb639..b0c86219b6 100644 --- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts @@ -172,6 +172,13 @@ }; };
pcie_default: pcie-default {
mux {
function = "pcie";
groups = "pcie0_0_perst", "pcie1_0_perst";
};
};
uart0_pins_a: uart0-default { mux { function = "uart";
@@ -201,6 +208,28 @@ }; };
+&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_default>;
status = "okay";
pcie@0,0 {
status = "okay";
};
pcie@1,0 {
status = "okay";
};
+};
+&pcie0_phy {
status = "okay";
+};
+&pcie1_phy {
status = "okay";
+};
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
What about dts binding document ?
Is it mandatory? It seems just armada8k has its doc there.

On Mon, Aug 5, 2019 at 10:32 AM Ryder Lee ryder.lee@mediatek.com wrote:
On Mon, 2019-08-05 at 09:34 +0300, Ramon Fried wrote:
On Sun, Aug 4, 2019 at 8:26 PM Frank Wunderlich frank-w@public-files.de
wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe and its PHY nodes for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
arch/arm/dts/mt7623.dtsi | 128 +++++++++++++++++++++++ arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 +++++ 2 files changed, 157 insertions(+)
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 64079c61bf..3a868ea2ee 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> #include <dt-bindings/reset/mtk-reset.h> #include "skeleton.dtsi" @@ -255,6 +256,133 @@ #reset-cells = <1>; };
pcie: pcie@1a140000 {
compatible = "mediatek,mt7623-pcie";
device_type = "pci";
reg = <0x1a140000 0x1000>, /* PCIe shared registers */
<0x1a142000 0x1000>, /* Port0 registers */
<0x1a143000 0x1000>, /* Port1 registers */
<0x1a144000 0x1000>; /* Port2 registers */
reg-names = "subsys", "port0", "port1", "port2";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xf800 0 0 0>;
interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193
IRQ_TYPE_LEVEL_LOW>,
<0x0800 0 0 0 &sysirq GIC_SPI 194
IRQ_TYPE_LEVEL_LOW>,
<0x1000 0 0 0 &sysirq GIC_SPI 195
IRQ_TYPE_LEVEL_LOW>;
clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
<&hifsys CLK_HIFSYS_PCIE0>,
<&hifsys CLK_HIFSYS_PCIE1>,
<&hifsys CLK_HIFSYS_PCIE2>;
clock-names = "free_ck", "sys_ck0", "sys_ck1",
"sys_ck2";
resets = <&hifsys HIFSYS_PCIE0_RST>,
<&hifsys HIFSYS_PCIE1_RST>,
<&hifsys HIFSYS_PCIE2_RST>;
reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2";
phys = <&pcie0_port PHY_TYPE_PCIE>,
<&pcie1_port PHY_TYPE_PCIE>,
<&u3port1 PHY_TYPE_PCIE>;
phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
power-domains = <&scpsys MT7623_POWER_DOMAIN_HIF>;
bus-range = <0x00 0xff>;
status = "disabled";
ranges = <0x81000000 0 0x1a160000 0x1a160000 0
0x00010000
0x83000000 0 0x60000000 0x60000000 0
0x10000000>;
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@1,0 {
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@2,0 {
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
};
pcie0_phy: pcie-phy@1a149000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a149000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie0_port: pcie-phy@1a149900 {
reg = <0x1a149900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
pcie1_phy: pcie-phy@1a14a000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a14a000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie1_port: pcie-phy@1a14a900 {
reg = <0x1a14a900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
u3phy2: usb-phy@1a244000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a244000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
u2port1: usb-phy@1a244800 {
reg = <0x1a244800 0x0100>;
clocks = <&topckgen CLK_TOP_USB_PHY48M>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
u3port1: usb-phy@1a244900 {
reg = <0x1a244900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "syscon"; reg = <0x1b000000 0x1000>;
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
index 51628bb639..b0c86219b6 100644 --- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts @@ -172,6 +172,13 @@ }; };
pcie_default: pcie-default {
mux {
function = "pcie";
groups = "pcie0_0_perst", "pcie1_0_perst";
};
};
uart0_pins_a: uart0-default { mux { function = "uart";
@@ -201,6 +208,28 @@ }; };
+&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_default>;
status = "okay";
pcie@0,0 {
status = "okay";
};
pcie@1,0 {
status = "okay";
};
+};
+&pcie0_phy {
status = "okay";
+};
+&pcie1_phy {
status = "okay";
+};
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
What about dts binding document ?
Is it mandatory? It seems just armada8k has its doc there.
It is encouraged.

It's here in Linux BPI-R2-4.14/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt So seems there is no problem to add.
пн, 5 серп. 2019 о 11:10 Ramon Fried ramon.fried@gmail.com пише:
On Mon, Aug 5, 2019 at 10:32 AM Ryder Lee ryder.lee@mediatek.com wrote:
On Mon, 2019-08-05 at 09:34 +0300, Ramon Fried wrote:
On Sun, Aug 4, 2019 at 8:26 PM Frank Wunderlich <
frank-w@public-files.de> wrote:
From: Ryder Lee ryder.lee@mediatek.com
This adds PCIe and its PHY nodes for MT7623.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com
arch/arm/dts/mt7623.dtsi | 128
+++++++++++++++++++++++
arch/arm/dts/mt7623n-bananapi-bpi-r2.dts | 29 +++++ 2 files changed, 157 insertions(+)
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 64079c61bf..3a868ea2ee 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> #include <dt-bindings/reset/mtk-reset.h> #include "skeleton.dtsi" @@ -255,6 +256,133 @@ #reset-cells = <1>; };
pcie: pcie@1a140000 {
compatible = "mediatek,mt7623-pcie";
device_type = "pci";
reg = <0x1a140000 0x1000>, /* PCIe shared registers */
<0x1a142000 0x1000>, /* Port0 registers */
<0x1a143000 0x1000>, /* Port1 registers */
<0x1a144000 0x1000>; /* Port2 registers */
reg-names = "subsys", "port0", "port1", "port2";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xf800 0 0 0>;
interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193
IRQ_TYPE_LEVEL_LOW>,
<0x0800 0 0 0 &sysirq GIC_SPI 194
IRQ_TYPE_LEVEL_LOW>,
<0x1000 0 0 0 &sysirq GIC_SPI 195
IRQ_TYPE_LEVEL_LOW>;
clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
<&hifsys CLK_HIFSYS_PCIE0>,
<&hifsys CLK_HIFSYS_PCIE1>,
<&hifsys CLK_HIFSYS_PCIE2>;
clock-names = "free_ck", "sys_ck0", "sys_ck1",
"sys_ck2";
resets = <&hifsys HIFSYS_PCIE0_RST>,
<&hifsys HIFSYS_PCIE1_RST>,
<&hifsys HIFSYS_PCIE2_RST>;
reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2";
phys = <&pcie0_port PHY_TYPE_PCIE>,
<&pcie1_port PHY_TYPE_PCIE>,
<&u3port1 PHY_TYPE_PCIE>;
phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2";
power-domains = <&scpsys MT7623_POWER_DOMAIN_HIF>;
bus-range = <0x00 0xff>;
status = "disabled";
ranges = <0x81000000 0 0x1a160000 0x1a160000 0
0x00010000
0x83000000 0 0x60000000 0x60000000 0
0x10000000>;
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@1,0 {
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
pcie@2,0 {
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195
IRQ_TYPE_LEVEL_LOW>;
ranges;
status = "disabled";
};
};
pcie0_phy: pcie-phy@1a149000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a149000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie0_port: pcie-phy@1a149900 {
reg = <0x1a149900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
pcie1_phy: pcie-phy@1a14a000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a14a000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
pcie1_port: pcie-phy@1a14a900 {
reg = <0x1a14a900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
u3phy2: usb-phy@1a244000 {
compatible = "mediatek,generic-tphy-v1";
reg = <0x1a244000 0x0700>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
status = "disabled";
u2port1: usb-phy@1a244800 {
reg = <0x1a244800 0x0100>;
clocks = <&topckgen CLK_TOP_USB_PHY48M>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
u3port1: usb-phy@1a244900 {
reg = <0x1a244900 0x0700>;
clocks = <&clk26m>;
clock-names = "ref";
#phy-cells = <1>;
status = "okay";
};
};
ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "syscon"; reg = <0x1b000000 0x1000>;
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
index 51628bb639..b0c86219b6 100644 --- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts @@ -172,6 +172,13 @@ }; };
pcie_default: pcie-default {
mux {
function = "pcie";
groups = "pcie0_0_perst", "pcie1_0_perst";
};
};
uart0_pins_a: uart0-default { mux { function = "uart";
@@ -201,6 +208,28 @@ }; };
+&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_default>;
status = "okay";
pcie@0,0 {
status = "okay";
};
pcie@1,0 {
status = "okay";
};
+};
+&pcie0_phy {
status = "okay";
+};
+&pcie1_phy {
status = "okay";
+};
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.17.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
What about dts binding document ?
Is it mandatory? It seems just armada8k has its doc there.
It is encouraged.

From: Ryder Lee ryder.lee@mediatek.com
This follows the linux header rules to avoid conflict bitfields.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Ryder Lee ryder.lee@mediatek.com --- arch/arm/dts/mt7623.dtsi | 2 +- arch/arm/dts/mt7629.dtsi | 2 +- .../reset/{mtk-reset.h => mt7623-reset.h} | 4 +-- include/dt-bindings/reset/mt7629-reset.h | 36 +++++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) rename include/dt-bindings/reset/{mtk-reset.h => mt7623-reset.h} (88%) create mode 100644 include/dt-bindings/reset/mt7629-reset.h
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi index 3a868ea2ee..1135b1e1ae 100644 --- a/arch/arm/dts/mt7623.dtsi +++ b/arch/arm/dts/mt7623.dtsi @@ -11,7 +11,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt7623-power.h> -#include <dt-bindings/reset/mtk-reset.h> +#include <dt-bindings/reset/mt7623-reset.h> #include "skeleton.dtsi"
/ { diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi index ecbd29d7ae..3c9eab9770 100644 --- a/arch/arm/dts/mt7629.dtsi +++ b/arch/arm/dts/mt7629.dtsi @@ -10,7 +10,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/power/mt7629-power.h> -#include <dt-bindings/reset/mtk-reset.h> +#include <dt-bindings/reset/mt7629-reset.h> #include "skeleton.dtsi"
/ { diff --git a/include/dt-bindings/reset/mtk-reset.h b/include/dt-bindings/reset/mt7623-reset.h similarity index 88% rename from include/dt-bindings/reset/mtk-reset.h rename to include/dt-bindings/reset/mt7623-reset.h index 78fcdab009..a859a5b26a 100644 --- a/include/dt-bindings/reset/mtk-reset.h +++ b/include/dt-bindings/reset/mt7623-reset.h @@ -6,11 +6,9 @@ #ifndef _DT_BINDINGS_MTK_RESET_H_ #define _DT_BINDINGS_MTK_RESET_H_
-/* ETHSYS */ +/* ETHSYS resets */ #define ETHSYS_PPE_RST 31 -#define ETHSYS_EPHY_RST 24 #define ETHSYS_GMAC_RST 23 -#define ETHSYS_ESW_RST 16 #define ETHSYS_FE_RST 6 #define ETHSYS_MCM_RST 2 #define ETHSYS_SYS_RST 0 diff --git a/include/dt-bindings/reset/mt7629-reset.h b/include/dt-bindings/reset/mt7629-reset.h new file mode 100644 index 0000000000..8f1634f7a6 --- /dev/null +++ b/include/dt-bindings/reset/mt7629-reset.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + */ + +#ifndef _DT_BINDINGS_MTK_RESET_H_ +#define _DT_BINDINGS_MTK_RESET_H_ + +/* PCIe Subsystem resets */ +#define PCIE1_CORE_RST 19 +#define PCIE1_MMIO_RST 20 +#define PCIE1_HRST 21 +#define PCIE1_USER_RST 22 +#define PCIE1_PIPE_RST 23 +#define PCIE0_CORE_RST 27 +#define PCIE0_MMIO_RST 28 +#define PCIE0_HRST 29 +#define PCIE0_USER_RST 30 +#define PCIE0_PIPE_RST 31 + +/* SSUSB Subsystem resets */ +#define SSUSB_PHY_PWR_RST 3 +#define SSUSB_MAC_PWR_RST 4 + +/* ETH Subsystem resets */ +#define ETHSYS_SYS_RST 0 +#define ETHSYS_MCM_RST 2 +#define ETHSYS_HSDMA_RST 5 +#define ETHSYS_FE_RST 6 +#define ETHSYS_ESW_RST 16 +#define ETHSYS_GMAC_RST 23 +#define ETHSYS_EPHY_RST 24 +#define ETHSYS_CRYPTO_RST 29 +#define ETHSYS_PPE_RST 31 + +#endif /* _DT_BINDINGS_MTK_RESET_H_ */ -- 2.17.1

From: Oleksandr Rybalko ray@ddteam.net
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Oleksandr Rybalko ray@ddteam.net --- drivers/ata/ahci-pci.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/ata/ahci-pci.c b/drivers/ata/ahci-pci.c index 1ca439d3fa..11ec98b56f 100644 --- a/drivers/ata/ahci-pci.c +++ b/drivers/ata/ahci-pci.c @@ -35,6 +35,7 @@ U_BOOT_DRIVER(ahci_pci) = {
static struct pci_device_id ahci_pci_supported[] = { { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, ~0) }, + { PCI_DEVICE(0x1b21, 0x0611) }, {}, };
-- 2.17.1

From: Oleksandr Rybalko ray@ddteam.net
In 32bits mode upper bits need to be set to 0, otherwise controller will try to DMA into not existing memory and stops with error.
Tested-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Oleksandr Rybalko ray@ddteam.net --- drivers/ata/ahci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e3135bb75f..716f9c1c7e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -593,10 +593,15 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) pp->cmd_tbl_sg = (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
- writel_with_flush((unsigned long)pp->cmd_slot, - port_mmio + PORT_LST_ADDR); + writel_with_flush((u32)pp->cmd_slot, port_mmio + PORT_LST_ADDR); +#ifndef CONFIG_PHYS_64BIT + writel_with_flush(0, port_mmio + PORT_LST_ADDR_HI); +#endif
writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR); +#ifndef CONFIG_PHYS_64BIT + writel_with_flush(0, port_mmio + PORT_FIS_ADDR_HI); +#endif
#ifdef CONFIG_SUNXI_AHCI sunxi_dma_init(port_mmio); -- 2.17.1

a link the v1, because subject differs:
https://patchwork.ozlabs.org/project/uboot/list/?series=122451
regards Frank
participants (5)
-
Aleksandr Rybalko
-
Frank Wunderlich
-
Ramon Fried
-
Ramon Fried
-
Ryder Lee