diff mbox

[PATCHv5,2/3] ARM: socfpga: dts: Add support for SD/MMC

Message ID 1377272686-13253-2-git-send-email-dinguyen@altera.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dinh Nguyen Aug. 23, 2013, 3:44 p.m. UTC
From: Dinh Nguyen <dinguyen@altera.com>

Add bindings for SD/MMC for SOCFPGA.

Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Seungwon Jeon <tgih.jun@samsung.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: devicetree@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org

v5:
- Add "altr,ciu-clk-offset" that represents the necessary offset
  and shift values in the sysmgr phandle. This is used to set
  the correct CIU clock values.

v4:
- Add a complete binding example in documentations
- Add a phandle entry for "altr,sysmgr" which links the system
  manager to the SD/MMC IP block that controls the SDR timings.
- Split up patches
        1/3 - Add syscon binding to sys-mgr node
        2/3 - DTS bindings and documentation for SD/MMC on SOCFPGA
        3/3 - Driver changes to use the bindings

v3:
- Explicitly reference synopsis-dw-mshc.txt for base bindings
- Remove "dw-mshc-ciu-div" as driver can get clock information dts "ciu" entry
- Fixed indentation issue

v2:
- Remove bus-width and extra line in documentation
- Merge bindings example into a single node in documentation
---
 .../devicetree/bindings/mmc/socfpga-dw-mshc.txt    |   63 ++++++++++++++++++++
 arch/arm/boot/dts/socfpga.dtsi                     |   11 ++++
 arch/arm/boot/dts/socfpga_cyclone5.dts             |   14 +++++
 arch/arm/boot/dts/socfpga_vt.dts                   |   14 +++++
 4 files changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt

Comments

Stephen Warren Aug. 23, 2013, 10:29 p.m. UTC | #1
On 08/23/2013 09:44 AM, dinguyen@altera.com wrote:
> From: Dinh Nguyen <dinguyen@altera.com>
> 
> Add bindings for SD/MMC for SOCFPGA.

> diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt

> +* altr,sysmgr: Should be the phandle to the system_mgr node. As this is where
> +		this where the register that controls the CIU clock phases
> +		reside.
> +
> +* altr,ciu-clk-offset: The order of the cells should be:
> +	- First Cell: Offset of the register in the system_mgr node that controls
> +		the smpsel bits.
> +	- Second Cell: Shift value of the drvsel bits.
> +	- Third Cell: Shift value of the smpsel bits.

This almost solves the issues I was thinking of. A few more thoughts though:

* What if the sysmgr node has multiple reg entries. Is the offset cell
in altr,ciu-clk-offset an offset from the first reg entry, or across all
reg entries? It might be better to specify this as a reg index plus
offset, or allow the sysmgr node to define the format (#sysmgr-cells
perhaps).

* What if the drvsel and smpsel bits are in different registers, even
different sysmgr blocks? Wouldn't it be better to have 2 separate
properties, each one defining the location of one bit-field?

* bikeshed: altr,ciu-clk-offset isn't a great name; the value is more
than just an offset.

Putting those together, I might expect the following properties:

sysmgr: sysmgr {
    /* binding for sysmgr node must specify what those 3 cells are */
    #sysmgr-cells = <3>;
}

dwmmc {
    altr,drvsel-reg-field = <
        &sysmgr /* sysmgr phandle */
        0 /* reg index */
        0 /* reg offset */
        0 /* field bit position */
        3 /* field bit size */>;
    altr,smpsel-reg-field = <
        &sysmgr /* sysmgr phandle */
        0 /* reg index */
        0 /* reg offset */
        3 /* field bit position */
        3 /* field bit size */>;
};

That would allow the whole sysmgr concept to be completely generic.

But, this is a bit like representing raw register I/O in DT, which has
been frowned upon in the past.

Finally, what if the values for drvsel, smpsel are different in
different sysmgr implementations? Do you need a property that defines
that values?

