ata: Add APM X-Gene SoC AHCI SATA host controller support
Subsystems (3)
v17 cover ata: Add APM X-Gene SoC AHCI SATA host controller support
This patch adds support for the APM X-Gene SoC AHCI SATA host controller. In order for the host controller to work, the corresponding PHY driver musts also be available. Currently, only Gen3 disk is supported with this initial version.
v17:
* Add comment on no support for PM currently
* Add xgene_ahci_host_stop function to support stopping the controller
* Remove call to phy_exit as not necessary with new ahci_platform code
v16:
* Rebase to libata-for-3.15
* Pull in the PHY DTS patch as the host controller DTS patch depends on it
v15:
* Rebase to libata next branch
* Remove field plat_data and PHY from context structure
* Fix comment on function xgene_ahci_read_id as well as using bit mask to clear DEVSLP bit
* Remove function xgene_ahci_force_phy_rdy and xgene_ahci_phy_restart as not required since Gen1/Gen2 support remove for this initial version
* Update function xgene_ahci_do_hardreset comment
* Remove Gen1/Gen2 support from function xgene_ahci_do_hardreset
* Change int to u32 for variable portcmd_saved in function xgene_ahci_hardreset
* Change variable hplat_data to ctx in function xgene_ahci_probe
* Remove PHY call and using ahci_platform_enable_resource instead
* Add ahci_patlform_remove_one to driver function .remove
* Change phy-name to "sata-phy"
v14:
* Remove the shutdown already check and replace the while loop check with msleep in function xgene_ahci_init_memram
v13:
* Add fully-winged style comment for function xgene_ahci_read_id and xgene_ahci_do_hardrest
* Minor comments update for function xgene_ahci_read_id, xgene_ahci_do_hardrest, and xgene_ahci_hardreset
* NOTE: There is no functional code change.
v12:
* Remove function xgene_ahci_get_channel and use the ata_port field port_no
* Update comment for function xgene_ahci_read_id to function comment style '/**'
* Update comment for multiple lines to fully-winged style
v11:
* Drop the export functions requirement with libachi
* Change CONFIG_SATA_XGENE to CONFIG_AHCI_XGENE
* Rename file sata_xgene.c to ahci_xgene.c
* Convert to use Hans De Geode version 5 ahci_platform code re-factor changes to reduce code duplication. For extra context, use plat_data to store our context. The probe function follows the ahci_sunxi implementation. A number of code fragments update to reflect this change.
* Update comment for function xgene_ahci_read_id
* Minor code move around in function xgene_ahci_do_hardreset and use ATA_BUSY instead 0x80
* Fix hardreset to use start_engine function pointer as required due to newer kernel rebased
* Fix the set DMA mask for 32-bit as well
v10:
* Update binding documentation
v9:
* Remove ACPI/EFI include files
* Remove the IO flush support, interrupt routine, and DTS resources
* Remove function xgene_rd, xgene_wr, and xgene_wr_flush
* Remove PMP support (function xgene_ahci_qc_issue, xgene_ahci_qc_prep, xgene_ahci_qc_fill_rtf, xgene_ahci_softreset, and xgene_ahci_do_softreset)
* Rename function xgene_ahci_enable_phy to xgene_ahci_force_phy_rdy
* Clean up hardreset functions
* Require v7 of the PHY driver
v8:
* Remove _ADDR from defines
* Remove define MSTAWAUX_COHERENT_BYPASS_SET and STARAUX_COHERENT_BYPASS_SET and use direct coding
* Remove the un-necessary check for DTS boot with built in ACPI table
* Switch to use dma_set_mask_and_coherent for setting DMA mask
* Remove ACPI table matching code
* Update clock-names for sata01clk, sata23clk, and sata45clk
v7:
* Update the clock code by toggle the clock
* Update the DTS clock mask values due to the clock spilt between host and v5 of the PHY drivers
v6:
* Update binding documentation
* Change select PHY_XGENE_SATA to PHY_XGENE
* Add ULL to constants
* Change indentation and comments
* Clean up the probe functions a bit more
* Remove xgene_ahci_remove function
* Add the flush register to DTS
* Remove the interrupt-parent from DTS
v5:
* Sync up to v3 of the PHY driver
* Remove MSLIM wrapper functions
* Change the memory shutdown loop to use usleep_range
* Use devm_ioremap_resource instead devm_ioremap
* Remove suspend/resume functions as not needed
v4:
* Remove the ID property in DT
* Remove the temporary PHY direct function call and use PHY function
* Change printk to pr_debug
* Move the IOB flush addresses into the DT
* Remove the parameters retrieval function as no longer needed
* Remove the header file as no longer needed
* Require v2 patch of the SATA PHY driver. Require slightly modification in the Kconfig as it is moved to folder driver/phy and use Kconfig PHY_XGENE_SATA instead SATA_XGENE_PHY.
v3:
* Move out the SATA PHY to another driver
* Remove the clock-cells entry from DTS
* Remove debug wrapper
* Remove delay functions wrapper
* Clean up resource and IRQ query
* Remove query clock name
* Switch to use dma_set_mask/dma_coherent_mask
* Remove un-necessary devm_kfree
* Update GPL license header to v2
* Spilt up function xgene_ahci_hardreset
* Spilt up function xgene_ahci_probe
* Remove all reference of CONFIG_ARCH_MSLIM
* Clean up chip revision code
v2:
* Clean up file sata_xgene.c with Lindent and etc
* Clean up file sata_xgene_serdes.c with Lindent and etc
* Add description to each patch
v1:
* inital version
---
Loc Ho (4):
arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries
Documentation: Add documentation for the APM X-Gene SoC SATA host
controller DTS binding
ata: Add APM X-Gene SoC AHCI SATA host controller driver
arm64: Add APM X-Gene SoC AHCI SATA host controller DTS entries
.../devicetree/bindings/ata/apm-xgene.txt | 70 +++ arch/arm64/boot/dts/apm-storm.dtsi | 150 ++++++ drivers/ata/Kconfig | 7 + drivers/ata/Makefile | 1 + drivers/ata/ahci_xgene.c | 497 ++++++++++++++++++++ 5 files changed, 725 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/ata/apm-xgene.txt create mode 100644 drivers/ata/ahci_xgene.c
PATCH v17 1/4 arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries
This patch adds the DTS entries for the APM X-Gene SoC 15Gbps Multi-purpose PHY driver. The PHY for SATA controller 2 and 3 are enabled by default.
--- arch/arm64/boot/dts/apm-storm.dtsi | 75 ++++++++++++++++++++++++++++++++++++ 1 files changed, 75 insertions(+), 0 deletions(-)
arch/arm64/boot/dts/apm-storm.dtsi +75 -0
@@ -176,6 +176,51 @@ reg-names = "csr-reg"; clock-output-names = "eth8clk"; }; + + sataphy1clk: sataphy1clk at 1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy1clk"; + status = "disabled"; + csr-offset = <0x4>; + csr-mask = <0x00>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; + + sataphy2clk: sataphy1clk at 1f22c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f22c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy2clk"; + status = "ok"; + csr-offset = <0x4>; + csr-mask = <0x3a>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; + + sataphy3clk: sataphy1clk at 1f23c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f23c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy3clk"; + status = "ok"; + csr-offset = <0x4>; + csr-mask = <0x3a>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; }; serial0: serial at 1c020000 {
@@ -187,5 +232,35 @@ interrupt-parent = <&gic>; interrupts = <0x0 0x4c 0x4>; }; + + phy1: phy at 1f21a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f21a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy1clk 0>; + status = "disabled"; + apm,tx-boost-gain = <30 30 30 30 30 30>; + apm,tx-eye-tuning = <2 10 10 2 10 10>; + }; + + phy2: phy at 1f22a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f22a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy2clk 0>; + status = "ok"; + apm,tx-boost-gain = <30 30 30 30 30 30>; + apm,tx-eye-tuning = <1 10 10 2 10 10>; + }; + + phy3: phy at 1f23a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f23a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy3clk 0>; + status = "ok"; + apm,tx-boost-gain = <31 31 31 31 31 31>; + apm,tx-eye-tuning = <2 10 10 2 10 10>; + }; }; };
Signature · 1 line
1.5.5
PATCH v17 2/4 Documentation: Add documentation for the APM X-Gene SoC SATA host controller DTS binding
This patch adds documentation for the APM X-Gene SoC SATA host controller DTS binding.
--- .../devicetree/bindings/ata/apm-xgene.txt | 70 ++++++++++++++++++++ 1 files changed, 70 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/ata/apm-xgene.txt
Documentation/devicetree/bindings/ata/apm-xgene.txt new file +70 -0
@@ -0,0 +1,70 @@ +* APM X-Gene 6.0 Gb/s SATA host controller nodes + +SATA host controller nodes are defined to describe on-chip Serial ATA +controllers. Each SATA controller (pair of ports) have its own node. + +Required properties: +- compatible : Shall contain: + * "apm,xgene-ahci-sgmii" if mux'ed with SGMII + * "apm,xgene-ahci-pcie" if mux'ed with PCIe +- reg : First memory resource shall be the AHCI memory + resource. + Second memory resource shall be the host controller + memory resource. +- interrupts : Interrupt-specifier for SATA host controller IRQ. +- clocks : Reference to the clock entry. +- phys : A list of phandles + phy-specifiers, one for each + entry in phy-names. +- phy-names : Should contain: + * "sata-6g" for the SATA 6.0Gbps PHY + +Optional properties: +- status : Shall be "ok" if enabled or "disabled" if disabled. + Default is "ok". +- interrupt-parent : Interrupt controller. + +Example: + sataclk: sataclk { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <100000000>; + clock-output-names = "sataclk"; + }; + + phy2: phy at 1f22a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f22a000 0x0 0x100>, + <0x0 0x1f22c000 0x0 0x100>; + #phy-cells = <1>; + }; + + phy3: phy at 1f23a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f23a000 0x0 0x100>, + <0x0 0x1f23c000 0x0 0x100>; + #phy-cells = <1>; + }; + + sata2: sata at 1a400000 { + compatible = "apm,xgene-ahci-sgmii"; + reg = <0x0 0x1a400000 0x0 0x1000>, + <0x0 0x1f220000 0x0 0x10000>; + interrupt-parent = <&gic>; + interrupts = <0x0 0x87 0x4>; + status = "ok"; + clocks = <&sataclk 0>; + phys = <&phy2 0>; + phy-names = "sata-6g"; + }; + + sata3: sata at 1a800000 { + compatible = "apm,xgene-ahci-pcie"; + reg = <0x0 0x1a800000 0x0 0x1000>, + <0x0 0x1f230000 0x0 0x10000>; + interrupt-parent = <&gic>; + interrupts = <0x0 0x88 0x4>; + status = "ok"; + clocks = <&sataclk 0>; + phys = <&phy3 0>; + phy-names = "sata-6g"; + };
Signature · 1 line
1.5.5
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
This patch adds support for the APM X-Gene SoC AHCI SATA host controller driver. It requires the corresponding APM X-Gene SoC PHY driver. This initial version only supports Gen3 speed.
--- drivers/ata/Kconfig | 7 + drivers/ata/Makefile | 1 + drivers/ata/ahci_xgene.c | 497 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 505 insertions(+), 0 deletions(-) create mode 100644 drivers/ata/ahci_xgene.c
drivers/ata/Kconfig +7 -0
@@ -115,6 +115,13 @@ config AHCI_SUNXI If unsure, say N. +config AHCI_XGENE + tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" + depends on SATA_AHCI_PLATFORM && (ARM64 || COMPILE_TEST) + select PHY_XGENE + help + This option enables support for APM X-Gene SoC SATA host controller. + config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC
drivers/ata/Makefile +1 -0
@@ -12,6 +12,7 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o +obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
drivers/ata/ahci_xgene.c new file +497 -0
497 lines not on this page · raw message
Signature · 1 line
1.5.5
PATCH v17 4/4 arm64: Add APM X-Gene SoC AHCI SATA host controller DTS entries
This patch adds APM X-Gene SoC AHCI SATA host controller DTS entries.
--- arch/arm64/boot/dts/apm-storm.dtsi | 75 ++++++++++++++++++++++++++++++++++++ 1 files changed, 75 insertions(+), 0 deletions(-)
arch/arm64/boot/dts/apm-storm.dtsi +75 -0
@@ -221,6 +221,48 @@ enable-offset = <0x0>; enable-mask = <0x06>; }; + + sata01clk: sata01clk at 1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata01clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; + + sata23clk: sata23clk at 1f22c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f22c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata23clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; + + sata45clk: sata45clk at 1f23c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f23c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata45clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; }; serial0: serial at 1c020000 {
@@ -262,5 +304,38 @@ apm,tx-boost-gain = <31 31 31 31 31 31>; apm,tx-eye-tuning = <2 10 10 2 10 10>; }; + + sata1: sata at 1a000000 { + compatible = "apm,xgene-ahci-sgmii"; + reg = <0x0 0x1a000000 0x0 0x1000>, + <0x0 0x1f210000 0x0 0x10000>; + interrupts = <0x0 0x86 0x4>; + status = "disabled"; + clocks = <&sata01clk 0>; + phys = <&phy1 0>; + phy-names = "sata-phy"; + }; + + sata2: sata at 1a400000 { + compatible = "apm,xgene-ahci-sgmii"; + reg = <0x0 0x1a400000 0x0 0x1000>, + <0x0 0x1f220000 0x0 0x10000>; + interrupts = <0x0 0x87 0x4>; + status = "ok"; + clocks = <&sata23clk 0>; + phys = <&phy2 0>; + phy-names = "sata-phy"; + }; + + sata3: sata at 1a800000 { + compatible = "apm,xgene-ahci-pcie"; + reg = <0x0 0x1a800000 0x0 0x1000>, + <0x0 0x1f230000 0x0 0x10000>; + interrupts = <0x0 0x88 0x4>; + status = "ok"; + clocks = <&sata45clk 0>; + phys = <&phy3 0>; + phy-names = "sata-phy"; + }; }; };
Signature · 1 line
1.5.5
PATCH v17 4/4 arm64: Add APM X-Gene SoC AHCI SATA host controller DTS entries
arch/arm64/boot/dts/apm-storm.dtsi line 236
Quoted 12 lines · Loc Ho
arch/arm64/boot/dts/apm-storm.dtsi +12
-0+ sata01clk: sata01clk at 1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2"; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata01clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>;
Same comment about the "clock-names" as in the first patch here.
Arnd
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
In reply to Loc HoQuoted 7 lines · Loc Ho
This patch adds support for the APM X-Gene SoC AHCI SATA host controller driver. It requires the corresponding APM X-Gene SoC PHY driver. This initial version only supports Gen3 speed.
Signed-off-by Loc Ho <[email protected]>Signed-off-by Tuan Phan <[email protected]>Signed-off-by Suman Tripathi <[email protected]>
Thanks for fixing all the remaining issues.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
In reply to Loc HoQuoted 7 lines · Loc Ho
This patch adds support for the APM X-Gene SoC AHCI SATA host controller driver. It requires the corresponding APM X-Gene SoC PHY driver. This initial version only supports Gen3 speed.
Signed-off-by Loc Ho <[email protected]>Signed-off-by Tuan Phan <[email protected]>Signed-off-by Suman Tripathi <[email protected]>
Sorry I've skipped the last ten review rounds. I'm glad to see the code has improved so much in the meantime!
I hope the points I'm making here were not already covered in the many previous review rounds.
drivers/ata/ahci_xgene.c line 37
Quoted 5 lines
drivers/ata/ahci_xgene.c new file +5
-0+/* Controller who PHY shared with SGMII Ethernet PHY */ +#define XGENE_AHCI_SGMII_DTS "apm,xgene-ahci-sgmii" + +/* Controller who PHY (internal reference clock macro) shared with PCIe */ +#define XGENE_AHCI_PCIE_DTS "apm,xgene-ahci-pcie"
Please remove these macros, they don't help anything at all but make it harder to follow what's going on.
Regarding the actual strings, reflecting them now I think listing 'pcie' and 'sgmii' is not really helpful to the reader. The difference to the AHCI driver should not be which device it's sharing its PHY with, but rather how that looks from software side.
The only difference in your current driver is whether this function
+/* MUX CSR */
+#define SATA_ENET_CONFIG_REG 0x00000000
+#define CFG_SATA_ENET_SELECT_MASK 0x00000001
+static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx) +{
+ void *mux_csr = ctx->csr_base + SATA_ENET_MUX_OFFSET;
+ u32 val;
+
+ val = readl(mux_csr + SATA_ENET_CONFIG_REG); + val &= ~CFG_SATA_ENET_SELECT_MASK; + writel(val, mux_csr + SATA_ENET_CONFIG_REG); + val = readl(mux_csr + SATA_ENET_CONFIG_REG); + return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0;
+}
gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
ret = of_property_read_u32(node, "apm,ahci-mux", &mux); if (!ret) xgene_ahci_mux_select(ctx, mux);
Quoted 4 lines
drivers/ata/ahci_xgene.c new file +4
-0+/* +* Can't use devm_ioremap_resource due to overlapping region. +* 0xYYYY.0000 - host core +* 0xYYYY.7000 - Mux (if applicable)
drivers/ata/ahci_xgene.c line 429
Quoted 10 lines
drivers/ata/ahci_xgene.c new file +10
-0+* 0xYYYY.A000 - PHY indirect access +* 0xYYYY.C000 - Clock +* 0xYYYY.D000 - RAM shutdown removal +* As we map the entire region as one, it overlaps with the PHY driver. +*/ + ctx->csr_base =devm_ioremap (dev, res->start,resource_size (res)); +if (!ctx->csr_base) { +dev_err (dev,"can't map %pR\n" , res); +return -ENOMEM ; + }
I still think we should try not to have overlapping memory areas here. Could you split up the registers into another range in the reg property to leave the PHY registers out?
drivers/ata/ahci_xgene.c line 461
Quoted 6 lines
drivers/ata/ahci_xgene.c new file +6
-0+/* Setup DMA mask - 32 for 32-bit system and 64 for 64-bit system */ + rc =dma_set_mask_and_coherent (dev,DMA_BIT_MASK (8 *sizeof (void *))); +if (rc) { +dev_err (dev,"Unable to set dma mask\n" ); + goto disable_resources; + }
This is something we definitely have to fix properly. We are hitting the problem of dma masks for internal devices on arm32 now, and there is ongoing discussion about whether a device driver should touch these at all, or rather rely on the DT core to set up the masks in a generic way. This device is probably the first DMA master capable device we have on arm64, other than PCI devices, and we must be careful to get it right.
In either way, the mask of the device must *not* depend on sizeof(void*):
If the device is capable of doing 64-bit DMA, it should also be able to do that when running a 32-bit kernel.
Please change this to DMA_BIT_MASK(64) for now, and add a comment explaining that it is preliminary.
Also, please read the thread named "[PATCH 0/7] of: setup dma parameters using dma-ranges and dma-coherent" and comment there about what you think we should do here. I assume we will have to add "dma-ranges" properties in a number of places to get this all to work fine any 64-bit SoC. Do you know if you have any DMA master devices in x-gene that are not 64-bit capable?
Arnd
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Hi,
Quoted 52 lines · Loc Ho
Quoted 7 lines
This patch adds support for the APM X-Gene SoC AHCI SATA host controller driver. It requires the corresponding APM X-Gene SoC PHY driver. This initial version only supports Gen3 speed.
Signed-off-by Loc Ho <[email protected]>Signed-off-by Tuan Phan <[email protected]>Signed-off-by Suman Tripathi <[email protected]>Sorry I've skipped the last ten review rounds. I'm glad to see the code has improved so much in the meantime!
I hope the points I'm making here were not already covered in the many previous review rounds.
drivers/ata/ahci_xgene.c line 37
Quoted 5 lines
drivers/ata/ahci_xgene.c new file +5
-0+/* Controller who PHY shared with SGMII Ethernet PHY */ +#define XGENE_AHCI_SGMII_DTS "apm,xgene-ahci-sgmii" + +/* Controller who PHY (internal reference clock macro) shared with PCIe */ +#define XGENE_AHCI_PCIE_DTS "apm,xgene-ahci-pcie"Please remove these macros, they don't help anything at all but make it harder to follow what's going on.
Regarding the actual strings, reflecting them now I think listing 'pcie' and 'sgmii' is not really helpful to the reader. The difference to the AHCI driver should not be which device it's sharing its PHY with, but rather how that looks from software side.
The only difference in your current driver is whether this function
drivers/ata/ahci_xgene.c new file +14
-0+/* MUX CSR */ +#define SATA_ENET_CONFIG_REG 0x00000000 +#define CFG_SATA_ENET_SELECT_MASK 0x00000001 +static int xgene_ahci_mux_select (struct xgene_ahci_context *ctx) +{ +void *mux_csr = ctx->csr_base +SATA_ENET_MUX_OFFSET ; +u32 val; + + val =readl (mux_csr +SATA_ENET_CONFIG_REG ); + val &= ~CFG_SATA_ENET_SELECT_MASK ; +writel (val, mux_csr +SATA_ENET_CONFIG_REG ); + val =readl (mux_csr +SATA_ENET_CONFIG_REG ); +return val &CFG_SATA_ENET_SELECT_MASK ?-1 :0 ; +}gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
Quoted 4 lines
ret = of_property_read_u32(node, "apm,ahci-mux", &mux);
if (!ret)
xgene_ahci_mux_select(ctx, mux);Given that fact that I will break up the resource. Let's just use the resource for the MUX to handle this. For the IP that doesn't existed, I will just not list it.
Quoted 15 lines
Quoted 4 lines
drivers/ata/ahci_xgene.c new file +4
-0+/* +* Can't use devm_ioremap_resource due to overlapping region. +* 0xYYYY.0000 - host core +* 0xYYYY.7000 - Mux (if applicable) drivers/ata/ahci_xgene.c line 429
Quoted 10 lines
drivers/ata/ahci_xgene.c new file +10
-0+* 0xYYYY.A000 - PHY indirect access +* 0xYYYY.C000 - Clock +* 0xYYYY.D000 - RAM shutdown removal +* As we map the entire region as one, it overlaps with the PHY driver. +*/ + ctx->csr_base =devm_ioremap (dev, res->start,resource_size (res)); +if (!ctx->csr_base) { +dev_err (dev,"can't map %pR\n" , res); +return -ENOMEM ; + }
Quoted 3 lines
I still think we should try not to have overlapping memory areas here. Could you split up the registers into another range in the reg property to leave the PHY registers out?
Let me do this:
1. One resource for the RAM shutdown
2. One resource for the host controller
3. One optional resource for the MUX if needed.
With #3, this also solved the MUX detection and avoid having another node "apm,ahci-mux".
Quoted 16 lines
drivers/ata/ahci_xgene.c line 461
Quoted 7 lines
drivers/ata/ahci_xgene.c new file +6
-0+/* Setup DMA mask - 32 for 32-bit system and 64 for 64-bit system */ + rc =dma_set_mask_and_coherent (dev,DMA_BIT_MASK (8 *sizeof (void *))); +if (rc) { +dev_err (dev,"Unable to set dma mask\n" ); + goto disable_resources; + }This is something we definitely have to fix properly. We are hitting the problem of dma masks for internal devices on arm32 now, and there is ongoing discussion about whether a device driver should touch these at all, or rather rely on the DT core to set up the masks in a generic way. This device is probably the first DMA master capable device we have on arm64, other than PCI devices, and we must be careful to get it right.
Quoted 6 lines
In either way, the mask of the device must *not* depend on
sizeof(void*):
If the device is capable of doing 64-bit DMA, it should also be able to do that when running a 32-bit kernel.Please change this to
DMA_BIT_MASK(64)for now, and add a comment explaining that it is preliminary.
okay.
Quoted 8 lines
Also, please read the thread named "[PATCH 0/7] of: setup dma parameters using dma-ranges and dma-coherent" and comment there about what you think we should do here. I assume we will have to add "dma-ranges" properties in a number of places to get this all to work fine any 64-bit SoC. Do you know if you have any DMA master devices in x-gene that are not 64-bit capable?
I will read and follow later. We do have non-64-bit devices such as SDIO and SPI. But these IP's have translation in the bus similar to PCIe PIM.
-Loc
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Quoted 8 lines · Loc Ho
Quoted 8 lines · Loc Ho
gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
Quoted 8 lines
Quoted 4 lines
ret = of_property_read_u32(node, "apm,ahci-mux", &mux); if (!ret) xgene_ahci_mux_select(ctx, mux);Given that fact that I will break up the resource. Let's just use the resource for the MUX to handle this. For the IP that doesn't existed, I will just not list it.
Ah, that sounds good. It also means that if the firmware has set up the mux already, you don't have to touch it again. That would probably be the preferred case.
I'm undecided about the value that you write in there. That could either be passed through DT as I suggested above for extra flexibility, or you can keep it hardcoded if you are absolutely sure that there will never need to be a case where you have to set it to something other than '1',
Quoted 19 lines
Quoted 15 lines
Quoted 4 lines
drivers/ata/ahci_xgene.c new file +4
-0+/* +* Can't use devm_ioremap_resource due to overlapping region. +* 0xYYYY.0000 - host core +* 0xYYYY.7000 - Mux (if applicable) drivers/ata/ahci_xgene.c line 429
Quoted 10 lines
drivers/ata/ahci_xgene.c new file +10
-0+* 0xYYYY.A000 - PHY indirect access +* 0xYYYY.C000 - Clock +* 0xYYYY.D000 - RAM shutdown removal +* As we map the entire region as one, it overlaps with the PHY driver. +*/ + ctx->csr_base =devm_ioremap (dev, res->start,resource_size (res)); +if (!ctx->csr_base) { +dev_err (dev,"can't map %pR\n" , res); +return -ENOMEM ; + }Quoted 3 lines
I still think we should try not to have overlapping memory areas here. Could you split up the registers into another range in the reg property to leave the PHY registers out?
Quoted 8 lines
Let me do this:
1. One resource for the RAM shutdown
2. One resource for the host controller
3. One optional resource for the MUX if needed.With #3, this also solved the MUX detection and avoid having another node "apm,ahci-mux".
My suggestion was not to have another device node, just a property that contains a value to be written into the mux register if present.
Quoted 11 lines
Quoted 7 lines
Also, please read the thread named "[PATCH 0/7] of: setup dma parameters using dma-ranges and dma-coherent" and comment there about what you think we should do here. I assume we will have to add "dma-ranges" properties in a number of places to get this all to work fine any 64-bit SoC. Do you know if you have any DMA master devices in x-gene that are not 64-bit capable?
I will read and follow later. We do have non-64-bit devices such as SDIO and SPI. But these IP's have translation in the bus similar to PCIe PIM.
Is there also an IOMMU, or just the PIM? If there is no IOMMU, we will actually have to use the swiotlb code here, otherwise we can rely on the IOMMU to do the translation so we can pretend that there is always 64-bit DMA capability.
In theory, the PIM could be dynamically reprogrammed for each DMA, as an extremely primitive IOMMU implementation, but I don't know what the impact on performance would be from doing that. It would also prevent you from starting multiple concurrent DMAs, although I suspect that is not an important case for SPI and SDIO.
Arnd
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Hi,
Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
Quoted 8 lines
Quoted 4 lines
ret = of_property_read_u32(node, "apm,ahci-mux", &mux); if (!ret) xgene_ahci_mux_select(ctx, mux);Given that fact that I will break up the resource. Let's just use the resource for the MUX to handle this. For the IP that doesn't existed, I will just not list it.
Quoted 8 lines
Ah, that sounds good. It also means that if the firmware has set up the mux already, you don't have to touch it again. That would probably be the preferred case.
I'm undecided about the value that you write in there. That could either be passed through DT as I suggested above for extra flexibility, or you can keep it hardcoded if you are absolutely sure that there will never need to be a case where you have to set it to something other than '1',
It is only a mux between two IP's. Writing 1 is fine. For ACPI, it can be missing and handled by the firmware or can be handled just like the DTS way.
Quoted 49 lines
Quoted 20 lines
Quoted 16 lines
Quoted 5 lines
drivers/ata/ahci_xgene.c new file +4
-0+/* +* Can't use devm_ioremap_resource due to overlapping region. +* 0xYYYY.0000 - host core +* 0xYYYY.7000 - Mux (if applicable) drivers/ata/ahci_xgene.c line 429
Quoted 10 lines
drivers/ata/ahci_xgene.c new file +10
-0+* 0xYYYY.A000 - PHY indirect access +* 0xYYYY.C000 - Clock +* 0xYYYY.D000 - RAM shutdown removal +* As we map the entire region as one, it overlaps with the PHY driver. +*/ + ctx->csr_base =devm_ioremap (dev, res->start,resource_size (res)); +if (!ctx->csr_base) { +dev_err (dev,"can't map %pR\n" , res); +return -ENOMEM ; + }Quoted 3 lines
I still think we should try not to have overlapping memory areas here. Could you split up the registers into another range in the reg property to leave the PHY registers out?
Quoted 8 lines
Let me do this:
1. One resource for the RAM shutdown
2. One resource for the host controller
3. One optional resource for the MUX if needed.With #3, this also solved the MUX detection and avoid having another node "apm,ahci-mux".
My suggestion was not to have another device node, just a property that contains a value to be written into the mux register if present.
Quoted 11 lines
Quoted 7 lines
Also, please read the thread named "[PATCH 0/7] of: setup dma parameters using dma-ranges and dma-coherent" and comment there about what you think we should do here. I assume we will have to add "dma-ranges" properties in a number of places to get this all to work fine any 64-bit SoC. Do you know if you have any DMA master devices in x-gene that are not 64-bit capable?
I will read and follow later. We do have non-64-bit devices such as SDIO and SPI. But these IP's have translation in the bus similar to PCIe PIM.
Is there also an IOMMU, or just the PIM? If there is no IOMMU, we will actually have to use the swiotlb code here, otherwise we can rely on the IOMMU to do the translation so we can pretend that there is always 64-bit DMA capability.
Quoted 5 lines
In theory, the PIM could be dynamically reprogrammed for each DMA, as an extremely primitive IOMMU implementation, but I don't know what the impact on performance would be from doing that. It would also prevent you from starting multiple concurrent DMAs, although I suspect that is not an important case for SPI and SDIO.
This first generation don't support IOMMU and rely on swiotlb. In any case, for SDIO, the solution is to reprogram the PIM and limit to SDMA
- single buffer - for each operation.
-Loc
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Quoted 21 lines · Loc Ho
Hi,
Quoted 19 lines
Quoted 6 lines
Quoted 6 lines
gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
Quoted 8 lines
Quoted 4 lines
ret = of_property_read_u32(node, "apm,ahci-mux", &mux); if (!ret) xgene_ahci_mux_select(ctx, mux);Given that fact that I will break up the resource. Let's just use the resource for the MUX to handle this. For the IP that doesn't existed, I will just not list it.
Ah, that sounds good. It also means that if the firmware has set up the mux already, you don't have to touch it again. That would probably be the preferred case.
Quoted 8 lines
Quoted 4 lines
I'm undecided about the value that you write in there. That could either be passed through DT as I suggested above for extra flexibility, or you can keep it hardcoded if you are absolutely sure that there will never need to be a case where you have to set it to something other than '1',
It is only a mux between two IP's. Writing 1 is fine. For ACPI, it can be missing and handled by the firmware or can be handled just like the DTS way.
Why can't you have it handled by the firmware in the DTS case?
I still think it's rather unlikely that we will actually see ACPI support on your platform, btw.
I'm willing to look at the patches you need for it, but I'm not very optimistic, in particular because of the kind of hacks you need for random bits of hardware.
Quoted 11 lines
Quoted 10 lines
Is there also an IOMMU, or just the PIM? If there is no IOMMU, we will actually have to use the swiotlb code here, otherwise we can rely on the IOMMU to do the translation so we can pretend that there is always 64-bit DMA capability.
In theory, the PIM could be dynamically reprogrammed for each DMA, as an extremely primitive IOMMU implementation, but I don't know what the impact on performance would be from doing that. It would also prevent you from starting multiple concurrent DMAs, although I suspect that is not an important case for SPI and SDIO.
Quoted 3 lines
This first generation don't support IOMMU and rely on swiotlb. In any case, for SDIO, the solution is to reprogram the PIM and limit to SDMA
- single buffer - for each operation.
Ok, interesting. In that case, I suppose the DMA mask is actually 64-bit.
Arnd
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Hi
Quoted 28 lines
Quoted 19 lines
Quoted 19 lines
Quoted 6 lines
Quoted 6 lines
gets called. Can you clarify what this register access does? If it's just setting a index into a mux output, would it make sense to have an optional DT property containing an integer with the mux setting you want to set? That way you wouldn't even have to have two compatible strings but just do
Quoted 8 lines
Quoted 4 lines
ret = of_property_read_u32(node, "apm,ahci-mux", &mux); if (!ret) xgene_ahci_mux_select(ctx, mux);Given that fact that I will break up the resource. Let's just use the resource for the MUX to handle this. For the IP that doesn't existed, I will just not list it.
Ah, that sounds good. It also means that if the firmware has set up the mux already, you don't have to touch it again. That would probably be the preferred case.
Quoted 8 lines
Quoted 4 lines
I'm undecided about the value that you write in there. That could either be passed through DT as I suggested above for extra flexibility, or you can keep it hardcoded if you are absolutely sure that there will never need to be a case where you have to set it to something other than '1',
It is only a mux between two IP's. Writing 1 is fine. For ACPI, it can be missing and handled by the firmware or can be handled just like the DTS way.
Quoted 9 lines
Why can't you have it handled by the firmware in the DTS case?
I still think it's rather unlikely that we will actually see ACPI support on your platform, btw.
I'm willing to look at the patches you need for it, but I'm not very optimistic, in particular because of the kind of hacks you need for random bits of hardware.
I am about to post another version. Can you look at the next version? If you still think it needs to be moved to the FW (either U-Boot or Tianocore UEFI boot loader), I will then move out of the Linux driver code.
-Loc
PATCH v17 3/4 ata: Add APM X-Gene SoC AHCI SATA host controller driver
Quoted 8 lines · Loc Ho
Quoted 7 lines
I still think it's rather unlikely that we will actually see ACPI support on your platform, btw.
I'm willing to look at the patches you need for it, but I'm not very optimistic, in particular because of the kind of hacks you need for random bits of hardware.
Quoted 4 lines
I am about to post another version. Can you look at the next version? If you still think it needs to be moved to the FW (either U-Boot or Tianocore UEFI boot loader), I will then move out of the Linux driver code.
I would certainly be happier if it could just be moved into the firmware or boot loader all the time. The only times we actually want to do this stuff in the kernel is when we can't trust the boot loader to get it right, or when the kernel has to support alternative configurations that the boot loader is not aware of, e.g. when you can plug in different kinds of extension boards but the boot loader doesn't know which one you have.
Arnd
PATCH v17 2/4 Documentation: Add documentation for the APM X-Gene SoC SATA host controller DTS binding
In reply to Loc HoDocumentation/devicetree/bindings/ata/apm-xgene.txt line 20
Quoted 6 lines · Loc Ho
+- clocks : Reference to the clock entry. +- phys : A list of phandles + phy-specifiers, one for eachDocumentation/devicetree/bindings/ata/apm-xgene.txt new file +4
-0+ entry in phy-names. +- phy-names : Should contain: + * "sata-6g" for the SATA 6.0Gbps PHY +
The generic ahci binding has convered on using the string "sata-phy" for ahci nodes. I think you should use the same for consistency. I realize I agreed to using "sata-6g" earlier on, but the discussion about the generic binding has moved on in the meantime and that is already merged.
Arnd
PATCH v17 1/4 arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries
In reply to Loc Hoarch/arm64/boot/dts/apm-storm.dtsi line 184
Quoted 5 lines · Loc Ho
arch/arm64/boot/dts/apm-storm.dtsi +5
-0+ sataphy1clk: sataphy1clk at 1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + clock-names = "socplldiv2";
I think we still need to resolve the question regarding the "clock-names" properties in your clock provider nodes. I've commented on this in the past, since it shows up in all the x-gene drivers, but it's very inconsistent.
The binding says
+- clock-names : shall be the name of the device clock. If missing, use the + device name.
which to me makes no sense. What will "use the device name", and which device? Your clock driver doesn't actually use these strings, so could you please fix the binding to remove this, and stop adding the strings to any clock nodes?
Since nothing ever used these and they are marked "optional" in the binding, I don't think there is a chance of breaking anything by changing it now.
Arnd