Commit 9195e6dd authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/ctrl/qcom'

- Add PHY clock source implementation (Dmitry Baryshkov)

- Use new clk_regmap_phy_mux_ops for gcc-sm8450 and gcc-sc7280 PCIe pipe
  clocks (Dmitry Baryshkov)

- Set up rev 2.1.0 PARF_PHY before enabling clocks (Christian Marangi)

- Power on PHY before accessing IPQ8074 DBI registers to avoid boot hangs
  (Robert Marko)

- Power on PHY before accessing DBI registers on all variants for
  consistency (Robert Marko)

- Remove unnecessary pipe_clk handling since this is done in PHY drivers
  (Dmitry Baryshkov)

- Drop manual pipe_clk_src handling (Dmitry Baryshkov)

- Move GEN3_RELATED DBI definitions to common dwc header (Baruch Siach)

- Define slot capabilities using generic PCI_EXP_SLTCAP_* macros (Baruch
  Siach)

- Add IPQ60xx support (Selvam Sathappan Periakaruppan)

- Fix DT description typo (Baruch Siach)

- Fix DT "compatibles" typo (Johan Hovold)

- Allow ASPM L1 and substates for 2.7.0 (Krishna chaitanya chundru)

* pci/ctrl/qcom:
  PCI: qcom: Allow ASPM L1 and substates for 2.7.0
  dt-bindings: PCI: qcom: Fix reset conditional
  dt-bindings: PCI: qcom: Fix description typo
  PCI: qcom: Add IPQ60xx support
  PCI: qcom: Define slot capabilities using PCI_EXP_SLTCAP_*
  PCI: dwc: Move GEN3_RELATED DBI definitions to common header
  PCI: qcom: Drop manual pipe_clk_src handling
  PCI: qcom: Remove unnecessary pipe_clk handling
  PCI: qcom: Power on PHY before DBI register accesses
  PCI: qcom: Power on PHY before IPQ8074 DBI register accesses
  PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
  clk: qcom: gcc-sc7280: use new clk_regmap_phy_mux_ops for PCIe pipe clocks
  clk: qcom: gcc-sm8450: use new clk_regmap_phy_mux_ops for PCIe pipe clocks
  clk: qcom: regmap: add PHY clock source implementation
parents 4faef108 5147ba8a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ maintainers:
  - Stanimir Varbanov <svarbanov@mm-sol.com>

description: |
  Qualcomm PCIe root complex controller is bansed on the Synopsys DesignWare
  Qualcomm PCIe root complex controller is based on the Synopsys DesignWare
  PCIe IP.

properties:
@@ -615,7 +615,7 @@ allOf:
  - if:
      not:
        properties:
          compatibles:
          compatible:
            contains:
              enum:
                - qcom,pcie-msm8996
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
clk-qcom-y += clk-regmap-mux-div.o
clk-qcom-y += clk-regmap-phy-mux.o
clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
clk-qcom-y += clk-hfpll.o
clk-qcom-y += reset.o
+62 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022, Linaro Ltd.
 */

#include <linux/clk-provider.h>
#include <linux/bitfield.h>
#include <linux/regmap.h>
#include <linux/export.h>

#include "clk-regmap.h"
#include "clk-regmap-phy-mux.h"

#define PHY_MUX_MASK		GENMASK(1, 0)
#define PHY_MUX_PHY_SRC		0
#define PHY_MUX_REF_SRC		2

static inline struct clk_regmap_phy_mux *to_clk_regmap_phy_mux(struct clk_regmap *clkr)
{
	return container_of(clkr, struct clk_regmap_phy_mux, clkr);
}

static int phy_mux_is_enabled(struct clk_hw *hw)
{
	struct clk_regmap *clkr = to_clk_regmap(hw);
	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);
	unsigned int val;

	regmap_read(clkr->regmap, phy_mux->reg, &val);
	val = FIELD_GET(PHY_MUX_MASK, val);

	WARN_ON(val != PHY_MUX_PHY_SRC && val != PHY_MUX_REF_SRC);

	return val == PHY_MUX_PHY_SRC;
}

static int phy_mux_enable(struct clk_hw *hw)
{
	struct clk_regmap *clkr = to_clk_regmap(hw);
	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);

	return regmap_update_bits(clkr->regmap, phy_mux->reg,
				  PHY_MUX_MASK,
				  FIELD_PREP(PHY_MUX_MASK, PHY_MUX_PHY_SRC));
}

static void phy_mux_disable(struct clk_hw *hw)
{
	struct clk_regmap *clkr = to_clk_regmap(hw);
	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);

	regmap_update_bits(clkr->regmap, phy_mux->reg,
			   PHY_MUX_MASK,
			   FIELD_PREP(PHY_MUX_MASK, PHY_MUX_REF_SRC));
}