Another option might be to define a semantic API between the two, such
that you only need a sysmgr=<&sysmgr> property, yet the driver for the
sysmgr node exposes a function sysmgr_set_dwmmc_drvsel_smpsel(struct
device_node *sysmgr_node, uint drvsel, uint smpsel); Now, the sysmgr
driver would have to implement that on any SoC that supported a dwmmc.
Dinh Nguyen Aug. 23, 2013, 11:01 p.m. UTC | #2
On Fri, 2013-08-23 at 16:29 -0600, Stephen Warren wrote:
> On 08/23/2013 09:44 AM, dinguyen@altera.com wrote:
> > From: Dinh Nguyen <dinguyen@altera.com>
> > 
> > Add bindings for SD/MMC for SOCFPGA.
> 
> > diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
> 
> > +* altr,sysmgr: Should be the phandle to the system_mgr node. As this is where
> > +		this where the register that controls the CIU clock phases
> > +		reside.
> > +
> > +* altr,ciu-clk-offset: The order of the cells should be:
> > +	- First Cell: Offset of the register in the system_mgr node that controls
> > +		the smpsel bits.
> > +	- Second Cell: Shift value of the drvsel bits.
> > +	- Third Cell: Shift value of the smpsel bits.
> 
> This almost solves the issues I was thinking of. A few more thoughts though:
> 
> * What if the sysmgr node has multiple reg entries. Is the offset cell
> in altr,ciu-clk-offset an offset from the first reg entry, or across all
> reg entries? It might be better to specify this as a reg index plus
> offset, or allow the sysmgr node to define the format (#sysmgr-cells
> perhaps).
> 
> * What if the drvsel and smpsel bits are in different registers, even
> different sysmgr blocks? Wouldn't it be better to have 2 separate
> properties, each one defining the location of one bit-field?
> 
> * bikeshed: altr,ciu-clk-offset isn't a great name; the value is more
> than just an offset.
> 
> Putting those together, I might expect the following properties:
> 
> sysmgr: sysmgr {
>     /* binding for sysmgr node must specify what those 3 cells are */
>     #sysmgr-cells = <3>;
> }
> 
> dwmmc {
>     altr,drvsel-reg-field = <
>         &sysmgr /* sysmgr phandle */
>         0 /* reg index */
>         0 /* reg offset */
>         0 /* field bit position */
>         3 /* field bit size */>;
>     altr,smpsel-reg-field = <
>         &sysmgr /* sysmgr phandle */
>         0 /* reg index */
>         0 /* reg offset */
>         3 /* field bit position */
>         3 /* field bit size */>;
> };
> 
> That would allow the whole sysmgr concept to be completely generic.
> 
> But, this is a bit like representing raw register I/O in DT, which has
> been frowned upon in the past.
> 
> Finally, what if the values for drvsel, smpsel are different in
> different sysmgr implementations? Do you need a property that defines
> that values?
> 
> Another option might be to define a semantic API between the two, such
> that you only need a sysmgr=<&sysmgr> property, yet the driver for the
> sysmgr node exposes a function sysmgr_set_dwmmc_drvsel_smpsel(struct
> device_node *sysmgr_node, uint drvsel, uint smpsel); Now, the sysmgr
> driver would have to implement that on any SoC that supported a dwmmc.

I was trying to avoid adding a driver for the sysmgr, as it really does
not represent any type of device. It is a merely a register region with
miscellaneous registers that controls other IPs in the SOC.

I'm thinking perhaps I can set this register in the arch specific file,
then the SD/MMC driver would not need to bother with it at all?

