[PATCH] pcie: qcom: add support to msm8996 PCIE controller

Srinivas Kandagatla srinivas.kandagatla at linaro.org
Wed Sep 7 05:53:11 PDT 2016


Thanks for the comments,

On 07/09/16 12:57, Robin Murphy wrote:
> On 07/09/16 12:06, Srinivas Kandagatla wrote:
>> This patch adds support to msm8996/apq8096 pcie, MSM8996 supports
>> Gen 1/2, One lane, 3 pcie root-complex with support to MSI and
>> legacy interrupts and it conforms to PCI Express Base 2.1 specification.
>>
>> This patch adds post_init callback to qcom_pcie_ops, as this is pcie
>> pipe clocks and smmu configuration are only setup after the phy is
>> powered on. It also adds ltssm_enable callback as it is very much
>> different to other supported SOCs in the driver.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
>> ---
>>
>> I tested this patch along with phy driver patch on DB820c based on
>> APQ8096 on port A and port B using sata and ethernet controllers.
>>
>> Thanks
>> srini
>>
>>  .../devicetree/bindings/pci/qcom,pcie.txt          |  88 +++++++-
>>  drivers/pci/host/pcie-qcom.c                       | 237 ++++++++++++++++++++-
>>  2 files changed, 318 insertions(+), 7 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
>> index 4059a6f..1ddfcb4 100644
>> --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
>> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
>> @@ -92,6 +92,18 @@
>>  			- "aux"		Auxiliary (AUX) clock
>>  			- "bus_master"	Master AXI clock
>>  			- "bus_slave"	Slave AXI clock
>> +
>> +- clock-names:
>> +	Usage: required for msm8996/apq8096
>> +	Value type: <stringlist>
>> +	Definition: Should contain the following entries
>> +			- "aux"		Auxiliary (AUX) clock
>> +			- "bus_master"	Master AXI clock
>> +			- "bus_slave"	Slave AXI clock
>> +			- "pipe"	Pipe Clock driving internal logic.
>> +			- "cfg"		Configuration clk.
>> +			- "snoc_axi"	SNOC AXI clk
>> +			- "cnoc_ahb"	CNOC AHB clk
>>  - resets:
>>  	Usage: required
>>  	Value type: <prop-encoded-array>
>> @@ -114,8 +126,15 @@
>>  	Definition: Should contain the following entries
>>  			- "core" Core reset
>>
>> +- iommus:
>> +	Usage: required for msm8996/apq8096
>> +	Value type: <prop-encoded-array>
>> +	Definition: Should point to the respective IOMMU block with master port
>> +		    as argument, see Documentation/devicetree/bindings/iommu/
>> +		    mediatek,iommu.txt for details.
>
> Qualcomm have cross-licensed the M4U!? :P
Oops...Copy paste error!!
This is supposed to be Documentation/devicetree/bindings/iommu/arm,smmu.txt

