Commit d620d864 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/amlogic'

  - Add Amlogic AXG MIPI/PCIe PHY driver and related DT bindings (Remi
    Pommarel)

  - Use shared PHY driver for Amlogic AXG and G12A platforms (Remi
    Pommarel)

* remotes/lorenzo/pci/amlogic:
  PCI: amlogic: Use AXG PCIE
  phy: amlogic: Add Amlogic AXG PCIE PHY Driver
  phy: amlogic: Add Amlogic AXG MIPI/PCIE analog PHY Driver
  dt-bindings: PCI: meson: Update PCIE bindings documentation
  dt-bindings: Add AXG shared MIPI/PCIE analog PHY bindings
  dt-bindings: Add AXG PCIE PHY bindings
parents 1ee57ad6 1e6bbc46
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ Required properties:
- reg-names: Must be
	- "elbi"	External local bus interface registers
	- "cfg"		Meson specific registers
	- "phy"		Meson PCIE PHY registers for AXG SoC Family
	- "config"	PCIe configuration space
- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal.
- clocks: Must contain an entry for each entry in clock-names.
@@ -26,13 +25,13 @@ Required properties:
	- "pclk"       PCIe GEN 100M PLL clock
	- "port"       PCIe_x(A or B) RC clock gate
	- "general"    PCIe Phy clock
	- "mipi"       PCIe_x(A or B) 100M ref clock gate for AXG SoC Family
- resets: phandle to the reset lines.
- reset-names: must contain "phy" "port" and "apb"
       - "phy"         Share PHY reset for AXG SoC Family
- reset-names: must contain "port" and "apb"
       - "port"        Port A or B reset
       - "apb"         Share APB reset
- phys: should contain a phandle to the shared phy for G12A SoC Family
- phys: should contain a phandle to the PCIE phy
- phy-names: must contain "pcie"

- device_type:
	should be "pci". As specified in designware-pcie.txt

@@ -43,9 +42,8 @@ Example configuration:
			compatible = "amlogic,axg-pcie", "snps,dw-pcie";
			reg = <0x0 0xf9800000 0x0 0x400000
					0x0 0xff646000 0x0 0x2000
					0x0 0xff644000 0x0 0x2000
					0x0 0xf9f00000 0x0 0x100000>;
			reg-names = "elbi", "cfg", "phy", "config";
			reg-names = "elbi", "cfg", "config";
			reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>;
			interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>;
			#interrupt-cells = <1>;
@@ -58,17 +56,15 @@ Example configuration:
			ranges = <0x82000000 0 0 0x0 0xf9c00000 0 0x00300000>;

			clocks = <&clkc CLKID_USB
					&clkc CLKID_MIPI_ENABLE
					&clkc CLKID_PCIE_A
					&clkc CLKID_PCIE_CML_EN0>;
			clock-names = "general",
					"mipi",
					"pclk",
					"port";
			resets = <&reset RESET_PCIE_PHY>,
				<&reset RESET_PCIE_A>,
			resets = <&reset RESET_PCIE_A>,
				<&reset RESET_PCIE_APB>;
			reset-names = "phy",
					"port",
			reset-names = "port",
					"apb";
			phys = <&pcie_phy>;
			phy-names = "pcie";
	};
+35 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/phy/amlogic,meson-axg-mipi-pcie-analog.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Amlogic AXG shared MIPI/PCIE analog PHY

maintainers:
  - Remi Pommarel <repk@triplefau.lt>

properties:
  compatible:
    const: amlogic,axg-mipi-pcie-analog-phy

  reg:
    maxItems: 1

  "#phy-cells":
    const: 1

required:
  - compatible
  - reg
  - "#phy-cells"

additionalProperties: false

examples:
  - |
    mpphy: phy@0 {
          compatible = "amlogic,axg-mipi-pcie-analog-phy";
          reg = <0x0 0x0 0x0 0xc>;
          #phy-cells = <1>;
    };
+52 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/phy/amlogic,meson-axg-pcie.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: Amlogic AXG PCIE PHY

maintainers:
  - Remi Pommarel <repk@triplefau.lt>

properties:
  compatible:
    const: amlogic,axg-pcie-phy

  reg:
    maxItems: 1

  resets:
    maxItems: 1

  phys:
    maxItems: 1

  phy-names:
    const: analog

  "#phy-cells":
    const: 0

