diff options
-rw-r--r-- | arch/arm/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/dts/mt7622-bpi-r64.dts | 246 | ||||
-rw-r--r-- | arch/arm/dts/mt7622-rfb.dts | 31 | ||||
-rw-r--r-- | arch/arm/dts/mt7622.dtsi | 116 | ||||
-rw-r--r-- | configs/mt7622_rfb_defconfig | 4 | ||||
-rw-r--r-- | drivers/ata/Kconfig | 8 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/mtk_ahci.c | 130 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mt7622.c | 69 | ||||
-rw-r--r-- | drivers/pci/pcie_mediatek.c | 462 | ||||
-rw-r--r-- | drivers/phy/phy-mtk-tphy.c | 105 | ||||
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mt8512.c | 6 | ||||
-rw-r--r-- | include/dt-bindings/reset/mt7629-reset.h | 5 |
13 files changed, 1177 insertions, 7 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7e29b9096b..b2b5360f6d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -962,6 +962,7 @@ dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt7622-rfb.dtb \ mt7623a-unielec-u7623-02-emmc.dtb \ + mt7622-bpi-r64.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ mt8512-bm1-emmc.dtb \ diff --git a/arch/arm/dts/mt7622-bpi-r64.dts b/arch/arm/dts/mt7622-bpi-r64.dts new file mode 100644 index 0000000000..51287cea3a --- /dev/null +++ b/arch/arm/dts/mt7622-bpi-r64.dts @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Sam Shih <sam.shih@mediatek.com> + */ + +/dts-v1/; +#include "mt7622.dtsi" +#include "mt7622-u-boot.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7622-bpi-r64"; + compatible = "mediatek,mt7622", "mediatek,mt7622-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + aliases { + spi0 = &snfi; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x40000000 0x40000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; + + pcie@1,0 { + status = "okay"; + }; +}; + +&pinctrl { + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + snfi_pins: snfi-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + snor_pins: snor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + uart0_pins: uart0 { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + pwm_pins: pwm1 { + mux { + function = "pwm"; + groups = "pwm_ch1_0" ; + }; + }; + + watchdog_pins: watchdog-default { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "emmc"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + + }; + + mmc1_pins_default: mmc1default { + mux { + function = "sd"; + groups = "sd_0"; + }; + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + + }; +}; + +&snfi { + pinctrl-names = "default", "snfi"; + pinctrl-0 = <&snor_pins>; + pinctrl-1 = <&snfi_pins>; + status = "okay"; + + spi-flash@0{ + compatible = "jedec,spi-nor"; + reg = <0>; + u-boot,dm-pre-reloc; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-sd-highspeed; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_default>; + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + r_smpl = <1>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 54 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&gpio { + /*gpio 90 for setting mode to sata*/ + asm_sel { + gpio-hog; + gpios = <90 GPIO_ACTIVE_HIGH>; + output-low; + }; +}; diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts index f05c3fe14d..317fc78abd 100644 --- a/arch/arm/dts/mt7622-rfb.dts +++ b/arch/arm/dts/mt7622-rfb.dts @@ -46,8 +46,39 @@ }; }; +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; + + pcie@1,0 { + status = "okay"; + }; +}; &pinctrl { + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + snfi_pins: snfi-pins { mux { function = "flash"; diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi index f9ce0c6c3e..c43ad65702 100644 --- a/arch/arm/dts/mt7622.dtsi +++ b/arch/arm/dts/mt7622.dtsi @@ -10,6 +10,7 @@ #include <dt-bindings/power/mt7629-power.h> #include <dt-bindings/reset/mt7629-reset.h> #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/phy/phy.h> / { compatible = "mediatek,mt7622"; @@ -142,6 +143,11 @@ reg = <0x10212000 0x800>; }; + wdt-reboot { + compatible = "wdt-reboot"; + wdt = <&watchdog>; + }; + gic: interrupt-controller@10300000 { compatible = "arm,gic-400"; interrupt-controller; @@ -186,6 +192,116 @@ status = "disabled"; }; + pciesys: pciesys@1a100800 { + compatible = "mediatek,mt7622-pciesys", "syscon"; + reg = <0x1a100800 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pcie: pcie@1a140000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0x1a140000 0x1000>, + <0x1a143000 0x1000>, + <0x1a145000 0x1000>; + reg-names = "subsys", "port0", "port1"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, + <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, + <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, + <&pciesys CLK_PCIE_P1_OBFF_EN>, + <&pciesys CLK_PCIE_P0_PIPE_EN>, + <&pciesys CLK_PCIE_P1_PIPE_EN>; + clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", + "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", + "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; + power-domains = <&scpsys MT7629_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>; + status = "disabled"; + + pcie0: pcie@0,0 { + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + status = "disabled"; + + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1,0 { + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + status = "disabled"; + + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + + sata: sata@1a200000 { + compatible = "mediatek,mtk-ahci"; + reg = <0x1a200000 0x1100>; + resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, + <&pciesys MT7622_SATA_PHY_SW_RST>, + <&pciesys MT7622_SATA_PHY_REG_RST>; + reset-names = "axi", "sw", "reg"; + mediatek,phy-mode = <&pciesys>; + ports-implemented = <0x1>; + phys = <&sata_port PHY_TYPE_SATA>; + phy-names = "sata-phy"; + status = "okay"; + }; + + sata_phy: sata-phy@1a243000 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0x1a243000 0x0100>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "okay"; + + sata_port: sata-phy@1a243000 { + reg = <0x1a243000 0x0100>; + clocks = <&topckgen CLK_TOP_ETH_500M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + ethsys: syscon@1b000000 { compatible = "mediatek,mt7622-ethsys", "syscon"; reg = <0x1b000000 0x1000>; diff --git a/configs/mt7622_rfb_defconfig b/configs/mt7622_rfb_defconfig index 9ab621da15..fa2b4f9f52 100644 --- a/configs/mt7622_rfb_defconfig +++ b/configs/mt7622_rfb_defconfig @@ -14,6 +14,7 @@ CONFIG_SYS_PROMPT="MT7622> " CONFIG_CMD_BOOTMENU=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_PCI=y CONFIG_CMD_PING=y CONFIG_CMD_SMC=y CONFIG_ENV_OVERWRITE=y @@ -53,3 +54,6 @@ CONFIG_MTK_TIMER=y CONFIG_WDT_MTK=y CONFIG_LZO=y CONFIG_HEXDUMP=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_MEDIATEK=y diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index d8c9756c2a..f2f8275aec 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -130,4 +130,12 @@ config AHCI_MVEBU onboard AHCI SATA. If unsure, say N. + +config MTK_AHCI + bool "Enable Mediatek AHCI driver support" + depends on AHCI + help + Enable this driver to support Sata devices through + Mediatek AHCI controller (e.g. MT7622). + endmenu diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index a69edb10f7..98fb480700 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_SATA_SIL) += sata_sil.o obj-$(CONFIG_SANDBOX) += sata_sandbox.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o obj-$(CONFIG_SUNXI_AHCI) += ahci_sunxi.o +obj-$(CONFIG_MTK_AHCI) += mtk_ahci.o diff --git a/drivers/ata/mtk_ahci.c b/drivers/ata/mtk_ahci.c new file mode 100644 index 0000000000..8e09c5f9e6 --- /dev/null +++ b/drivers/ata/mtk_ahci.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * MTK SATA platform driver + * + * (C) Copyright 2020 + * Mediatek + * + * Author: Frank Wunderlich <frank-w@public-files.de> + * based on https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/ata/ahci_mtk.c + * Author: Ryder Lee <ryder.lee@mediatek.com> + */ + +#include <common.h> +#include <ahci.h> +#include <asm/io.h> +#include <dm.h> +#include <dm/of_access.h> +#include <generic-phy.h> +#include <linux/err.h> +#include <regmap.h> +#include <reset.h> +#include <sata.h> +#include <scsi.h> +#include <syscon.h> + +#define SYS_CFG 0x14 +#define SYS_CFG_SATA_MSK GENMASK(31, 30) +#define SYS_CFG_SATA_EN BIT(31) + +struct mtk_ahci_priv { + void *base; + + struct ahci_uc_priv ahci_priv; + struct regmap *mode; + struct reset_ctl_bulk rst_bulk; +}; + +static int mtk_ahci_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + + return ahci_bind_scsi(dev, &scsi_dev); +} + +static int mtk_ahci_ofdata_to_platdata(struct udevice *dev) +{ + struct mtk_ahci_priv *priv = dev_get_priv(dev); + + priv->base = devfdt_remap_addr_index(dev, 0); + + return 0; +} + +static int mtk_ahci_parse_property(struct ahci_uc_priv *hpriv, + struct udevice *dev) +{ + struct mtk_ahci_priv *plat = dev_get_priv(dev); + const void *fdt = gd->fdt_blob; + + /* enable SATA function if needed */ + if (fdt_get_property(fdt, dev_of_offset(dev), + "mediatek,phy-mode", NULL)) { + plat->mode = syscon_regmap_lookup_by_phandle(dev, + "mediatek,phy-mode"); + if (IS_ERR(plat->mode)) { + dev_err(dev, "missing phy-mode phandle\n"); + return PTR_ERR(plat->mode); + } + regmap_update_bits(plat->mode, SYS_CFG, + SYS_CFG_SATA_MSK, SYS_CFG_SATA_EN); + } + + ofnode_read_u32(dev->node, "ports-implemented", &hpriv->port_map); + return 0; +} + +static int mtk_ahci_probe(struct udevice *dev) +{ + struct mtk_ahci_priv *priv = dev_get_priv(dev); + int ret; + struct phy phy; + + ret = mtk_ahci_parse_property(&priv->ahci_priv, dev); + if (ret) + return ret; + + ret = reset_get_bulk(dev, &priv->rst_bulk); + if (!ret) { + reset_assert_bulk(&priv->rst_bulk); + reset_deassert_bulk(&priv->rst_bulk); + } else { + dev_err(dev, "Failed to get reset: %d\n", ret); + } + + ret = generic_phy_get_by_name(dev, "sata-phy", &phy); + if (ret) { + pr_err("can't get the phy from DT\n"); + return ret; + } + + ret = generic_phy_init(&phy); + if (ret) { + pr_err("unable to initialize the sata phy\n"); + return ret; + } + + ret = generic_phy_power_on(&phy); + if (ret) { + pr_err("unable to power on the sata phy\n"); + return ret; + } + + return ahci_probe_scsi(dev, (ulong)priv->base); +} + +static const struct udevice_id mtk_ahci_ids[] = { + { .compatible = "mediatek,mtk-ahci" }, + { } +}; + +U_BOOT_DRIVER(mtk_ahci) = { + .name = "mtk_ahci", + .id = UCLASS_AHCI, + .of_match = mtk_ahci_ids, + .bind = mtk_ahci_bind, + .ofdata_to_platdata = mtk_ahci_ofdata_to_platdata, + .ops = &scsi_ops, + .probe = mtk_ahci_probe, + .priv_auto_alloc_size = sizeof(struct mtk_ahci_priv), +}; diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c index dc0ba71f10..d53ed69189 100644 --- a/drivers/clk/mediatek/clk-mt7622.c +++ b/drivers/clk/mediatek/clk-mt7622.c @@ -453,6 +453,41 @@ static const struct mtk_gate peri_cgs[] = { GATE_PERI1(CLK_PERI_IRTX_PD, CLK_TOP_IRTX_SEL, 2), }; +/* pciesys */ +static const struct mtk_gate_regs pcie_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +#define GATE_PCIE(_id, _parent, _shift) { \ + .id = _id, \ + .parent = _parent, \ + .regs = &pcie_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate pcie_cgs[] = { + GATE_PCIE(CLK_PCIE_P1_AUX_EN, CLK_TOP_P1_1MHZ, 12), + GATE_PCIE(CLK_PCIE_P1_OBFF_EN, CLK_TOP_4MHZ, 13), + GATE_PCIE(CLK_PCIE_P1_AHB_EN, CLK_TOP_AXI_SEL, 14), + GATE_PCIE(CLK_PCIE_P1_AXI_EN, CLK_TOP_HIF_SEL, 15), + GATE_PCIE(CLK_PCIE_P1_MAC_EN, CLK_TOP_PCIE1_MAC_EN, 16), + GATE_PCIE(CLK_PCIE_P1_PIPE_EN, CLK_TOP_PCIE1_PIPE_EN, 17), + GATE_PCIE(CLK_PCIE_P0_AUX_EN, CLK_TOP_P0_1MHZ, 18), + GATE_PCIE(CLK_PCIE_P0_OBFF_EN, CLK_TOP_4MHZ, 19), + GATE_PCIE(CLK_PCIE_P0_AHB_EN, CLK_TOP_AXI_SEL, 20), + GATE_PCIE(CLK_PCIE_P0_AXI_EN, CLK_TOP_HIF_SEL, 21), + GATE_PCIE(CLK_PCIE_P0_MAC_EN, CLK_TOP_PCIE0_MAC_EN, 22), + GATE_PCIE(CLK_PCIE_P0_PIPE_EN, CLK_TOP_PCIE0_PIPE_EN, 23), + GATE_PCIE(CLK_SATA_AHB_EN, CLK_TOP_AXI_SEL, 26), + GATE_PCIE(CLK_SATA_AXI_EN, CLK_TOP_HIF_SEL, 27), + GATE_PCIE(CLK_SATA_ASIC_EN, CLK_TOP_SATA_ASIC, 28), + GATE_PCIE(CLK_SATA_RBC_EN, CLK_TOP_SATA_RBC, 29), + GATE_PCIE(CLK_SATA_PM_EN, CLK_TOP_UNIVPLL2_D4, 30), +}; + /* ethsys */ static const struct mtk_gate_regs eth_cg_regs = { .sta_ofs = 0x30, @@ -554,6 +589,25 @@ static int mt7622_pericfg_probe(struct udevice *dev) return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, peri_cgs); } +static int mt7622_pciesys_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, pcie_cgs); +} + +static int mt7622_pciesys_bind(struct udevice *dev) +{ + int ret = 0; + + if (IS_ENABLED(CONFIG_RESET_MEDIATEK)) { +// PCIESYS uses in linux also 0x34 = ETHSYS reset controller + ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); + if (ret) + debug("Warning: failed to bind reset controller\n"); + } + + return ret; +} + static int mt7622_ethsys_probe(struct udevice *dev) { return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, eth_cgs); @@ -597,6 +651,11 @@ static const struct udevice_id mt7622_pericfg_compat[] = { { } }; +static const struct udevice_id mt7622_pciesys_compat[] = { + { .compatible = "mediatek,mt7622-pciesys", }, + { } +}; + static const struct udevice_id mt7622_ethsys_compat[] = { { .compatible = "mediatek,mt7622-ethsys", }, { } @@ -660,6 +719,16 @@ U_BOOT_DRIVER(mtk_clk_pericfg) = { .flags = DM_FLAG_PRE_RELOC, }; +U_BOOT_DRIVER(mtk_clk_pciesys) = { + .name = "mt7622-clock-pciesys", + .id = UCLASS_CLK, + .of_match = mt7622_pciesys_compat, + .probe = mt7622_pciesys_probe, + .bind = mt7622_pciesys_bind, + .priv_auto_alloc_size = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, +}; + U_BOOT_DRIVER(mtk_clk_ethsys) = { .name = "mt7622-clock-ethsys", .id = UCLASS_CLK, diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c index 6e6375cec0..ad34f7c597 100644 --- a/drivers/pci/pcie_mediatek.c +++ b/drivers/pci/pcie_mediatek.c @@ -20,6 +20,7 @@ #include <linux/bitops.h> #include <linux/iopoll.h> #include <linux/list.h> +#include "pci_internal.h" /* PCIe shared registers */ #define PCIE_SYS_CFG 0x00 @@ -54,18 +55,90 @@ #define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) #define PCIE_FC_CREDIT_VAL(x) ((x) << 16) +/* PCIe V2 share registers */ +#define PCIE_SYS_CFG_V2 0x0 +#define PCIE_CSR_LTSSM_EN(x) BIT(0 + (x) * 8) +#define PCIE_CSR_ASPM_L1_EN(x) BIT(1 + (x) * 8) + +/* PCIe V2 per-port registers */ +#define PCIE_CONF_VEND_ID 0x100 +#define PCIE_CONF_DEVICE_ID 0x102 +#define PCIE_CONF_CLASS_ID 0x106 + +#define PCIE_AHB_TRANS_BASE0_L 0x438 +#define PCIE_AHB_TRANS_BASE0_H 0x43c +#define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) +#define PCIE_AXI_WINDOW0 0x448 +#define WIN_ENABLE BIT(7) + +/* + * Define PCIe to AHB window size as 2^33 to support max 8GB address space + * translate, support least 4GB DRAM size access from EP DMA(physical DRAM + * start from 0x40000000). + */ +#define PCIE2AHB_SIZE 0x21 + +/* PCIe V2 configuration transaction header */ +#define PCIE_CFG_HEADER0 0x460 +#define PCIE_CFG_HEADER1 0x464 +#define PCIE_CFG_HEADER2 0x468 +#define PCIE_CFG_WDATA 0x470 +#define PCIE_APP_TLP_REQ 0x488 +#define PCIE_CFG_RDATA 0x48c +#define APP_CFG_REQ BIT(0) +#define APP_CPL_STATUS GENMASK(7, 5) + +#define CFG_WRRD_TYPE_0 4 +#define CFG_WR_FMT 2 +#define CFG_RD_FMT 0 + +#define CFG_DW0_LENGTH(length) ((length) & GENMASK(9, 0)) +#define CFG_DW0_TYPE(type) (((type) << 24) & GENMASK(28, 24)) +#define CFG_DW0_FMT(fmt) (((fmt) << 29) & GENMASK(31, 29)) +#define CFG_DW2_REGN(regn) ((regn) & GENMASK(11, 2)) +#define CFG_DW2_FUN(fun) (((fun) << 16) & GENMASK(18, 16)) +#define CFG_DW2_DEV(dev) (((dev) << 19) & GENMASK(23, 19)) +#define CFG_DW2_BUS(bus) (((bus) << 24) & GENMASK(31, 24)) +#define CFG_HEADER_DW0(type, fmt) \ + (CFG_DW0_LENGTH(1) | CFG_DW0_TYPE(type) | CFG_DW0_FMT(fmt)) +#define CFG_HEADER_DW1(where, size) \ + (GENMASK(((size) - 1), 0) << ((where) & 0x3)) +#define CFG_HEADER_DW2(regn, fun, dev, bus) \ + (CFG_DW2_REGN(regn) | CFG_DW2_FUN(fun) | \ + CFG_DW2_DEV(dev) | CFG_DW2_BUS(bus)) + +#define PCIE_RST_CTRL 0x510 +#define PCIE_PHY_RSTB BIT(0) +#define PCIE_PIPE_SRSTB BIT(1) +#define PCIE_MAC_SRSTB BIT(2) +#define PCIE_CRSTB BIT(3) +#define PCIE_PERSTB BIT(8) +#define PCIE_LINKDOWN_RST_EN GENMASK(15, 13) +#define PCIE_LINK_STATUS_V2 0x804 +#define PCIE_PORT_LINKUP_V2 BIT(11) + +#define PCI_VENDOR_ID_MEDIATEK 0x14c3 + +enum MTK_PCIE_GEN {PCIE_V1, PCIE_V2, PCIE_V3}; + struct mtk_pcie_port { void __iomem *base; struct list_head list; struct mtk_pcie *pcie; struct reset_ctl reset; struct clk sys_ck; + struct clk ahb_ck; + struct clk axi_ck; + struct clk aux_ck; + struct clk obff_ck; + struct clk pipe_ck; struct phy phy; u32 slot; }; struct mtk_pcie { void __iomem *base; + void *priv; struct clk free_ck; struct list_head ports; }; @@ -102,6 +175,152 @@ static const struct dm_pci_ops mtk_pcie_ops = { .write_config = mtk_pcie_write_config, }; +static int mtk_pcie_check_cfg_cpld(struct mtk_pcie_port *port) +{ + u32 val; + int err; + + err = readl_poll_timeout(port->base + PCIE_APP_TLP_REQ, val, + !(val & APP_CFG_REQ), 100 * 1000); + if (err) + return -1; + + if (readl(port->base + PCIE_APP_TLP_REQ) & APP_CPL_STATUS) + return -1; + + return 0; +} + +static int mtk_pcie_hw_rd_cfg(struct mtk_pcie_port *port, u32 bus, pci_dev_t devfn, + int where, int size, ulong *val) +{ + u32 tmp; + + writel(CFG_HEADER_DW0(CFG_WRRD_TYPE_0, CFG_RD_FMT), + port->base + PCIE_CFG_HEADER0); + writel(CFG_HEADER_DW1(where, size), port->base + PCIE_CFG_HEADER1); + writel(CFG_HEADER_DW2(where, PCI_FUNC(devfn), PCI_DEV(devfn), bus), + port->base + PCIE_CFG_HEADER2); + + /* Trigger h/w to transmit Cfgrd TLP */ + tmp = readl(port->base + PCIE_APP_TLP_REQ); + tmp |= APP_CFG_REQ; + writel(tmp, port->base + PCIE_APP_TLP_REQ); + + /* Check completion status */ + if (mtk_pcie_check_cfg_cpld(port)) + return -1; + + /* Read cpld payload of Cfgrd */ + *val = readl(port->base + PCIE_CFG_RDATA); + + if (size == 1) + *val = (*val >> (8 * (where & 3))) & 0xff; + else if (size == 2) + *val = (*val >> (8 * (where & 3))) & 0xffff; + + return 0; +} + +static int mtk_pcie_hw_wr_cfg(struct mtk_pcie_port *port, u32 bus, pci_dev_t devfn, + int where, int size, u32 val) +{ + /* Write PCIe configuration transaction header for Cfgwr */ + writel(CFG_HEADER_DW0(CFG_WRRD_TYPE_0, CFG_WR_FMT), + port->base + PCIE_CFG_HEADER0); + writel(CFG_HEADER_DW1(where, size), port->base + PCIE_CFG_HEADER1); + writel(CFG_HEADER_DW2(where, PCI_FUNC(devfn), PCI_DEV(devfn), bus), + port->base + PCIE_CFG_HEADER2); + + /* Write Cfgwr data */ + val = val << 8 * (where & 3); + writel(val, port->base + PCIE_CFG_WDATA); + + /* Trigger h/w to transmit Cfgwr TLP */ + val = readl(port->base + PCIE_APP_TLP_REQ); + val |= APP_CFG_REQ; + writel(val, port->base + PCIE_APP_TLP_REQ); + + /* Check completion status */ + return mtk_pcie_check_cfg_cpld(port); +} + +static struct mtk_pcie_port *mtk_pcie_find_port(const struct udevice *bus, + pci_dev_t bdf) +{ + struct mtk_pcie *pcie = dev_get_priv(bus); + struct mtk_pcie_port *port; + struct udevice *dev; + struct pci_child_platdata *pplat = NULL; + int ret = 0; + + if (PCI_BUS(bdf) != 0) { + ret = pci_get_bus(PCI_BUS(bdf), &dev); + if (ret) { + debug("No such device,ret = %d\n", ret); + return NULL; + } + + while (dev->parent->seq != 0) + dev = dev->parent; + + pplat = dev_get_parent_platdata(dev); + } + + list_for_each_entry(port, &pcie->ports, list) { + if ((PCI_BUS(bdf) == 0) && (PCI_DEV(bdf) == port->slot)) + return port; + + if (PCI_BUS(bdf) != 0 && PCI_DEV(bdf) == 0 && + PCI_DEV(pplat->devfn) == port->slot) + return port; + } + + return NULL; +} + +static int mtk_pcie_config_read(const struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct mtk_pcie_port *port; + int ret; + + port = mtk_pcie_find_port(bus, bdf); + if (!port) { + *valuep = pci_get_ff(size); + return 0; + } + + ret = mtk_pcie_hw_rd_cfg(port, PCI_BUS(bdf), bdf, offset, (1 << size), valuep); + if (ret) + *valuep = pci_get_ff(size); + + return ret; +} + +static int mtk_pcie_config_write(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct mtk_pcie_port *port; + + port = mtk_pcie_find_port(bus, bdf); + if (!port) + return 0; + + /* Do not modify RC bar 0/1. */ + if (PCI_BUS(bdf) == 0 && (offset == 0x10 || offset == 0x14)) + return 0; + + return mtk_pcie_hw_wr_cfg(port, PCI_BUS(bdf), bdf, offset, (1 << size), value); +} + +static const struct dm_pci_ops mtk_pcie_ops_v2 = { + .read_config = mtk_pcie_config_read, + .write_config = mtk_pcie_config_write, +}; + static void mtk_pcie_port_free(struct mtk_pcie_port *port) { list_del(&port->list); @@ -151,6 +370,73 @@ static int mtk_pcie_startup_port(struct mtk_pcie_port *port) return 0; } +static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) +{ + struct mtk_pcie *pcie = port->pcie; + struct udevice *dev = pcie->priv; + struct pci_region *pci_mem; + u32 val; + int err; + + /* MT7622/MT7629 platforms need to enable LTSSM and ASPM from PCIe subsys */ + if (pcie->base) { + val = readl(pcie->base + PCIE_SYS_CFG_V2); + val |= PCIE_CSR_LTSSM_EN(port->slot) | + PCIE_CSR_ASPM_L1_EN(port->slot); + writel(val, pcie->base + PCIE_SYS_CFG_V2); + } + + /* Assert all reset signals */ + writel(0, port->base + PCIE_RST_CTRL); + + /* + * Enable PCIe link down reset, if link status changed from link up to + * link down, this will reset MAC control registers and configuration + * space. + */ + writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); + udelay(500); + + /* De-assert PHY, PE, PIPE, MAC and configuration reset */ + val = readl(port->base + PCIE_RST_CTRL); + val |= PCIE_PHY_RSTB | PCIE_PIPE_SRSTB | PCIE_MAC_SRSTB | PCIE_CRSTB; + writel(val, port->base + PCIE_RST_CTRL); + + mdelay(100); + val |= PCIE_PERSTB; + writel(val, port->base + PCIE_RST_CTRL); + + /* Set up vendor ID and class code */ + val = PCI_VENDOR_ID_MEDIATEK; + writew(val, port->base + PCIE_CONF_VEND_ID); + + val = PCI_CLASS_BRIDGE_PCI; + writew(val, port->base + PCIE_CONF_CLASS_ID); + + /* 100ms timeout value should be enough for Gen1/2 training */ + err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, + !!(val & PCIE_PORT_LINKUP_V2), + 100 * 1000); + if (err) + return -ETIMEDOUT; + + pci_get_regions(dev, NULL, &pci_mem, NULL); + + /* Set AHB to PCIe translation windows */ + val = lower_32_bits(pci_mem->bus_start) | + AHB2PCIE_SIZE(fls(pci_mem->size) - 1); + writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); + + val = upper_32_bits(pci_mem->bus_start); + writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); + + /* Set PCIe to AXI translation memory space.*/ + val = PCIE2AHB_SIZE | WIN_ENABLE; + writel(val, port->base + PCIE_AXI_WINDOW0); + + return 0; +} + static void mtk_pcie_enable_port(struct mtk_pcie_port *port) { int err; @@ -183,6 +469,55 @@ exit: mtk_pcie_port_free(port); } +static void mtk_pcie_enable_port_v2(struct mtk_pcie_port *port) +{ + int err = 0; + + err = clk_enable(&port->sys_ck); + if (err) { + debug("clk_enable(sys_ck) failed: %d\n", err); + goto exit; + } + + err = clk_enable(&port->ahb_ck); + if (err) { + debug("clk_enable(ahb_ck) failed: %d\n", err); + goto exit; + } + + err = clk_enable(&port->aux_ck); + if (err) { + debug("clk_enable(aux_ck) failed: %d\n", err); + goto exit; + } + + err = clk_enable(&port->axi_ck); + if (err) { + debug("clk_enable(axi_ck) failed: %d\n", err); + goto exit; + } + + err = clk_enable(&port->obff_ck); + if (err) { + debug("clk_enable(obff_ck) failed: %d\n", err); + goto exit; + } + + err = clk_enable(&port->pipe_ck); + if (err) { + debug("clk_enable(pipe_ck) failed: %d\n", err); + goto exit; + } + + err = mtk_pcie_startup_port_v2(port); + if (!err) + 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); @@ -221,6 +556,75 @@ static int mtk_pcie_parse_port(struct udevice *dev, u32 slot) return 0; } +static int mtk_pcie_parse_port_v2(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) { + debug("failed to map port%d base\n", slot); + return -ENOENT; + } + + snprintf(name, sizeof(name), "sys_ck%d", slot); + err = clk_get_by_name(dev, name, &port->sys_ck); + if (err) { + debug("clk_get_by_name(sys_ck) failed: %d\n", err); + return err; + } + + snprintf(name, sizeof(name), "ahb_ck%d", slot); + err = clk_get_by_name(dev, name, &port->ahb_ck); + if (err) { + debug("clk_get_by_name(ahb_ck) failed: %d\n", err); + return err; + } + + snprintf(name, sizeof(name), "aux_ck%d", slot); + err = clk_get_by_name(dev, name, &port->aux_ck); + if (err) { + debug("clk_get_by_name(aux_ck) failed: %d\n", err); + return err; + } + + snprintf(name, sizeof(name), "axi_ck%d", slot); + err = clk_get_by_name(dev, name, &port->axi_ck); + if (err) { + debug("clk_get_by_name(axi_ck) failed: %d\n", err); + return err; + } + + snprintf(name, sizeof(name), "obff_ck%d", slot); + err = clk_get_by_name(dev, name, &port->obff_ck); + if (err) { + debug("clk_get_by_name(obff_ck) failed: %d\n", err); + return err; + } + + snprintf(name, sizeof(name), "pipe_ck%d", slot); + err = clk_get_by_name(dev, name, &port->pipe_ck); + if (err) { + debug("clk_get_by_name(pipe_ck) failed: %d\n", 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); @@ -268,16 +672,68 @@ static int mtk_pcie_probe(struct udevice *dev) return 0; } +static int mtk_pcie_probe_v2(struct udevice *dev) +{ + struct mtk_pcie *pcie = dev_get_priv(dev); + struct mtk_pcie_port *port, *tmp; + struct fdt_pci_addr addr; + ofnode subnode; + unsigned int slot; + int err; + + INIT_LIST_HEAD(&pcie->ports); + + pcie->base = dev_remap_addr_name(dev, "subsys"); + if (!pcie->base) + return -ENOENT; + + pcie->priv = dev; + + dev_for_each_subnode(subnode, dev) { + 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_v2(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_v2(port); + + return 0; +} + static const struct udevice_id mtk_pcie_ids[] = { - { .compatible = "mediatek,mt7623-pcie", }, + { .compatible = "mediatek,mt7623-pcie", PCIE_V1}, { } }; -U_BOOT_DRIVER(pcie_mediatek) = { - .name = "pcie_mediatek", +U_BOOT_DRIVER(pcie_mediatek_v1) = { + .name = "pcie_mediatek_v1", .id = UCLASS_PCI, .of_match = mtk_pcie_ids, .ops = &mtk_pcie_ops, .probe = mtk_pcie_probe, .priv_auto_alloc_size = sizeof(struct mtk_pcie), }; + +static const struct udevice_id mtk_pcie_ids_v2[] = { + { .compatible = "mediatek,mt7622-pcie", PCIE_V2}, + { } +}; + +U_BOOT_DRIVER(pcie_mediatek_v2) = { + .name = "pcie_mediatek_v2", + .id = UCLASS_PCI, + .of_match = mtk_pcie_ids_v2, + .ops = &mtk_pcie_ops_v2, + .probe = mtk_pcie_probe_v2, + .priv_auto_alloc_size = sizeof(struct mtk_pcie), +}; diff --git a/drivers/phy/phy-mtk-tphy.c b/drivers/phy/phy-mtk-tphy.c index 1e65c24356..326227a30d 100644 --- a/drivers/phy/phy-mtk-tphy.c +++ b/drivers/phy/phy-mtk-tphy.c @@ -175,6 +175,65 @@ #define XC3_RG_U3_XTAL_RX_PWD BIT(9) #define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8) +/* SATA register setting */ +#define PHYD_CTRL_SIGNAL_MODE4 0x1c +/* CDR Charge Pump P-path current adjustment */ +#define RG_CDR_BICLTD1_GEN1_MSK GENMASK(23, 20) +#define RG_CDR_BICLTD1_GEN1_VAL(x) ((0xf & (x)) << 20) +#define RG_CDR_BICLTD0_GEN1_MSK GENMASK(11, 8) +#define RG_CDR_BICLTD0_GEN1_VAL(x) ((0xf & (x)) << 8) + +#define PHYD_DESIGN_OPTION2 0x24 +/* Symbol lock count selection */ +#define RG_LOCK_CNT_SEL_MSK GENMASK(5, 4) +#define RG_LOCK_CNT_SEL_VAL(x) ((0x3 & (x)) << 4) + +#define PHYD_DESIGN_OPTION9 0x40 +/* COMWAK GAP width window */ +#define RG_TG_MAX_MSK GENMASK(20, 16) +#define RG_TG_MAX_VAL(x) ((0x1f & (x)) << 16) +/* COMINIT GAP width window */ +#define RG_T2_MAX_MSK GENMASK(13, 8) +#define RG_T2_MAX_VAL(x) ((0x3f & (x)) << 8) +/* COMWAK GAP width window */ +#define RG_TG_MIN_MSK GENMASK(7, 5) +#define RG_TG_MIN_VAL(x) ((0x7 & (x)) << 5) +/* COMINIT GAP width window */ +#define RG_T2_MIN_MSK GENMASK(4, 0) +#define RG_T2_MIN_VAL(x) (0x1f & (x)) + +#define ANA_RG_CTRL_SIGNAL1 0x4c +/* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */ +#define RG_IDRV_0DB_GEN1_MSK GENMASK(13, 8) +#define RG_IDRV_0DB_GEN1_VAL(x) ((0x3f & (x)) << 8) + +#define ANA_RG_CTRL_SIGNAL4 0x58 +#define RG_CDR_BICLTR_GEN1_MSK GENMASK(23, 20) +#define RG_CDR_BICLTR_GEN1_VAL(x) ((0xf & (x)) << 20) +/* Loop filter R1 resistance adjustment for Gen1 speed */ +#define RG_CDR_BR_GEN2_MSK GENMASK(10, 8) +#define RG_CDR_BR_GEN2_VAL(x) ((0x7 & (x)) << 8) + +#define ANA_RG_CTRL_SIGNAL6 0x60 +/* I-path capacitance adjustment for Gen1 */ +#define RG_CDR_BC_GEN1_MSK GENMASK(28, 24) +#define RG_CDR_BC_GEN1_VAL(x) ((0x1f & (x)) << 24) +#define RG_CDR_BIRLTR_GEN1_MSK GENMASK(4, 0) +#define RG_CDR_BIRLTR_GEN1_VAL(x) (0x1f & (x)) + +#define ANA_EQ_EYE_CTRL_SIGNAL1 0x6c +/* RX Gen1 LEQ tuning step */ +#define RG_EQ_DLEQ_LFI_GEN1_MSK GENMASK(11, 8) +#define RG_EQ_DLEQ_LFI_GEN1_VAL(x) ((0xf & (x)) << 8) + +#define ANA_EQ_EYE_CTRL_SIGNAL4 0xd8 +#define RG_CDR_BIRLTD0_GEN1_MSK GENMASK(20, 16) +#define RG_CDR_BIRLTD0_GEN1_VAL(x) ((0x1f & (x)) << 16) + +#define ANA_EQ_EYE_CTRL_SIGNAL5 0xdc +#define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0) +#define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x)) + enum mtk_phy_version { MTK_TPHY_V1 = 1, MTK_TPHY_V2, @@ -372,6 +431,45 @@ static void pcie_phy_instance_init(struct mtk_tphy *tphy, udelay(3000); } +static void sata_phy_instance_init(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct u3phy_banks *u3_banks = &instance->u3_banks; + + clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL6, + RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK, + RG_CDR_BIRLTR_GEN1_VAL(0x6) | + RG_CDR_BC_GEN1_VAL(0x1a)); + clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL4, + RG_CDR_BIRLTD0_GEN1_MSK, + RG_CDR_BIRLTD0_GEN1_VAL(0x18)); + clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL5, + RG_CDR_BIRLTD0_GEN3_MSK, + RG_CDR_BIRLTD0_GEN3_VAL(0x06)); + clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL4, + RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK, + RG_CDR_BICLTR_GEN1_VAL(0x0c) | + RG_CDR_BR_GEN2_VAL(0x07)); + clrsetbits_le32(u3_banks->phyd + PHYD_CTRL_SIGNAL_MODE4, + RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK, + RG_CDR_BICLTD0_GEN1_VAL(0x08) | + RG_CDR_BICLTD1_GEN1_VAL(0x02)); + clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION2, + RG_LOCK_CNT_SEL_MSK, + RG_LOCK_CNT_SEL_VAL(0x02)); + clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION9, + RG_T2_MIN_MSK | RG_TG_MIN_MSK | + RG_T2_MAX_MSK | RG_TG_MAX_MSK, + RG_T2_MIN_VAL(0x12) | RG_TG_MIN_VAL(0x04) | + RG_T2_MAX_VAL(0x31) | RG_TG_MAX_VAL(0x0e)); + clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL1, + RG_IDRV_0DB_GEN1_MSK, + RG_IDRV_0DB_GEN1_VAL(0x20)); + clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL1, + RG_EQ_DLEQ_LFI_GEN1_MSK, + RG_EQ_DLEQ_LFI_GEN1_VAL(0x03)); +} + static void pcie_phy_instance_power_on(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) { @@ -414,6 +512,9 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy, u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; break; + case PHY_TYPE_SATA: + u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; + break; default: dev_err(tphy->dev, "incompatible PHY type\n"); return; @@ -474,6 +575,9 @@ static int mtk_phy_init(struct phy *phy) case PHY_TYPE_PCIE: pcie_phy_instance_init(tphy, instance); break; + case PHY_TYPE_SATA: + sata_phy_instance_init(tphy, instance); + break; default: dev_err(tphy->dev, "incompatible PHY type\n"); return -EINVAL; @@ -552,6 +656,7 @@ static int mtk_phy_xlate(struct phy *phy, instance->type = args->args[1]; if (!(instance->type == PHY_TYPE_USB2 || instance->type == PHY_TYPE_USB3 || + instance->type == PHY_TYPE_SATA || instance->type == PHY_TYPE_PCIE)) { dev_err(phy->dev, "unsupported device type\n"); return -EINVAL; diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8512.c b/drivers/pinctrl/mediatek/pinctrl-mt8512.c index af43754a4d..bf2a8dd90f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8512.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8512.c @@ -31,15 +31,15 @@ static const struct mtk_pin_field_calc mt8512_pin_di_range[] = { }; static const struct mtk_pin_field_calc mt8512_pin_do_range[] = { - PIN_FIELD(0, 115, 0x860, 0x10, 0, 1), + PIN_FIELD(0, 115, 0x0A0, 0x10, 0, 1), }; static const struct mtk_pin_field_calc mt8512_pin_pullen_range[] = { - PIN_FIELD(0, 115, 0x900, 0x10, 0, 1), + PIN_FIELD(0, 115, 0x860, 0x10, 0, 1), }; static const struct mtk_pin_field_calc mt8512_pin_pullsel_range[] = { - PIN_FIELD(0, 115, 0x0A0, 0x10, 0, 1), + PIN_FIELD(0, 115, 0x900, 0x10, 0, 1), }; static const struct mtk_pin_field_calc mt8512_pin_ies_range[] = { diff --git a/include/dt-bindings/reset/mt7629-reset.h b/include/dt-bindings/reset/mt7629-reset.h index 8f1634f7a6..311a5cb3d0 100644 --- a/include/dt-bindings/reset/mt7629-reset.h +++ b/include/dt-bindings/reset/mt7629-reset.h @@ -6,7 +6,10 @@ #ifndef _DT_BINDINGS_MTK_RESET_H_ #define _DT_BINDINGS_MTK_RESET_H_ -/* PCIe Subsystem resets */ +/* PCIe/SATA Subsystem resets */ +#define MT7622_SATA_PHY_REG_RST 12 +#define MT7622_SATA_PHY_SW_RST 13 +#define MT7622_SATA_AXI_BUS_RST 15 #define PCIE1_CORE_RST 19 #define PCIE1_MMIO_RST 20 #define PCIE1_HRST 21 |