const struct clk_ops clk_regmap_phy_mux_ops = {
	.enable = phy_mux_enable,
	.disable = phy_mux_disable,
	.is_enabled = phy_mux_is_enabled,
};
EXPORT_SYMBOL_GPL(clk_regmap_phy_mux_ops);
+33 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022, Linaro Ltd.
 */

#ifndef __QCOM_CLK_REGMAP_PHY_MUX_H__
#define __QCOM_CLK_REGMAP_PHY_MUX_H__

#include "clk-regmap.h"

/*
 * A clock implementation for PHY pipe and symbols clock muxes.
 *
 * If the clock is running off the from-PHY source, report it as enabled.
 * Report it as disabled otherwise (if it uses reference source).
 *
 * This way the PHY will disable the pipe clock before turning off the GDSC,
 * which in turn would lead to disabling corresponding pipe_clk_src (and thus
 * it being parked to a safe, reference clock source). And vice versa, after
 * enabling the GDSC the PHY will enable the pipe clock, which would cause
 * pipe_clk_src to be switched from a safe source to the working one.
 *
 * For some platforms this should be used for the UFS symbol_clk_src clocks
 * too.
 */
struct clk_regmap_phy_mux {
	u32			reg;
	struct clk_regmap	clkr;
};

extern const struct clk_ops clk_regmap_phy_mux_ops;

#endif
+15 −34
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "clk-rcg.h"
#include "clk-regmap-divider.h"
#include "clk-regmap-mux.h"
#include "clk-regmap-phy-mux.h"
#include "common.h"
#include "gdsc.h"
#include "reset.h"
@@ -255,26 +256,6 @@ static const struct clk_parent_data gcc_parent_data_5[] = {
	{ .hw = &gcc_gpll0_out_even.clkr.hw },
};

static const struct parent_map gcc_parent_map_6[] = {
	{ P_PCIE_0_PIPE_CLK, 0 },
	{ P_BI_TCXO, 2 },
};

static const struct clk_parent_data gcc_parent_data_6[] = {
	{ .fw_name = "pcie_0_pipe_clk", .name = "pcie_0_pipe_clk" },
	{ .fw_name = "bi_tcxo" },
};

static const struct parent_map gcc_parent_map_7[] = {
	{ P_PCIE_1_PIPE_CLK, 0 },
	{ P_BI_TCXO, 2 },
};

static const struct clk_parent_data gcc_parent_data_7[] = {
	{ .fw_name = "pcie_1_pipe_clk", .name = "pcie_1_pipe_clk" },
	{ .fw_name = "bi_tcxo" },
};

static const struct parent_map gcc_parent_map_8[] = {
	{ P_BI_TCXO, 0 },
	{ P_GCC_GPLL0_OUT_MAIN, 1 },
@@ -369,32 +350,32 @@ static const struct clk_parent_data gcc_parent_data_15[] = {
	{ .hw = &gcc_mss_gpll0_main_div_clk_src.clkr.hw },
};

static struct clk_regmap_mux gcc_pcie_0_pipe_clk_src = {
static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = {
	.reg = 0x6b054,
	.shift = 0,
	.width = 2,
	.parent_map = gcc_parent_map_6,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "gcc_pcie_0_pipe_clk_src",
			.parent_data = gcc_parent_data_6,
			.num_parents = ARRAY_SIZE(gcc_parent_data_6),
			.ops = &clk_regmap_mux_closest_ops,
			.parent_data = &(const struct clk_parent_data){
				.fw_name = "pcie_0_pipe_clk",
				.name = "pcie_0_pipe_clk",
			},
			.num_parents = 1,
			.ops = &clk_regmap_phy_mux_ops,
		},
	},
};

static struct clk_regmap_mux gcc_pcie_1_pipe_clk_src = {
static struct clk_regmap_phy_mux gcc_pcie_1_pipe_clk_src = {
	.reg = 0x8d054,
	.shift = 0,
	.width = 2,
	.parent_map = gcc_parent_map_7,
	.clkr = {
		.hw.init = &(struct clk_init_data){
			.name = "gcc_pcie_1_pipe_clk_src",
			.parent_data = gcc_parent_data_7,
			.num_parents = ARRAY_SIZE(gcc_parent_data_7),
			.ops = &clk_regmap_mux_closest_ops,
			.parent_data = &(const struct clk_parent_data){
				.fw_name = "pcie_1_pipe_clk",
				.name = "pcie_1_pipe_clk",
			},
			.num_parents = 1,
			.ops = &clk_regmap_phy_mux_ops,
		},
	},
};
Loading