required:
  - compatible
  - reg
  - phys
  - phy-names
  - resets
  - "#phy-cells"

additionalProperties: false

examples:
  - |
    #include <dt-bindings/reset/amlogic,meson-axg-reset.h>
    #include <dt-bindings/phy/phy.h>
    pcie_phy: pcie-phy@ff644000 {
          compatible = "amlogic,axg-pcie-phy";
          reg = <0x0 0xff644000 0x0 0x1c>;
          resets = <&reset RESET_PCIE_PHY>;
          phys = <&mipi_analog_phy PHY_TYPE_PCIE>;
          phy-names = "analog";
          #phy-cells = <0>;
    };
+22 −94
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@
#define PORT_CLK_RATE			100000000UL
#define MAX_PAYLOAD_SIZE		256
#define MAX_READ_REQ_SIZE		256
#define MESON_PCIE_PHY_POWERUP		0x1c
#define PCIE_RESET_DELAY		500
#define PCIE_SHARED_RESET		1
#define PCIE_NORMAL_RESET		0
@@ -81,26 +80,19 @@ enum pcie_data_rate {
struct meson_pcie_mem_res {
	void __iomem *elbi_base;
	void __iomem *cfg_base;
	void __iomem *phy_base;
};

struct meson_pcie_clk_res {
	struct clk *clk;
	struct clk *mipi_gate;
	struct clk *port_clk;
	struct clk *general_clk;
};

struct meson_pcie_rc_reset {
	struct reset_control *phy;
	struct reset_control *port;
	struct reset_control *apb;
};

struct meson_pcie_param {
	bool has_shared_phy;
};

struct meson_pcie {
	struct dw_pcie pci;
	struct meson_pcie_mem_res mem_res;
@@ -108,7 +100,6 @@ struct meson_pcie {
	struct meson_pcie_rc_reset mrst;
	struct gpio_desc *reset_gpio;
	struct phy *phy;
	const struct meson_pcie_param *param;
};

static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp,
@@ -130,13 +121,6 @@ static int meson_pcie_get_resets(struct meson_pcie *mp)
{
	struct meson_pcie_rc_reset *mrst = &mp->mrst;

	if (!mp->param->has_shared_phy) {
		mrst->phy = meson_pcie_get_reset(mp, "phy", PCIE_SHARED_RESET);
		if (IS_ERR(mrst->phy))
			return PTR_ERR(mrst->phy);
		reset_control_deassert(mrst->phy);
	}

	mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET);
	if (IS_ERR(mrst->port))
		return PTR_ERR(mrst->port);
@@ -162,22 +146,6 @@ static void __iomem *meson_pcie_get_mem(struct platform_device *pdev,
	return devm_ioremap_resource(dev, res);
}

static void __iomem *meson_pcie_get_mem_shared(struct platform_device *pdev,
					       struct meson_pcie *mp,
					       const char *id)
{
	struct device *dev = mp->pci.dev;
	struct resource *res;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id);
	if (!res) {
		dev_err(dev, "No REG resource %s\n", id);
		return ERR_PTR(-ENXIO);
	}

	return devm_ioremap(dev, res->start, resource_size(res));
}

static int meson_pcie_get_mems(struct platform_device *pdev,
			       struct meson_pcie *mp)
{
@@ -189,14 +157,6 @@ static int meson_pcie_get_mems(struct platform_device *pdev,
	if (IS_ERR(mp->mem_res.cfg_base))
		return PTR_ERR(mp->mem_res.cfg_base);

	/* Meson AXG SoC has two PCI controllers use same phy register */
	if (!mp->param->has_shared_phy) {
		mp->mem_res.phy_base =
			meson_pcie_get_mem_shared(pdev, mp, "phy");
		if (IS_ERR(mp->mem_res.phy_base))
			return PTR_ERR(mp->mem_res.phy_base);
	}

	return 0;
}

@@ -204,7 +164,6 @@ static int meson_pcie_power_on(struct meson_pcie *mp)
{
	int ret = 0;

	if (mp->param->has_shared_phy) {
	ret = phy_init(mp->phy);
	if (ret)
		return ret;
@@ -214,27 +173,24 @@ static int meson_pcie_power_on(struct meson_pcie *mp)
		phy_exit(mp->phy);
		return ret;
	}
	} else
		writel(MESON_PCIE_PHY_POWERUP, mp->mem_res.phy_base);

	return 0;
}

static void meson_pcie_power_off(struct meson_pcie *mp)
{
	phy_power_off(mp->phy);
	phy_exit(mp->phy);
}

static int meson_pcie_reset(struct meson_pcie *mp)
{
	struct meson_pcie_rc_reset *mrst = &mp->mrst;
	int ret = 0;

	if (mp->param->has_shared_phy) {
	ret = phy_reset(mp->phy);
	if (ret)
		return ret;
	} else {
		reset_control_assert(mrst->phy);
		udelay(PCIE_RESET_DELAY);
		reset_control_deassert(mrst->phy);
		udelay(PCIE_RESET_DELAY);
	}

	reset_control_assert(mrst->port);
	reset_control_assert(mrst->apb);
@@ -286,12 +242,6 @@ static int meson_pcie_probe_clocks(struct meson_pcie *mp)
	if (IS_ERR(res->port_clk))
		return PTR_ERR(res->port_clk);

	if (!mp->param->has_shared_phy) {
		res->mipi_gate = meson_pcie_probe_clock(dev, "mipi", 0);
		if (IS_ERR(res->mipi_gate))
			return PTR_ERR(res->mipi_gate);
	}

	res->general_clk = meson_pcie_probe_clock(dev, "general", 0);
	if (IS_ERR(res->general_clk))
		return PTR_ERR(res->general_clk);
@@ -562,7 +512,6 @@ static const struct dw_pcie_ops dw_pcie_ops = {

static int meson_pcie_probe(struct platform_device *pdev)
{
	const struct meson_pcie_param *match_data;
	struct device *dev = &pdev->dev;
	struct dw_pcie *pci;
	struct meson_pcie *mp;
@@ -576,16 +525,9 @@ static int meson_pcie_probe(struct platform_device *pdev)
	pci->dev = dev;
	pci->ops = &dw_pcie_ops;

	match_data = of_device_get_match_data(dev);
	if (!match_data) {
		dev_err(dev, "failed to get match data\n");
		return -ENODEV;
	}
	mp->param = match_data;

	if (mp->param->has_shared_phy) {
	mp->phy = devm_phy_get(dev, "pcie");
		if (IS_ERR(mp->phy))
	if (IS_ERR(mp->phy)) {
		dev_err(dev, "get phy failed, %ld\n", PTR_ERR(mp->phy));
		return PTR_ERR(mp->phy);
	}

@@ -636,30 +578,16 @@ static int meson_pcie_probe(struct platform_device *pdev)
	return 0;

err_phy:
	if (mp->param->has_shared_phy) {
		phy_power_off(mp->phy);
		phy_exit(mp->phy);
	}

	meson_pcie_power_off(mp);
	return ret;
}

static struct meson_pcie_param meson_pcie_axg_param = {
	.has_shared_phy = false,
};

static struct meson_pcie_param meson_pcie_g12a_param = {
	.has_shared_phy = true,
};

static const struct of_device_id meson_pcie_of_match[] = {
	{
		.compatible = "amlogic,axg-pcie",
		.data = &meson_pcie_axg_param,
	},
	{
		.compatible = "amlogic,g12a-pcie",
		.data = &meson_pcie_g12a_param,
	},
	{},
};
+22 −0
Original line number Diff line number Diff line
@@ -59,3 +59,25 @@ config PHY_MESON_G12A_USB3_PCIE
	  Enable this to support the Meson USB3 + PCIE Combo PHY found
	  in Meson G12A SoCs.
	  If unsure, say N.

config PHY_MESON_AXG_PCIE
	tristate "Meson AXG PCIE PHY driver"
	default ARCH_MESON
	depends on OF && (ARCH_MESON || COMPILE_TEST)
	select GENERIC_PHY
	select REGMAP_MMIO
	help
	  Enable this to support the Meson MIPI + PCIE PHY found
	  in Meson AXG SoCs.
	  If unsure, say N.

config PHY_MESON_AXG_MIPI_PCIE_ANALOG
	tristate "Meson AXG MIPI + PCIE analog PHY driver"
	default ARCH_MESON
	depends on OF && (ARCH_MESON || COMPILE_TEST)
	select GENERIC_PHY
	select REGMAP_MMIO
	help
	  Enable this to support the Meson MIPI + PCIE analog PHY
	  found in Meson AXG SoCs.
	  If unsure, say N.
Loading