Thanks,
Dinh
> 
>
Stephen Warren Aug. 26, 2013, 4:44 p.m. UTC | #3
On 08/23/2013 05:01 PM, Dinh Nguyen wrote:
> On Fri, 2013-08-23 at 16:29 -0600, Stephen Warren wrote:
>> On 08/23/2013 09:44 AM, dinguyen@altera.com wrote:
>>> From: Dinh Nguyen <dinguyen@altera.com>
>>>
>>> Add bindings for SD/MMC for SOCFPGA.
>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
>>
>>> +* altr,sysmgr: Should be the phandle to the system_mgr node. As this is where
>>> +		this where the register that controls the CIU clock phases
>>> +		reside.
>>> +
>>> +* altr,ciu-clk-offset: The order of the cells should be:
>>> +	- First Cell: Offset of the register in the system_mgr node that controls
>>> +		the smpsel bits.
>>> +	- Second Cell: Shift value of the drvsel bits.
>>> +	- Third Cell: Shift value of the smpsel bits.
>>
>> This almost solves the issues I was thinking of. A few more thoughts though:
>>
>> * What if the sysmgr node has multiple reg entries. Is the offset cell
>> in altr,ciu-clk-offset an offset from the first reg entry, or across all
>> reg entries? It might be better to specify this as a reg index plus
>> offset, or allow the sysmgr node to define the format (#sysmgr-cells
>> perhaps).
>>
>> * What if the drvsel and smpsel bits are in different registers, even
>> different sysmgr blocks? Wouldn't it be better to have 2 separate
>> properties, each one defining the location of one bit-field?
>>
>> * bikeshed: altr,ciu-clk-offset isn't a great name; the value is more
>> than just an offset.
>>
>> Putting those together, I might expect the following properties:
>>
>> sysmgr: sysmgr {
>>     /* binding for sysmgr node must specify what those 3 cells are */
>>     #sysmgr-cells = <3>;
>> }
>>
>> dwmmc {
>>     altr,drvsel-reg-field = <
>>         &sysmgr /* sysmgr phandle */
>>         0 /* reg index */
>>         0 /* reg offset */
>>         0 /* field bit position */
>>         3 /* field bit size */>;
>>     altr,smpsel-reg-field = <
>>         &sysmgr /* sysmgr phandle */
>>         0 /* reg index */
>>         0 /* reg offset */
>>         3 /* field bit position */
>>         3 /* field bit size */>;
>> };
>>
>> That would allow the whole sysmgr concept to be completely generic.
>>
>> But, this is a bit like representing raw register I/O in DT, which has
>> been frowned upon in the past.
>>
>> Finally, what if the values for drvsel, smpsel are different in
>> different sysmgr implementations? Do you need a property that defines
>> that values?
>>
>> Another option might be to define a semantic API between the two, such
>> that you only need a sysmgr=<&sysmgr> property, yet the driver for the
>> sysmgr node exposes a function sysmgr_set_dwmmc_drvsel_smpsel(struct
>> device_node *sysmgr_node, uint drvsel, uint smpsel); Now, the sysmgr
>> driver would have to implement that on any SoC that supported a dwmmc.
> 
> I was trying to avoid adding a driver for the sysmgr, as it really does
> not represent any type of device. It is a merely a register region with
> miscellaneous registers that controls other IPs in the SOC.
> 
> I'm thinking perhaps I can set this register in the arch specific file,
> then the SD/MMC driver would not need to bother with it at all?

The problem with hard-coding this in the MMC driver is that it makes the
MMC driver depend on information outside the MMC HW block. If you do
that, you may as well just write the "syscon" registers directly in the
MMC driver.
Steffen Trumtrar Aug. 27, 2013, 3:31 p.m. UTC | #4
Hi!

On Fri, Aug 23, 2013 at 10:44:45AM -0500, dinguyen@altera.com wrote:
> From: Dinh Nguyen <dinguyen@altera.com>
> 
> Add bindings for SD/MMC for SOCFPGA.
> 
> Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: Seungwon Jeon <tgih.jun@samsung.com>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-mmc@vger.kernel.org
> CC: linux-arm-kernel@lists.infradead.org
> 
> v5:
> - Add "altr,ciu-clk-offset" that represents the necessary offset
>   and shift values in the sysmgr phandle. This is used to set
>   the correct CIU clock values.
> 
> v4:
> - Add a complete binding example in documentations
> - Add a phandle entry for "altr,sysmgr" which links the system
>   manager to the SD/MMC IP block that controls the SDR timings.
> - Split up patches
>         1/3 - Add syscon binding to sys-mgr node
>         2/3 - DTS bindings and documentation for SD/MMC on SOCFPGA
>         3/3 - Driver changes to use the bindings
> 
> v3:
> - Explicitly reference synopsis-dw-mshc.txt for base bindings
> - Remove "dw-mshc-ciu-div" as driver can get clock information dts "ciu" entry
> - Fixed indentation issue
> 
> v2:
> - Remove bus-width and extra line in documentation
> - Merge bindings example into a single node in documentation
> ---

You should put your changelogs here and not above the ---
AFAIK nobody cares for the development history of a patch once it is applied.

>  .../devicetree/bindings/mmc/socfpga-dw-mshc.txt    |   63 ++++++++++++++++++++
>  arch/arm/boot/dts/socfpga.dtsi                     |   11 ++++
>  arch/arm/boot/dts/socfpga_cyclone5.dts             |   14 +++++
>  arch/arm/boot/dts/socfpga_vt.dts                   |   14 +++++
>  4 files changed, 102 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
> 