>
> In seriousness, though, it seems a bit odd to list "iommus" as a
> required property - unless the IOMMU is actually an integral part of the
> PCIe root complex being described (in which case it wants its own
> binding documenting as well), then the relationship is merely a
> circumstance of integration of those particular SoCs.
>
>> +
>>  - power-domains:
>> -	Usage: required for apq8084
>> +	Usage: required for apq8084 and msm8996/apq8096
>>  	Value type: <prop-encoded-array>
>>  	Definition: A phandle and power domain specifier pair to the
>>  		    power domain which is responsible for collapsing
>> @@ -137,6 +156,11 @@
>>  	Definition: A phandle to the analog power supply for IC which generates
>>  		    reference clock
>>
>> +- vdda_1p8-supply:
>> +	Usage: required for msm8996/apq8096
>> +	Value type: <phandle>
>> +	Definition: A phandle to the analog power supply for PCIE_1P8
>> +
>>  - phys:
>>  	Usage: required for apq8084
>>  	Value type: <phandle>
>> @@ -231,3 +255,65 @@
>>  		pinctrl-0 = <&pcie0_pins_default>;
>>  		pinctrl-names = "default";
>>  	};
>> +
>> +* Example for apq8096:
>> +	pcie1: qcom,pcie at 00608000 {
>> +		compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
>> +		power-domains = <&gcc PCIE1_GDSC>;
>> +		bus-range = <0x00 0xff>;
>> +		num-lanes = <1>;
>> +
>> +		status  = "disabled";
>> +
>> +		reg = <0x00608000 0x2000>,
>> +		      <0x0d000000 0xf1d>,
>> +		      <0x0d000f20 0xa8>,
>> +		      <0x0d100000 0x100000>;
>> +
>> +		reg-names = "parf", "dbi", "elbi","config";
>> +
>> +		phys = <&pcie_phy 1>;
>> +		phy-names = "pciephy";
>> +
>> +		#address-cells = <3>;
>> +		#size-cells = <2>;
>> +		ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>,
>> +			<0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
>> +
>> +		interrupts = <GIC_SPI 413 IRQ_TYPE_NONE>;
>> +		interrupt-names = "msi";
>> +		#interrupt-cells = <1>;
>> +		interrupt-map-mask = <0 0 0 0x7>;
>> +		interrupt-map = <0 0 0 1 &intc 0 272 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
>> +				<0 0 0 2 &intc 0 273 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
>> +				<0 0 0 3 &intc 0 274 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
>> +				<0 0 0 4 &intc 0 275 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
>> +
>> +		pinctrl-names = "default", "sleep";
>> +		pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>;
>> +		pinctrl-1 = <&pcie1_clkreq_sleep &pcie1_perst_default &pcie1_wake_sleep>;
>> +
>> +
>> +		vreg-1.8-supply = <&pm8994_l12>;
>> +		vreg-0.9-supply = <&pm8994_l28>;
>> +		iommus = <&anoc0_smmu>;
>
> Furthermore, the exact meaning of "iommus" is defined by the relevant
> IOMMU's binding itself - at face value here, you're missing the LARB
> port number :P - but more generally a bare phandle with no arguments for
> something as busy as a root complex smells a bit off.

This is arm smmu v2, the smmu instance in this case had #iommu-cells = 
<0>, so no arguments were not used. However I will dig in more details 
on why this smmu instance does not accept arguments/stream-ids.

>
>> +
>> +		linux,pci-domain = <1>;
>> +
>> +		clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
>> +			<&gcc GCC_PCIE_1_AUX_CLK>,
>> +			<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
>> +			<&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
>> +			<&gcc GCC_PCIE_1_SLV_AXI_CLK>,
>> +			<&gcc GCC_AGGRE0_SNOC_AXI_CLK>,
>> +			<&gcc GCC_AGGRE0_CNOC_AHB_CLK>;
>> +
>> +		clock-names =  "pipe",
>> +				"aux",
>> +				"cfg",
>> +				"bus_master",
>> +				"bus_slave",
>> +				"snoc_axi",
>> +				"cnoc_ahb";
>> +
>> +	};
>> diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
>> index f2f90c5..7748c11 100644
>> --- a/drivers/pci/host/pcie-qcom.c
>> +++ b/drivers/pci/host/pcie-qcom.c
> [...]
>> +static int qcom_pcie_post_init_msm8996(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_msm8996 *res = &pcie->res.msm8996;
>> +	struct device *dev = pcie->dev;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(res->pipe_clk);
>> +	if (ret) {
>> +		dev_err(dev, "cannot prepare/enable pipe clock\n");
>> +		return ret;
>> +	}
>> +	/* SMMU specific registers */
>> +	writel(0, pcie->parf + PCIE20_PARF_BDF_TRANSLATE_CFG);
>> +	writel(0, pcie->parf +	PCIE20_PARF_SID_OFFSET);
>
> Ah, so it's another of these RID->SID lookup-table-type things. That
> would be more appropriately described with "iommu-map"[1], particularly
> if you want things to actually work as expected[2]. There is of course a
> fun circular dependency there in that the DT becomes more of a promise
> than an actual description of the hardware state, since the latter
> doesn't necessarily exist until the driver programs it here. It might
> ultimately be cleaner to have the firmware program this and repaint the
> DT accordingly, so that things do look fixed from Linux's perspective.

Thanks for the hints, I will read thru the thread and give it a try.

--srini

>
> Robin.
>
> [1]:http://www.mail-archive.com/iommu@lists.linux-foundation.org/msg14165.html
> [2]:http://www.mail-archive.com/iommu@lists.linux-foundation.org/msg14162.html
>



More information about the linux-arm-kernel mailing list