Regards,
Steffen
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
new file mode 100644
index 0000000..70893a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
@@ -0,0 +1,63 @@ 
+* Altera SOCFPGA specific extensions to the Synopsis Designware Mobile
+  Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsis dw mshc controller properties described
+by synopsis-dw-mshc.txt and the properties used by the SOCFPGA specific
+extensions to the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+	- "altr,socfpga-dw-mshc": for controllers with Altera SOCFPGA
+	  specific extensions.
+
+* altr,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value
+  in transmit mode and CIU clock phase shift value in receive mode for single
+  data rate mode operation. Refer to notes below for the order of the cells and the
+  valid values.
+
+  Notes for the sdr-timing values:
+
+    The order of the cells should be
+      - First Cell: CIU clock phase shift value for RX mode, smplsel bits in
+	the system manager SDMMC control group.
+      - Second Cell: CIU clock phase shift value for TX mode, drvsel bits in
+	the system manager SDMMC control group.
+
+    Valid values for SDR CIU clock timing for SOCFPGA:
+      - valid value for tx phase shift and rx phase shift is 0 to 7.
+
+* altr,sysmgr: Should be the phandle to the system_mgr node. As this is where
+		this where the register that controls the CIU clock phases
+		reside.
+
+* altr,ciu-clk-offset: The order of the cells should be:
+	- First Cell: Offset of the register in the system_mgr node that controls
+		the smpsel bits.
+	- Second Cell: Shift value of the drvsel bits.
+	- Third Cell: Shift value of the smpsel bits.
+
+Example:
+	dwmmc0@ff704000 {
+		compatible = "altr,socfpga-dw-mshc", "snps,dw-mshc";
+		reg = <0xff704000 0x1000>;
+		interrupts = <0 139 4>;
+		fifo-depth = <0x400>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clocks = <&l4_mp_clk>, <&sdmmc_clk>;
+		clock-names = "biu", "ciu";
+		num-slots = <1>;
+		supports-highspeed;
+		broken-cd;
+		altr,sysmgr = <&system_mgr>;
+		altr,ciu-clk-offset = <0x108 0 3>;
+		altr,dw-mshc-sdr-timing = <0 3>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <4>;
+		};
+	};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index c31c8e9..9706767 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -468,6 +468,17 @@ 
 			cache-level = <2>;
 		};
 
+		mmc: dwmmc0@ff704000 {
+			compatible = "altr,socfpga-dw-mshc";
+			reg = <0xff704000 0x1000>;
+			interrupts = <0 139 4>;
+			fifo-depth = <0x400>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&l4_mp_clk>, <&sdmmc_clk>;
+			clock-names = "biu", "ciu";
+		};
+
 		/* Local timer */
 		timer@fffec600 {
 			compatible = "arm,cortex-a9-twd-timer";
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
index 973999d..c5861b1 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dts
@@ -54,6 +54,20 @@ 
 			status = "okay";
 		};
 
+		dwmmc0@ff704000 {
+			num-slots = <1>;
+			supports-highspeed;
+			broken-cd;
+			altr,sysmgr = <&system_mgr>;
+			altr,ciu-clk-offset = <0x108 0 3>;
+			altr,dw-mshc-sdr-timing = <0 3>;
+
+			slot@0 {
+				reg = <0>;
+				bus-width = <4>;
+			};
+		};
+
 		timer0@ffc08000 {
 			clock-frequency = <100000000>;
 		};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
index d1ec0ca..250991c 100644
--- a/arch/arm/boot/dts/socfpga_vt.dts
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -46,6 +46,20 @@ 
 			status = "okay";
 		};
 
+		dwmmc0@ff704000 {
+			num-slots = <1>;
+			supports-highspeed;
+			broken-cd;
+			altr,sysmgr = <&system_mgr>;
+			altr,ciu-clk-offset = <0x108 0 3>;
+			altr,dw-mshc-sdr-timing = <0 3>;
+
+			slot@0 {
+				reg = <0>;
+				bus-width = <4>;
+			};
+		};
+
 		timer0@ffc08000 {
 			clock-frequency = <7000000>;
 		};